-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
[API Proposal]: Kill System.Diagnostics.Process on parent death #101985
Comments
Tagging subscribers to this area: @dotnet/area-system-diagnostics-process |
Implements #96470 |
On Windows, the parent process would need to spawn the child process through a Job: https://learn.microsoft.com/en-us/windows/win32/procthread/job-objects. I've never understood why this functionality hasn't been exposed in .NET. It's certainly very useful, albeit somewhat niche -- though I think that's actually a chicken and egg problem. |
Could be a property of System.Diagnostics.ProcessStartInfo instead. That way, the getter of the property would just read a field and never need any interop calls. |
On Windows, JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE looks like a way to implement this. Have the parent process create a job object with that limit (and JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK?), never close the job handle, and don't make the handle inheritable. Place child processes in that job whenever KillOnParentDeath is true. |
Currently, on Windows .NET is using following sys-calls to start a process: runtime/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.Win32.cs Line 156 in 66ae90f
runtime/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.Windows.cs Line 556 in 66ae90f
Using JOB APIs makes sense, but we would need to ensure that all properties exposed by |
.NET also uses CreateProcess, when ProcessStartInfo.UserName is empty: runtime/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.Windows.cs Line 584 in 66ae90f
For CreateProcessWithLogonW or CreateProcess on Windows 10, I believe the new process can be atomically made a member of a job, via STARTUPINFOEXW::lpAttributeList and UpdateProcThreadAttribute PROC_THREAD_ATTRIBUTE_JOB_LIST. ShellExecuteExW doesn't take a STARTUPINFOEXW structure, and SHELLEXECUTEINFOW doesn't have a similar feature. One can set the SEE_MASK_FLAG_HINST_IS_SITE flag and provide an ICreatingProcess implementation, but ICreateProcessInputs doesn't support setting a job handle. It would be possible to read SHELLEXECUTEINFOW::hProcess after ShellExecuteExW finishes, and call AssignProcessToJobObject then. However:
A more robust solution might be to start a shim child process with CreateProcess, assign it to a job, and have it call ShellExecuteExW to start the program specified in ProcessStartInfo. That would however require an executable for the shim process, likely also an MSBuild property for configuring whether to publish that shim with the application. I feel it would be better to make Process.Start throw if ProcessStartInfo requests both UseShellExecute and KillOnParentDeath. |
I've modified the proposal to reflect that |
Background and motivation
Currently in .NET there is no way to ensure that a child process created through System.Diagnostics.Process is killed when the parent process dies, particularly unexpectedly by a SIGKILL. This proposal creates a simple property in the ProcessStartInfo class that would cause a child process to be killed by the OS in these cases.
On Linux, this could be done very easily by setting the
PR_SET_PDEATHSIG
flag on the fork using aprctl()
syscall.I'm not too well versed with the Windows platform but I believe something with Job Objects is possible.
I've named the property
KillOnParentDeath
, this can of course be changed if a better name is thought ofAPI Proposal
API Usage
Alternative Designs
No response
Risks
None as far as I'm aware. The default value should of course be
false
to emulate current behavior.The text was updated successfully, but these errors were encountered: