[mono] Preserve signal handlers during crash chaining#125835
[mono] Preserve signal handlers during crash chaining#125835jpnurmi wants to merge 4 commits intodotnet:mainfrom
Conversation
When mono_set_crash_chaining(true) is enabled, mono_handle_native_crash unconditionally resets SIGABRT, SIGILL, SIGCHLD, and SIGQUIT to SIG_DFL. This is problematic on Android where multiple threads may trigger signals concurrently — for example, FORTIFY detecting a destroyed mutex on an HWUI thread raises SIGABRT, but because the handler was reset to SIG_DFL, it kills the process before Mono can chain the original crash to the previous handler (e.g. sentry-native). Guard the signal handler reset with !mono_do_crash_chaining so that when crash chaining is enabled, Mono's handlers remain installed during native crash processing. This allows the crash to be fully handled and chained to any previously installed handlers before the process terminates. The fix has no effect when crash_chaining is disabled (the default), as the existing SIG_DFL reset behavior is preserved. Includes an Android functional test (CrashChaining) that: - Installs a SIGSEGV handler before mono_jit_init (gated by TEST_CRASH_CHAINING env var) to simulate a pre-Mono crash handler - Triggers a native SIGSEGV that Mono chains to the pre-Mono handler - Verifies SIGABRT was not reset to SIG_DFL during crash processing - Without the fix, the test process is killed by SIGABRT (test crashes) - With the fix, the test returns exit code 42 (pass)
|
Tagging subscribers to this area: @akoeplinger, @matouskozak, @simonrozsival |
There was a problem hiding this comment.
Pull request overview
This PR fixes Mono’s native-crash handling behavior when crash chaining is enabled so that Mono does not reset key signal handlers to SIG_DFL during mono_handle_native_crash, which can otherwise cause secondary signals (notably on Android) to terminate the process before crash chaining completes.
Changes:
- Guard signal-handler resets in
mono_handle_native_crashbehind!mono_do_crash_chaining. - Add an Android functional test that installs a pre-Mono
SIGSEGVhandler, triggers a native crash, and validatesSIGABRTwas not reset toSIG_DFL. - Wire the test via the Android app template using an environment-variable gate (
TEST_CRASH_CHAINING).
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| src/mono/mono/mini/mini-exceptions.c | Avoids resetting signal handlers to defaults when crash chaining is enabled. |
| src/tasks/AndroidAppBuilder/Templates/monodroid.c | Adds a crash-chaining functional test path (env-gated) and native test helpers. |
| src/tests/FunctionalTests/Android/Device_Emulator/CrashChaining/Program.cs | Managed entrypoint invoking the native test and mapping success to exit code 42. |
| src/tests/FunctionalTests/Android/Device_Emulator/CrashChaining/Android.Device_Emulator.CrashChaining.Test.csproj | New Android functional test project definition + env var injection. |
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
|
@jpnurmi please read the following Contributor License Agreement(CLA). If you agree with the CLA, please reply with the following information.
Contributor License AgreementContribution License AgreementThis Contribution License Agreement ( “Agreement” ) is agreed to by the party signing below ( “You” ), 1. Definitions. “Code” means the computer software code, whether in human-readable or machine-executable form, “Project” means any of the projects owned or managed by .NET Foundation and offered under a license “Submit” is the act of uploading, submitting, transmitting, or distributing code or other content to any “Submission” means the Code and any other copyrightable material Submitted by You, including any 2. Your Submission. You must agree to the terms of this Agreement before making a Submission to any 3. Originality of Work. You represent that each of Your Submissions is entirely Your 4. Your Employer. References to “employer” in this Agreement include Your employer or anyone else 5. Licenses. a. Copyright License. You grant .NET Foundation, and those who receive the Submission directly b. Patent License. You grant .NET Foundation, and those who receive the Submission directly or c. Other Rights Reserved. Each party reserves all rights not expressly granted in this Agreement. 6. Representations and Warranties. You represent that You are legally entitled to grant the above 7. Notice to .NET Foundation. You agree to notify .NET Foundation in writing of any facts or 8. Information about Submissions. You agree that contributions to Projects and information about 9. Governing Law/Jurisdiction. This Agreement is governed by the laws of the State of Washington, and 10. Entire Agreement/Assignment. This Agreement is the entire agreement between the parties, and .NET Foundation dedicates this Contribution License Agreement to the public domain according to the Creative Commons CC0 1. |
This change is part of the effort to fix native crash reporting on Sentry .NET apps on Android (getsentry/sentry-dotnet#3954). We intend to have sentry-native install signal handlers before Mono to capture native crashes. However,
mono_handle_native_crashunconditionally resetsSIGABRT,SIGILL,SIGCHLD, andSIGQUITtoSIG_DFLeven whencrash_chainingis enabled, killing the process before the chained handler can run.Guard the reset with
!mono_do_crash_chaining. No effect whencrash_chainingis disabled (the default).Includes an Android functional test (
CrashChaining) that verifies signal handlers are preserved during crash chaining.