Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cache process info where possible and dispose Process objects. #11274

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/Build/BackEnd/BuildManager/BuildManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -759,8 +759,8 @@ private static void AttachDebugger()
#endif
case "2":
// Sometimes easier to attach rather than deal with JIT prompt
Process currentProcess = Process.GetCurrentProcess();
Console.WriteLine($"Waiting for debugger to attach ({currentProcess.MainModule!.FileName} PID {currentProcess.Id}). Press enter to continue...");
Console.WriteLine($"Waiting for debugger to attach ({EnvironmentUtilities.ProcessPath} PID {EnvironmentUtilities.CurrentProcessId}). Press enter to continue...");

Console.ReadLine();
break;
}
Expand Down
2 changes: 1 addition & 1 deletion src/Build/BackEnd/Client/MSBuildClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -474,7 +474,7 @@ private bool TryLaunchServer()
];
NodeLauncher nodeLauncher = new NodeLauncher();
CommunicationsUtilities.Trace("Starting Server...");
Process msbuildProcess = nodeLauncher.Start(_msbuildLocation, string.Join(" ", msBuildServerOptions), nodeId: 0);
using Process msbuildProcess = nodeLauncher.Start(_msbuildLocation, string.Join(" ", msBuildServerOptions), nodeId: 0);
CommunicationsUtilities.Trace("Server started with PID: {0}", msbuildProcess?.Id);
}
catch (Exception ex)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1426,7 +1426,7 @@ private void TraceEngine(string format, params object[] stuff)
{
FileUtilities.EnsureDirectoryExists(_debugDumpPath);

using (StreamWriter file = FileUtilities.OpenWrite(String.Format(CultureInfo.CurrentCulture, Path.Combine(_debugDumpPath, @"EngineTrace_{0}.txt"), Process.GetCurrentProcess().Id), append: true))
using (StreamWriter file = FileUtilities.OpenWrite(string.Format(CultureInfo.CurrentCulture, Path.Combine(_debugDumpPath, @"EngineTrace_{0}.txt"), EnvironmentUtilities.CurrentProcessId), append: true))
{
string message = String.Format(CultureInfo.CurrentCulture, format, stuff);
file.WriteLine("{0}({1})-{2}: {3}", Thread.CurrentThread.Name, Thread.CurrentThread.ManagedThreadId, DateTime.UtcNow.Ticks, message);
Expand Down
5 changes: 1 addition & 4 deletions src/Build/BackEnd/Components/Communications/CurrentHost.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,7 @@ public static string GetCurrentHost()
}
else
{
using (Process currentProcess = Process.GetCurrentProcess())
{
s_currentHost = currentProcess.MainModule.FileName;
}
s_currentHost = EnvironmentUtilities.ProcessPath;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ internal abstract class NodeProviderOutOfProcBase
/// </summary>
private const int TimeoutForWaitForExit = 30000;

#if !FEATURE_PIPEOPTIONS_CURRENTUSERONLY
private static readonly WindowsIdentity s_currentWindowsIdentity = WindowsIdentity.GetCurrent();
#endif
/// <summary>
/// The build component host.
/// </summary>
Expand Down Expand Up @@ -237,11 +240,12 @@ protected IList<NodeContext> GetNodes(string msbuildLocation,
#endif
ConcurrentQueue<NodeContext> nodeContexts = new();
ConcurrentQueue<Exception> exceptions = new();
int currentProcessId = EnvironmentUtilities.CurrentProcessId;
Parallel.For(nextNodeId, nextNodeId + numberOfNodesToCreate, (nodeId) =>
{
try
{
if (!TryReuseAnyFromPossibleRunningNodes(nodeId) && !StartNewNode(nodeId))
if (!TryReuseAnyFromPossibleRunningNodes(currentProcessId, nodeId) && !StartNewNode(nodeId))
{
// We were unable to reuse or launch a node.
CommunicationsUtilities.Trace("FAILED TO CONNECT TO A CHILD NODE");
Expand All @@ -260,12 +264,12 @@ protected IList<NodeContext> GetNodes(string msbuildLocation,

return nodeContexts.ToList();

bool TryReuseAnyFromPossibleRunningNodes(int nodeId)
bool TryReuseAnyFromPossibleRunningNodes(int currentProcessId, int nodeId)
{
while (possibleRunningNodes != null && possibleRunningNodes.TryDequeue(out var nodeToReuse))
{
CommunicationsUtilities.Trace("Trying to connect to existing process {2} with id {1} to establish node {0}...", nodeId, nodeToReuse.Id, nodeToReuse.ProcessName);
if (nodeToReuse.Id == Process.GetCurrentProcess().Id)
if (nodeToReuse.Id == currentProcessId)
{
continue;
}
Expand Down Expand Up @@ -421,7 +425,7 @@ private string GetProcessesToIgnoreKey(Handshake hostHandshake, int nodeProcessI
// on non-Windows operating systems
private static void ValidateRemotePipeSecurityOnWindows(NamedPipeClientStream nodeStream)
{
SecurityIdentifier identifier = WindowsIdentity.GetCurrent().Owner;
SecurityIdentifier identifier = s_currentWindowsIdentity.Owner;
#if FEATURE_PIPE_SECURITY
PipeSecurity remoteSecurity = nodeStream.GetAccessControl();
#else
Expand Down
8 changes: 4 additions & 4 deletions src/Build/BackEnd/Components/Scheduler/Scheduler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2569,7 +2569,7 @@ private void TraceScheduler(string format, params object[] stuff)
{
FileUtilities.EnsureDirectoryExists(_debugDumpPath);

using StreamWriter file = FileUtilities.OpenWrite(String.Format(CultureInfo.CurrentCulture, Path.Combine(_debugDumpPath, "SchedulerTrace_{0}.txt"), Process.GetCurrentProcess().Id), append: true);
using StreamWriter file = FileUtilities.OpenWrite(string.Format(CultureInfo.CurrentCulture, Path.Combine(_debugDumpPath, "SchedulerTrace_{0}.txt"), EnvironmentUtilities.CurrentProcessId), append: true);
file.Write("{0}({1})-{2}: ", Thread.CurrentThread.Name, Thread.CurrentThread.ManagedThreadId, _schedulingData.EventTime.Ticks);
file.WriteLine(format, stuff);
file.Flush();
Expand All @@ -2593,7 +2593,7 @@ private void DumpSchedulerState()
try
{
FileUtilities.EnsureDirectoryExists(_debugDumpPath);
using StreamWriter file = FileUtilities.OpenWrite(String.Format(CultureInfo.CurrentCulture, Path.Combine(_debugDumpPath, "SchedulerState_{0}.txt"), Process.GetCurrentProcess().Id), append: true);
using StreamWriter file = FileUtilities.OpenWrite(string.Format(CultureInfo.CurrentCulture, Path.Combine(_debugDumpPath, "SchedulerState_{0}.txt"), EnvironmentUtilities.CurrentProcessId), append: true);

file.WriteLine("Scheduler state at timestamp {0}:", _schedulingData.EventTime.Ticks);
file.WriteLine("------------------------------------------------");
Expand Down Expand Up @@ -2707,7 +2707,7 @@ private void DumpConfigurations()
{
try
{
using StreamWriter file = FileUtilities.OpenWrite(String.Format(CultureInfo.CurrentCulture, Path.Combine(_debugDumpPath, "SchedulerState_{0}.txt"), Process.GetCurrentProcess().Id), append: true);
using StreamWriter file = FileUtilities.OpenWrite(string.Format(CultureInfo.CurrentCulture, Path.Combine(_debugDumpPath, "SchedulerState_{0}.txt"), EnvironmentUtilities.CurrentProcessId), append: true);

file.WriteLine("Configurations used during this build");
file.WriteLine("-------------------------------------");
Expand Down Expand Up @@ -2747,7 +2747,7 @@ private void DumpRequests()
{
try
{
using StreamWriter file = FileUtilities.OpenWrite(String.Format(CultureInfo.CurrentCulture, Path.Combine(_debugDumpPath, "SchedulerState_{0}.txt"), Process.GetCurrentProcess().Id), append: true);
using StreamWriter file = FileUtilities.OpenWrite(string.Format(CultureInfo.CurrentCulture, Path.Combine(_debugDumpPath, "SchedulerState_{0}.txt"), EnvironmentUtilities.CurrentProcessId), append: true);

file.WriteLine("Requests used during the build:");
file.WriteLine("-------------------------------");
Expand Down
5 changes: 3 additions & 2 deletions src/Build/BackEnd/Node/OutOfProcNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -847,7 +847,8 @@ private void HandleNodeBuildComplete(NodeBuildComplete buildComplete)
_shutdownReason = buildComplete.PrepareForReuse ? NodeEngineShutdownReason.BuildCompleteReuse : NodeEngineShutdownReason.BuildComplete;
if (_shutdownReason == NodeEngineShutdownReason.BuildCompleteReuse)
{
ProcessPriorityClass priorityClass = Process.GetCurrentProcess().PriorityClass;
using Process currentProcess = Process.GetCurrentProcess();
ProcessPriorityClass priorityClass = currentProcess.PriorityClass;
if (priorityClass != ProcessPriorityClass.Normal && priorityClass != ProcessPriorityClass.BelowNormal)
{
// This isn't a priority class known by MSBuild. We should avoid connecting to this node.
Expand All @@ -860,7 +861,7 @@ private void HandleNodeBuildComplete(NodeBuildComplete buildComplete)
{
if (!lowPriority || NativeMethodsShared.IsWindows)
{
Process.GetCurrentProcess().PriorityClass = lowPriority ? ProcessPriorityClass.Normal : ProcessPriorityClass.BelowNormal;
currentProcess.PriorityClass = lowPriority ? ProcessPriorityClass.Normal : ProcessPriorityClass.BelowNormal;
}
else
{
Expand Down
2 changes: 1 addition & 1 deletion src/Build/Evaluation/ProjectRootElementCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -674,7 +674,7 @@ private void DebugTraceCache(string message, string param1)
if (s_debugLogCacheActivity)
{
string prefix = OutOfProcNode.IsOutOfProcNode ? "C" : "P";
Trace.WriteLine(prefix + " " + Process.GetCurrentProcess().Id + " | " + message + param1);
Trace.WriteLine(prefix + " " + EnvironmentUtilities.CurrentProcessId + " | " + message + param1);
}
}
}
Expand Down
9 changes: 1 addition & 8 deletions src/Build/Logging/BinaryLogger/BinaryLogger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -502,13 +502,6 @@ private string GetUniqueStamp()
=> (PathParameterExpander ?? ExpandPathParameter)(string.Empty);

private static string ExpandPathParameter(string parameters)
=> $"{DateTime.UtcNow.ToString("yyyyMMdd-HHmmss")}--{ProcessId}--{StringUtils.GenerateRandomString(6)}";

private static int ProcessId
#if NET
=> Environment.ProcessId;
#else
=> System.Diagnostics.Process.GetCurrentProcess().Id;
#endif
=> $"{DateTime.UtcNow.ToString("yyyyMMdd-HHmmss")}--{EnvironmentUtilities.CurrentProcessId}--{StringUtils.GenerateRandomString(6)}";
}
}
3 changes: 0 additions & 3 deletions src/Build/Microsoft.Build.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,6 @@
</ItemGroup>

<ItemGroup>
<Compile Include="..\Shared\EnvironmentUtilities.cs">
<Link>SharedUtilities\EnvironmentUtilities.cs</Link>
</Compile>
<Compile Include="..\Shared\BuildEnvironmentHelper.cs">
<Link>SharedUtilities\BuildEnvironmentHelper.cs</Link>
</Compile>
Expand Down
6 changes: 4 additions & 2 deletions src/Framework/FileClassifier.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using Microsoft.Build.Shared;

#if !RUNTIME_TYPE_NETCORE
using System.Diagnostics;
using System.Linq;
Expand Down Expand Up @@ -141,10 +143,10 @@ public FileClassifier()

// Seems like MSBuild did not run from VS but from CLI.
// Identify current process and run it
string processName = Process.GetCurrentProcess().MainModule.FileName;
string? processName = EnvironmentUtilities.ProcessPath;
string processFileName = Path.GetFileNameWithoutExtension(processName);

if (string.IsNullOrEmpty(processFileName))
if (processName == null || string.IsNullOrEmpty(processFileName))
{
return null;
}
Expand Down
3 changes: 2 additions & 1 deletion src/Framework/Microsoft.Build.Framework.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>$(LibraryTargetFrameworks)</TargetFrameworks>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
Expand Down Expand Up @@ -40,6 +40,7 @@
<Compile Include="..\Shared\BinaryWriterExtensions.cs">
<Link>Shared\BinaryWriterExtensions.cs</Link>
</Compile>
<Compile Include="..\Shared\EnvironmentUtilities.cs" Link="EnvironmentUtilities.cs" />
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Out of curiosity, how long is this construct around please? (e.g. in other places we use an extra tag, while here we use an attribute)

<Compile Include="..\Shared\IMSBuildElementLocation.cs">
<Link>Shared\IMSBuildElementLocation.cs</Link>
</Compile>
Expand Down
3 changes: 2 additions & 1 deletion src/Framework/Profiler/EvaluationIdProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using System.Diagnostics;
using System.Threading;
using Microsoft.Build.Shared;

#nullable disable

Expand All @@ -14,7 +15,7 @@ namespace Microsoft.Build.Framework.Profiler
internal static class EvaluationIdProvider
{
private static long _sAssignedId = -1;
private static readonly long ProcessId = Process.GetCurrentProcess().Id;
private static readonly long ProcessId = EnvironmentUtilities.CurrentProcessId;

/// <summary>
/// Returns a unique evaluation id
Expand Down
5 changes: 1 addition & 4 deletions src/MSBuild/MSBuildClientApp.cs
Original file line number Diff line number Diff line change
Expand Up @@ -113,10 +113,7 @@ private static string GetCurrentHost()
}
else
{
using (Process currentProcess = Process.GetCurrentProcess())
{
CurrentHost = currentProcess.MainModule?.FileName ?? throw new InvalidOperationException("Failed to retrieve process executable.");
}
CurrentHost = EnvironmentUtilities.ProcessPath ?? throw new InvalidOperationException("Failed to retrieve process executable.");
}
}

Expand Down
5 changes: 3 additions & 2 deletions src/MSBuild/OutOfProcTaskHostNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -811,8 +811,9 @@ private NodeEngineShutdownReason HandleShutdown()
_taskRunnerThread?.Join();

using StreamWriter debugWriter = _debugCommunications
? File.CreateText(string.Format(CultureInfo.CurrentCulture, Path.Combine(FileUtilities.TempFileDirectory, @"MSBuild_NodeShutdown_{0}.txt"), Process.GetCurrentProcess().Id))
: null;
? File.CreateText(string.Format(CultureInfo.CurrentCulture, Path.Combine(FileUtilities.TempFileDirectory, @"MSBuild_NodeShutdown_{0}.txt"), EnvironmentUtilities.CurrentProcessId))
: null;

debugWriter?.WriteLine("Node shutting down with reason {0}.", _shutdownReason);

#if !CLR2COMPATIBILITY
Expand Down
2 changes: 1 addition & 1 deletion src/MSBuild/PerformanceLogEventListener.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ private PerformanceLogEventListener()

internal void Initialize(string logDirectory)
{
_processIDStr = Process.GetCurrentProcess().Id.ToString();
_processIDStr = EnvironmentUtilities.CurrentProcessId.ToString();

// Use a GUID disambiguator to make sure that we have a unique file name.
string logFilePath = Path.Combine(logDirectory, $"perf-{_processIDStr}-{Guid.NewGuid().ToString("N")}.log");
Expand Down
21 changes: 12 additions & 9 deletions src/MSBuild/XMake.cs
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,7 @@ private static void AppendOutputFile(string path, long elapsedTime)
/// </comments>
private static void DumpCounters(bool initializeOnly)
{
Process currentProcess = Process.GetCurrentProcess();
using Process currentProcess = Process.GetCurrentProcess();

if (!initializeOnly)
{
Expand Down Expand Up @@ -461,7 +461,7 @@ private static void DumpCounters(bool initializeOnly)
using PerformanceCounter counter = new PerformanceCounter(".NET CLR Memory", "Process ID", instance, true);
try
{
if ((int)counter.RawValue == currentProcess.Id)
if ((int)counter.RawValue == EnvironmentUtilities.CurrentProcessId)
{
currentInstance = instance;
break;
Expand Down Expand Up @@ -627,9 +627,9 @@ private static void DebuggerLaunchCheck()
#endif
case "2":
// Sometimes easier to attach rather than deal with JIT prompt
Process currentProcess = Process.GetCurrentProcess();
Console.WriteLine($"Waiting for debugger to attach ({currentProcess.MainModule.FileName} PID {currentProcess.Id}). Press enter to continue...");
Console.WriteLine($"Waiting for debugger to attach ({EnvironmentUtilities.ProcessPath} PID {EnvironmentUtilities.CurrentProcessId}). Press enter to continue...");
Console.ReadLine();

break;
}
}
Expand Down Expand Up @@ -1736,7 +1736,7 @@ private static bool PrintTargets(string projectFile, string toolsVersion, Dictio
new BuildManager.DeferredBuildMessage(
ResourceUtilities.FormatResourceStringIgnoreCodeAndKeyword(
"Process",
Process.GetCurrentProcess().MainModule?.FileName ?? string.Empty),
EnvironmentUtilities.ProcessPath ?? string.Empty),
MessageImportance.Low),
new BuildManager.DeferredBuildMessage(
ResourceUtilities.FormatResourceStringIgnoreCodeAndKeyword(
Expand Down Expand Up @@ -2527,8 +2527,7 @@ private static bool ProcessCommandLineSwitches(

if (!Debugger.IsAttached)
{
Process currentProcess = Process.GetCurrentProcess();
Console.WriteLine($"Waiting for debugger to attach... ({currentProcess.MainModule.FileName} PID {currentProcess.Id})");
Console.WriteLine($"Waiting for debugger to attach... ({EnvironmentUtilities.ProcessPath} PID {EnvironmentUtilities.CurrentProcessId})");
while (!Debugger.IsAttached)
{
Thread.Sleep(100);
Expand All @@ -2555,9 +2554,13 @@ private static bool ProcessCommandLineSwitches(
}
try
{
if (lowPriority && Process.GetCurrentProcess().PriorityClass != ProcessPriorityClass.Idle)
if (lowPriority)
{
Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.BelowNormal;
using Process currentProcess = Process.GetCurrentProcess();
if (currentProcess.PriorityClass != ProcessPriorityClass.Idle)
{
currentProcess.PriorityClass = ProcessPriorityClass.BelowNormal;
}
}
}
// We avoid increasing priority because that causes failures on mac/linux, but there is no good way to
Expand Down
3 changes: 2 additions & 1 deletion src/MSBuildTaskHost/MSBuildTaskHost.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<!-- The .NET Core version of MSBuild doesn't support targeting .NET Framework 3.5. So in that case, we import
a .props file that prevents building the project from doing much of anything. -->
Expand Down Expand Up @@ -70,6 +70,7 @@
<Link>CopyOnWriteDictionary.cs</Link>
</Compile>
<Compile Include="..\Shared\Constants.cs" />
<Compile Include="..\Shared\EnvironmentUtilities.cs" Link="EnvironmentUtilities.cs" />
<Compile Include="..\Shared\ReadOnlyEmptyDictionary.cs" />
<Compile Include="..\Framework\ErrorUtilities.cs">
<Link>ErrorUtilities.cs</Link>
Expand Down
4 changes: 2 additions & 2 deletions src/MSBuildTaskHost/OutOfProcTaskHost.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,8 @@ internal static ExitType Execute()
#endif
case "2":
// Sometimes easier to attach rather than deal with JIT prompt
Process currentProcess = Process.GetCurrentProcess();
Console.WriteLine($"Waiting for debugger to attach ({currentProcess.MainModule.FileName} PID {currentProcess.Id}). Press enter to continue...");
Console.WriteLine($"Waiting for debugger to attach ({EnvironmentUtilities.ProcessPath} PID {EnvironmentUtilities.CurrentProcessId}). Press enter to continue...");

Console.ReadLine();
break;
}
Expand Down
Loading