Uh oh!
There was an error while loading. Please reload this page.
Implement SafeProcessHandle.Kill and Signal - #126313
Conversation
Tagging subscribers to this area: @dotnet/area-system-diagnostics-process |
Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/f1233ff0-2352-488d-ae71-9947c67f09c6 Co-authored-by: adamsitnik <6011991+adamsitnik@users.noreply.github.com>
adamsitnik
left a comment
There was a problem hiding this comment.
@copilot address my feedback, also do search for other places in the repo where the new Signal API could be used
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
…r handling Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/33138282-b24e-4a35-b495-385af456c851 Co-authored-by: adamsitnik <6011991+adamsitnik@users.noreply.github.com>
All feedback addressed in 7c03c8c. For other usages: the main candidate in the codebase is the |
There was a problem hiding this comment.
Pull request overview
Adds process-termination and signal-sending capabilities directly to SafeProcessHandle, enabling callers to manage processes via handles without going through Process, with platform-specific implementations for Windows and Unix plus corresponding test updates.
Changes:
- Added
SafeProcessHandle.Kill()andSafeProcessHandle.Signal(PosixSignal)public APIs (with ref-assembly updates). - Implemented
SignalCoreon Windows (viaTerminateProcess) and Unix (viakill(2)+GetPlatformSignalNumber). - Added/updated tests to validate new APIs and switched an existing Unix test to use
SafeProcessHandle.Signal.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| src/libraries/System.Diagnostics.Process/src/Microsoft/Win32/SafeHandles/SafeProcessHandle.cs | Introduces the new public Kill/Signal APIs and validation path. |
| src/libraries/System.Diagnostics.Process/src/Microsoft/Win32/SafeHandles/SafeProcessHandle.Windows.cs | Implements Windows SignalCore mapping SIGKILL to TerminateProcess with exited-process detection. |
| src/libraries/System.Diagnostics.Process/src/Microsoft/Win32/SafeHandles/SafeProcessHandle.Unix.cs | Implements Unix SignalCore using GetPlatformSignalNumber + kill, returning false on ESRCH. |
| src/libraries/System.Diagnostics.Process/src/System.Diagnostics.Process.csproj | Adds Interop.PosixSignal.cs to the Unix compile item group. |
| src/libraries/System.Diagnostics.Process/ref/System.Diagnostics.Process.cs | Updates the public ref surface for SafeProcessHandle with Kill/Signal. |
| src/libraries/System.Diagnostics.Process/tests/SafeProcessHandleTests.cs | Adds unit tests covering invalid-handle, running-process, exited-process, and platform-specific behaviors. |
| src/libraries/System.Diagnostics.Process/tests/ProcessTests.Unix.cs | Updates signal-delivery test to use SafeProcessHandle.Signal instead of a raw P/Invoke helper. |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Uh oh!
There was an error while loading. Please reload this page.
This comment has been minimized.
This comment has been minimized.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
🤖 Copilot Code Review — PR #126313Note This review was generated by GitHub Copilot using Claude Opus 4.6. Holistic AssessmentMotivation: Justified. This is the next step in the approved API expansion (#125838, Approach: Sound. The implementation follows the approved API shape exactly, builds on the existing Summary: ✅ LGTM. The implementation matches the approved API shape, all prior maintainer review feedback (from Detailed Findings✅ API Approval Verification — Matches approved shapeThe approved API from #125838 (comment) by publicpartialclassSafeProcessHandle{publicvoidKill();publicboolSignal(PosixSignalsignal);}The ref assembly implementation matches exactly:
✅ Correctness — Edge cases handled properlyBoth platform implementations handle key edge cases correctly:
✅ Native Code — Clean simplification
✅ Test Coverage — ComprehensiveTests cover all key scenarios:
Existing tests also updated to use the new API ( 💡 |
Uh oh!
There was an error while loading. Please reload this page.
Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/1a45be3f-60b7-470e-b7c2-5361f31eb82a Co-authored-by: jkotas <6668460+jkotas@users.noreply.github.com>
Head branch was pushed to by a user without write access
jkotas
commented
Mar 31, 2026
@copilot Address this feedback |
…trypoints.c Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/d9e6abee-de7a-47e0-b18f-3a2375b62b15 Co-authored-by: jkotas <6668460+jkotas@users.noreply.github.com>
Head branch was pushed to by a user without write access
Done in 493466c — moved |
Uh oh!
There was an error while loading. Please reload this page.
Adds
Kill()andSignal(PosixSignal)toSafeProcessHandle, enabling callers to terminate or signal a process via a handle without going throughProcess.Description
Public API (
SafeProcessHandle.cs+ ref assembly)Kill()— sends a request to the OS to terminate the process; silently no-ops if already exited (matchesProcess.Killsemantics). On Windows, the handle must havePROCESS_TERMINATEaccess.Signal(PosixSignal)— sends an arbitrary signal; returnsfalseif process no longer exists (or never existed),trueon delivery, throwsPlatformNotSupportedExceptionfor unsupported signals. On Windows, the handle must havePROCESS_TERMINATEaccess.Both methods validate the handle (throw
InvalidOperationExceptionon invalid handle), carry the same[UnsupportedOSPlatform("ios/tvos")]/[SupportedOSPlatform("maccatalyst")]annotations asStart, and throwPlatformNotSupportedExceptionat runtime on iOS/tvOS (matching theProcessUtils.PlatformDoesNotSupportProcessStartAndKillpattern used byProcess.Kill).Windows (
SafeProcessHandle.Windows.cs)SignalCore: onlySIGKILLis supported (maps toTerminateProcess), matchingPosixSignalRegistration.Createexception behavior for unsupported signals. Retrieves the error code viaMarshal.GetLastWin32Error()before any checks and only constructsWin32Exception(errorCode)when actually throwing. Detects already-exited processes viaERROR_ACCESS_DENIED+GetExitCodeProcessreturning non-STILL_ACTIVE.KillCore;Kill()callsSignalCore(PosixSignal.SIGKILL)directly from the shared file.Unix (
SafeProcessHandle.Unix.cs)SignalCore: checksProcessUtils.PlatformDoesNotSupportProcessStartAndKillfirst (throwsPlatformNotSupportedExceptionon iOS/tvOS); usesInterop.Sys.GetPlatformSignalNumber(signal)to convert the managedPosixSignalto its platform-native signal number (throwsPlatformNotSupportedExceptionif unsupported, matchingPosixSignalRegistration.Createbehavior); passes the native signal number directly toInterop.Sys.Kill; returnsfalseonESRCH; usesInterop.Sys.GetLastErrorInfo()and passeserrorInfo.RawErrnoto theWin32Exceptionconstructor.KillCore;Kill()callsSignalCore(PosixSignal.SIGKILL)directly from the shared file.Native (
pal_process.c/pal_signal.c)SystemNative_Killsimplified to callkill(pid, signal)directly with no PAL mapping switch — it now takes the platform-native signal number, consistent with otherSystem.NativeAPIs such asSystemNative_EnablePosixSignalHandling. The oldSignalsPAL enum (PAL_NONE,PAL_SIGKILL,PAL_SIGSTOP) has been removed frompal_process.h.SystemNative_GetPlatformSIGSTOP()moved topal_signal.h/pal_signal.c(right belowSystemNative_GetPlatformSignalNumber) since it is signal-related. Dummy implementations returning0are provided inpal_signal_wasm.cfor bothSystemNative_GetPlatformSIGSTOPandSystemNative_GetPlatformSignalNumberfor BROWSER and WASI platforms.entrypoints.c: moved theDllImportEntry(SystemNative_GetPlatformSIGSTOP)registration from the process group (betweenSystemNative_KillandSystemNative_GetPid) to the signal group (alongsideSystemNative_GetPlatformSignalNumber,SystemNative_EnablePosixSignalHandling, etc.), consistent with the function's new home inpal_signal.c/pal_signal.h.Process.Kill refactoring (
Process.Windows.cs)Process.Kill()on Windows now delegates toSafeProcessHandle.Kill()after obtaining the handle, eliminating the duplicatedTerminateProcess+ error-handling logic.Interop (
Interop.Kill.cs/Interop.PosixSignal.cs)Signalsmanaged enum;Interop.Sys.Killnow takes a plainintsignal parameter (platform-native number).Interop.Sys.GetPlatformSIGSTOP()P/Invoke moved toInterop.PosixSignal.csalongsideGetPlatformSignalNumber, keeping all signal-number interop co-located.Process.Unix.csusesGetPlatformSignalNumber(PosixSignal.SIGKILL)andGetPlatformSIGSTOP();ProcessWaitState.Unix.csandProcessManager.Unix.cspass0directly for the "probe" call.Project / interop
Interop.PosixSignal.csto the UnixItemGroupinSystem.Diagnostics.Process.csprojto exposeGetPlatformSignalNumberandGetPlatformSIGSTOPin the main assembly.Tests
SafeProcessHandleTests.cs: Invalid handle →InvalidOperationException;Kill/Signal(SIGKILL)on running process terminates it;Killon exited process does not throw;Signal(SIGKILL)returnsfalseon exited process; Windows: non-SIGKILLsignal →PlatformNotSupportedException; Unix:Signal(SIGTERM)on running process returnstrueand terminates it; Windows:Kill_HandleWithoutTerminatePermission_ThrowsWin32Exception— opens a handle with onlyPROCESS_QUERY_LIMITED_INFORMATIONand verifiesKill()throwsWin32Exception.ProcessTests.Unix.cs: UpdatedChildProcess_WithParentSignalHandler_CanReceiveSignalsto useSafeProcessHandle.Signalinstead of the rawSendSignalhelper. RefactoredSendSignalhelper to accept aProcessparameter — Unix callsprocess.SafeHandle.Signal(signal)directly (simplified to a single-lineAssert.True). Removed the class-levelSIGKILLconstant andkillP/Invoke declaration;Kill_ExitedNonChildProcess_DoesNotThrownow usesSafeHandle.Signal(PosixSignal.SIGKILL)andProcess.HasExited.