Process.Kill can hang indefinitely on macOS arm64
- Dominant language
- C#
- Stars
- 18.3k
- Forks
- 5.6k
- PR merge metrics
- PR metrics pending
Description
### Description
On macOS arm64, `Process.Kill(entireProcessTree: true)` can block indefinitely while terminating process trees created by the `dotnet-watch` tests.
This appeared after consuming the runtime flow containing #128598, which introduced the two-phase stop-then-kill implementation on Unix.
Enable dotnet-watch tests on mac once fixed: https://github.com/dotnet/sdk/issues/55679
### Reproduction Steps
1. From a `dotnet/sdk` checkout at commit [`dc6cef6`](https://github.com/dotnet/sdk/commit/dc6cef6c6ceb55eacfcd244b9b812d7f464e1503), run the [`dotnet-watch.Tests`](https://github.com/dotnet/sdk/tree/dc6cef6c6ceb55eacfcd244b9b812d7f464e1503/test/dotnet-watch.Tests) suite on macOS 15 arm64. In CI, this is Helix shard `dotnet-watch.Tests.dll.2` on queue `osx.15.arm64.open`.
2. Allow tests to dispose their child processes using `Process.Kill(entireProcessTree: true)`.
3. Observe that some calls never return.
A standalone runtime-only reproduction has not yet been reduced. The failure reproduces in the SDK CI shard linked below.
### Expected behavior
`Process.Kill(entireProcessTree: true)` terminates the process tree and returns promptly.
### Actual behavior
Instrumentation logged nine calls entering `Process.Kill(entireProcessTree: true)`, but only three returned. Helix eventually detected the hang, collected dumps, and terminated the test process:
```text
[TEST AwaitableProcess.cs:237] Killing process tree for process 18251
Hang dump timeout of '00:48:00' expired
Test application process didn't exit gracefully, exit code is '137'
```
One separate call returned from `Kill`, but its process still did not exit within 30 seconds.
### Regression?
Observed after the SDK consumed the runtime flow containing #128598. That PR changed Unix process-tree termination to recursively stop the tree before killing it.
Confidence is high that the immediate hang occurs synchronously inside `Process.Kill(entireProcessTree: true)`. Confidence that #128598 introduced the regression is moderate pending a reduced runtime-only reproduction.
### Known Workarounds
None currently. Bounding the subsequent wait does not help because the call to `Process.Kill` itself does not return.
### Configuration
- macOS 15
- arm64
- Helix queue: `osx.15.arm64.open`
- Work item: `dotnet-watch.Tests.dll.2`
- .NET 11 runtime consumed by the SDK flow
### Other information
- SDK Known Build Error: https://github.com/dotnet/sdk/issues/55636
- Failing build: https://dev.azure.com/dnceng-public/public/_build/results?buildId=1542039
- Helix job: https://helix.dot.net/api/jobs/2393a91c-17df-4ae9-b32c-faab6d292cf1/details
- Suspected runtime change: https://github.com/dotnet/runtime/pull/128598
Contributor guide
Assessment
This issue has not been assessed yet.