From 524399d3a5da648c019991e7939a8ad54c7fbe84 Mon Sep 17 00:00:00 2001 From: Mischan Toosarani-Hausberger Date: Sat, 14 Mar 2026 17:48:13 +0100 Subject: [PATCH 1/2] fix(inproc): only the handling thread cleans up --- src/backends/sentry_backend_inproc.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/src/backends/sentry_backend_inproc.c b/src/backends/sentry_backend_inproc.c index 6efd2ad47..53aa0af54 100644 --- a/src/backends/sentry_backend_inproc.c +++ b/src/backends/sentry_backend_inproc.c @@ -1351,7 +1351,7 @@ has_handler_thread_crashed(void) return false; } -static void +static bool dispatch_ucontext(const sentry_ucontext_t *uctx, const struct signal_slot *sig_slot, int handler_depth) { @@ -1365,7 +1365,7 @@ dispatch_ucontext(const sentry_ucontext_t *uctx, // Disable stdio-based logging - not safe in signal handler context. sentry__logger_disable(); process_ucontext_deferred(uctx, sig_slot, skip_hooks); - return; + return true; #else if (has_handler_thread_crashed()) { // Disable stdio-based logging since we're now in signal handler context @@ -1377,7 +1377,7 @@ dispatch_ucontext(const sentry_ucontext_t *uctx, // Always skip hooks here since the first attempt (from handler thread) // already failed, likely due to a crashing hook. process_ucontext_deferred(uctx, sig_slot, true); - return; + return true; } // Try to become the crash handler. Only one thread can transition @@ -1398,7 +1398,7 @@ dispatch_ucontext(const sentry_ucontext_t *uctx, sentry__cpu_relax(); } // State is now DONE: just return and let the signal propagate - return; + return false; } // We are the first handler. Check if handler thread is available. @@ -1406,7 +1406,7 @@ dispatch_ucontext(const sentry_ucontext_t *uctx, // Disable stdio-based logging - not safe in signal handler context. sentry__logger_disable(); process_ucontext_deferred(uctx, sig_slot, skip_hooks); - return; + return true; } g_handler_state.uctx = *uctx; @@ -1460,7 +1460,7 @@ dispatch_ucontext(const sentry_ucontext_t *uctx, int depth = sentry__enter_signal_handler(); if (depth >= 3) { // Multiple recursive crashes - bail out - return; + return true; } // Disable stdio-based logging - not safe in signal handler context. sentry__logger_disable(); @@ -1469,7 +1469,7 @@ dispatch_ucontext(const sentry_ucontext_t *uctx, // always 1, which would incorrectly re-run hooks on a recursive // crash where the pipe also fails. process_ucontext_deferred(uctx, sig_slot, skip_hooks); - return; + return true; } # elif defined(SENTRY_PLATFORM_WINDOWS) if (g_handler_semaphore) { @@ -1486,7 +1486,7 @@ dispatch_ucontext(const sentry_ucontext_t *uctx, // Disable stdio-based logging - not safe in signal handler context. sentry__logger_disable(); process_ucontext_deferred(uctx, sig_slot, skip_hooks); - return; + return true; } # endif @@ -1516,6 +1516,7 @@ dispatch_ucontext(const sentry_ucontext_t *uctx, (void)!sentry__enter_signal_handler(); # endif + return true; #endif } @@ -1618,11 +1619,18 @@ process_ucontext(const sentry_ucontext_t *uctx) // invoke the handler thread for signal unsafe actions #ifdef SENTRY_PLATFORM_UNIX - dispatch_ucontext(uctx, sig_slot, handler_depth); + bool is_handling_thread = dispatch_ucontext(uctx, sig_slot, handler_depth); #else - dispatch_ucontext(uctx, sig_slot, 1); + bool is_handling_thread = dispatch_ucontext(uctx, sig_slot, 1); #endif + // Non-handling threads (that lost the CAS race) should just return. + // Signal handlers are already reset by the handling thread, so + // re-executing the crashing instruction will hit the default handler. + if (!is_handling_thread) { + return; + } + #ifdef SENTRY_PLATFORM_UNIX cleanup: // reset signal handlers and invoke the original ones. This will then tear From 8901ef5a7a777164b059a28f02a39071ae815a10 Mon Sep 17 00:00:00 2001 From: Mischan Toosarani-Hausberger Date: Sat, 14 Mar 2026 17:56:27 +0100 Subject: [PATCH 2/2] changelog --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index aebb8a8cc..a57e0d348 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## Unreleased: + +**Fixes**: + +- inproc: only the handling thread cleans up after the crash. ([#1579](https://github.com/getsentry/sentry-native/pull/1579)) + ## 0.13.2 **Features**: