[release/11.0] [CreateDump] Use _exit after createdump launch failures - #133928
Open
github-actions[bot] wants to merge 1 commit into
Open
github-actions[bot] wants to merge 1 commit into
github-actions[bot] wants to merge 1 commit into
Conversation
Fixes #133733 Use `_exit(EXIT_FAILURE)` instead of `exit(-1)` when the forked `createdump` launcher child fails before completing `execve`. On Unix, CoreCLR forks a temporary child and expects it to replace itself with `createdump`. If the parent/child synchronization handshake fails or `execve(createdump)` fails, the child is still a forked copy of the managed runtime. Calling `exit()` in that child runs inherited process destructors. In particular, the PAL process-shutdown destructor invokes the CoreCLR shutdown callback, which cleans up the debugger transport and diagnostic server. Because the child shares the parent's filesystem namespace, that cleanup unlinks paths belonging to the still-running parent: ```text /tmp/clr-debug-pipe-<pid>-<key>-in /tmp/clr-debug-pipe-<pid>-<key>-out /tmp/dotnet-diagnostic-<pid>-<key>-socket ``` The parent runtime remains alive and retains its diagnostic listener file descriptor, but new diagnostic clients cannot connect after the Unix-domain socket pathname has been removed. ## Cleanup behavior before this change On a child failure: ```text forked child | | handshake or execve failure v exit(-1) | | runs inherited destructors v PAL shutdown callback | +-- closes the child's inherited descriptor references +-- runs debugger transport cleanup +-- runs diagnostic server shutdown +-- unlinks debugger pipe and diagnostic socket paths ``` The kernel eventually closed the child's file descriptors when the child terminated, but `exit()` first ran userspace cleanup that belonged to the parent runtime. Unlinking the shared endpoint paths affected the parent even though closing the child's descriptor references alone would not have affected it. ## Cleanup behavior after this change On a child failure: ```text forked child | | handshake or execve failure v _exit(EXIT_FAILURE) | +-- kernel closes the child's file descriptors +-- kernel releases the child's mappings and other process resources +-- parent observes EOF on the child stderr pipe +-- parent reaps the child with waitpid() | +-- does not run inherited destructors +-- does not invoke the PAL shutdown callback +-- does not unlink the parent's diagnostic endpoint paths ``` The child still closes all of its file descriptor references as part of kernel process termination. The difference is that it no longer performs inherited userspace teardown against copied runtime state. On a successful `execve`, the existing `SOCK_CLOEXEC` and `FD_CLOEXEC` flags continue to close inherited diagnostic descriptors in the new `createdump` process. This change affects only failure paths before a successful exec. Both forked-child failure paths are updated: 1. Failure to read the one-byte synchronization signal from the parent. 2. Failure to execute the external `createdump` binary. ## Validation The issue was reproduced by running a target with its colocated `createdump` set to mode `0644`. Before the change: 1. `dotnet-dump collect` reached the target runtime. 2. `execve(createdump)` failed with `EACCES`. 3. The target process remained alive. 4. The target's default diagnostic socket disappeared. After the change: 1. Two consecutive dump requests failed with the expected execute-permission error. 2. The target process remained alive after both requests. 3. The default diagnostic socket remained present after both requests. 4. The second request successfully connected to the same runtime, confirming that the listener remained reachable. 5. After restoring execute permission, a subsequent minidump completed successfully. 6. The diagnostic socket remained present after successful collection. CoreCLR Release was rebuilt successfully with the change. --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
github-actions
Bot
requested a review
from MichalStrehovsky
as a code owner
September 15, 2026 03:40
|
Azure Pipelines: Successfully started running 3 pipeline(s). 13 pipeline(s) were filtered out due to trigger conditions. There may be pipelines that require an authorized user to comment /azp run to run. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Backport of #133742 to release/11.0
/cc @steveisok @mdh1418
Customer Impact
[Select one or both of the boxes. Describe how this issue impacts customers, citing the expected and actual behaviors and scope of the issue. If customer-reported, provide the issue number.]
Regression
[If yes, specify when the regression was introduced. Provide the PR or commit if known.]
Testing
[How was the fix verified? How was the issue missed previously? What tests were added?]
Risk
[High/Medium/Low. Justify the indication by mentioning how risks were measured and addressed.]
IMPORTANT: If this backport is for a servicing release, please verify that:
release/X.0-staging, notrelease/X.0.release/X.0(no-stagingsuffix).Package authoring no longer needed in .NET 9
IMPORTANT: Starting with .NET 9, you no longer need to edit a NuGet package's csproj to enable building and bump the version.
Keep in mind that we still need package authoring in .NET 8 and older versions.