Skip to content
Merged
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
38 changes: 31 additions & 7 deletions src/Shared/ProcessSignaler.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.ComponentModel;
using System.Diagnostics;
using System.Runtime.InteropServices;
using Microsoft.Extensions.Logging;
Expand Down Expand Up @@ -49,32 +50,55 @@ public static void ForceKill(int pid, DateTimeOffset? expectedStartTime, ILogger

public static Process? TryGetRunningProcess(int pid, DateTimeOffset? expectedStartTime, ILogger logger)
{
Process? process = null;
try
{
var process = Process.GetProcessById(pid);
if (expectedStartTime is not null && !AreClose(expectedStartTime, process.StartTime))
process = Process.GetProcessById(pid);
if (process.HasExited)
{
logger.LogDebug("Process {Pid} start time {ProcessStartTime} does not match expected start time {ExpectedStartTime}", pid, process.StartTime, expectedStartTime);
process.Dispose();
return null; // Do not return processes that do not match the expected start time
return null;
}

if (process.HasExited)
if (expectedStartTime is not null)
{
process.Dispose();
return null;
var processStartTime = process.StartTime;
if (!AreClose(expectedStartTime, processStartTime))
{
logger.LogDebug("Process {Pid} start time {ProcessStartTime} does not match expected start time {ExpectedStartTime}", pid, processStartTime, expectedStartTime);
process.Dispose();
return null; // Do not return processes that do not match the expected start time
}

if (process.HasExited)
{
process.Dispose();
return null;
}
}

return process;
}
catch (ArgumentException)
{
// Process doesn't exist - already terminated.
process?.Dispose();
return null;
}
catch (InvalidOperationException)
{
// Process has already exited.
process?.Dispose();
return null;
}
catch (Win32Exception ex)
{
// Process inspection can race with process exit. On macOS, StartTime can throw:
// Win32Exception (3): Unable to retrieve the specified information about the process or thread. It may have exited or may be privileged.
// If we cannot inspect the process enough to prove it is the expected target, do
// not signal or kill it.
logger.LogDebug(ex, "Could not inspect process {Pid}. Treating it as not running.", pid);
process?.Dispose();
return null;
}
}
Expand Down
Loading