From 1cfbbca866ba16893ceddb166588c5a3fb38ef68 Mon Sep 17 00:00:00 2001 From: Ivan Povazan Date: Tue, 17 Dec 2024 19:31:58 +0100 Subject: [PATCH 1/2] Consider SIG_DFL handlers for chaining SIGSEGV signals --- src/mono/mono/mini/mini-posix.c | 34 ++++++++++++++++++++++++++++--- src/mono/mono/mini/mini-runtime.c | 6 ++++-- src/mono/mono/mini/mini-runtime.h | 1 + src/mono/mono/mini/mini-wasm.c | 6 ++++++ src/mono/mono/mini/mini-windows.c | 6 ++++++ 5 files changed, 48 insertions(+), 5 deletions(-) diff --git a/src/mono/mono/mini/mini-posix.c b/src/mono/mono/mini/mini-posix.c index 429d1dc3744f3..e39a5fe9200c3 100644 --- a/src/mono/mono/mini/mini-posix.c +++ b/src/mono/mono/mini/mini-posix.c @@ -188,7 +188,7 @@ save_old_signal_handler (int signo, struct sigaction *old_action) * * Call the original signal handler for the signal given by the arguments, which * should be the same as for a signal handler. Returns TRUE if the original handler - * was called, false otherwise. + * was called, false otherwise. NOTE: sigaction.sa_handler == SIG_DFL handlers are not considered. */ gboolean MONO_SIG_HANDLER_SIGNATURE (mono_chain_signal) @@ -196,6 +196,7 @@ MONO_SIG_HANDLER_SIGNATURE (mono_chain_signal) int signal = MONO_SIG_HANDLER_GET_SIGNO (); struct sigaction *saved_handler = (struct sigaction *)get_saved_signal_handler (signal); + // Ignores chaining to default signal handlers i.e. when saved_handler->sa_handler == SIG_DFL if (saved_handler && saved_handler->sa_handler) { if (!(saved_handler->sa_flags & SA_SIGINFO)) { saved_handler->sa_handler (signal); @@ -209,6 +210,27 @@ MONO_SIG_HANDLER_SIGNATURE (mono_chain_signal) return FALSE; } + +/* + * mono_chain_signal_to_default_sigsegv_handler: + * + * Call the original SIGSEGV signal handler in cases when the original handler is + * sigaction.sa_handler == SIG_DFL. This is used to propagate the crash to the OS. + */ +void +mono_chain_signal_to_default_sigsegv_handler () +{ + struct sigaction *saved_handler = (struct sigaction *)get_saved_signal_handler (SIGSEGV); + + if (saved_handler && saved_handler->sa_handler == SIG_DFL) { + sigaction (SIGSEGV, saved_handler, NULL); + raise (SIGSEGV); + } else { + g_async_safe_printf ("\nFailed to chain SIGSEGV signal to the default handler.\n"); + } +} + + MONO_SIG_HANDLER_FUNC (static, sigabrt_signal_handler) { MonoJitInfo *ji = NULL; @@ -348,8 +370,14 @@ add_signal_handler (int signo, MonoSignalHandler handler, int flags) /* if there was already a handler in place for this signal, store it */ if (! (previous_sa.sa_flags & SA_SIGINFO) && - (SIG_DFL == previous_sa.sa_handler)) { - /* it there is no sa_sigaction function and the sa_handler is default, we can safely ignore this */ + (SIG_DFL == previous_sa.sa_handler) && signo != SIGSEGV) { + /* + * If there is no sa_sigaction function and the sa_handler is default, + * it means the currently registered handler for this signal is the default one. + * For signal chaining, we need to store the default SIGSEGV handler so that the crash + * is properly propagated, while default handlers for other signals are ignored and + * are not considered. + */ } else { if (mono_do_signal_chaining) save_old_signal_handler (signo, &previous_sa); diff --git a/src/mono/mono/mini/mini-runtime.c b/src/mono/mono/mini/mini-runtime.c index f431897becd00..bcd7754da660a 100644 --- a/src/mono/mono/mini/mini-runtime.c +++ b/src/mono/mono/mini/mini-runtime.c @@ -3908,7 +3908,8 @@ MONO_SIG_HANDLER_FUNC (, mono_sigsegv_signal_handler) mono_handle_native_crash (mono_get_signame (SIGSEGV), &mctx, (MONO_SIG_HANDLER_INFO_TYPE*)info); if (mono_do_crash_chaining) { - mono_chain_signal (MONO_SIG_HANDLER_PARAMS); + if (!mono_chain_signal (MONO_SIG_HANDLER_PARAMS)) + mono_chain_signal_to_default_sigsegv_handler (); return; } } @@ -3918,7 +3919,8 @@ MONO_SIG_HANDLER_FUNC (, mono_sigsegv_signal_handler) } else { mono_handle_native_crash (mono_get_signame (SIGSEGV), &mctx, (MONO_SIG_HANDLER_INFO_TYPE*)info); if (mono_do_crash_chaining) { - mono_chain_signal (MONO_SIG_HANDLER_PARAMS); + if (!mono_chain_signal (MONO_SIG_HANDLER_PARAMS)) + mono_chain_signal_to_default_sigsegv_handler (); return; } } diff --git a/src/mono/mono/mini/mini-runtime.h b/src/mono/mono/mini/mini-runtime.h index 5104a053b30c7..dc757726199fb 100644 --- a/src/mono/mono/mini/mini-runtime.h +++ b/src/mono/mono/mini/mini-runtime.h @@ -678,6 +678,7 @@ void MONO_SIG_HANDLER_SIGNATURE (mono_sigsegv_signal_handler); void MONO_SIG_HANDLER_SIGNATURE (mono_sigint_signal_handler) ; void MONO_SIG_HANDLER_SIGNATURE (mono_sigterm_signal_handler) ; gboolean MONO_SIG_HANDLER_SIGNATURE (mono_chain_signal); +void mono_chain_signal_to_default_sigsegv_handler (); #if defined (HOST_WASM) diff --git a/src/mono/mono/mini/mini-wasm.c b/src/mono/mono/mini/mini-wasm.c index b4c1aaa1729b9..2305f338ed06c 100644 --- a/src/mono/mono/mini/mini-wasm.c +++ b/src/mono/mono/mini/mini-wasm.c @@ -587,6 +587,12 @@ MONO_SIG_HANDLER_SIGNATURE (mono_chain_signal) return FALSE; } +void +mono_chain_signal_to_default_sigsegv_handler () +{ + g_error ("mono_chain_signal_to_default_sigsegv_handler not supported on WASM"); +} + gboolean mono_thread_state_init_from_handle (MonoThreadUnwindState *tctx, MonoThreadInfo *info, void *sigctx) { diff --git a/src/mono/mono/mini/mini-windows.c b/src/mono/mono/mini/mini-windows.c index 322488abdaab7..94056dad20bbf 100644 --- a/src/mono/mono/mini/mini-windows.c +++ b/src/mono/mono/mini/mini-windows.c @@ -252,6 +252,12 @@ MONO_SIG_HANDLER_SIGNATURE (mono_chain_signal) return TRUE; } +void +mono_chain_signal_to_default_sigsegv_handler () +{ + g_error ("mono_chain_signal_to_default_sigsegv_handler not supported on Windows"); +} + #if !HAVE_EXTERN_DEFINED_NATIVE_CRASH_HANDLER #ifndef MONO_CROSS_COMPILE void From 45b19a696ba227a98c4ac5a0b23d0a64d5154db9 Mon Sep 17 00:00:00 2001 From: Ivan Povazan Date: Wed, 18 Dec 2024 20:24:15 +0100 Subject: [PATCH 2/2] cleanup --- src/mono/mono/mini/mini-posix.c | 2 +- src/mono/mono/mini/mini-runtime.h | 2 +- src/mono/mono/mini/mini-wasm.c | 2 +- src/mono/mono/mini/mini-windows.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/mono/mono/mini/mini-posix.c b/src/mono/mono/mini/mini-posix.c index e39a5fe9200c3..fd8b480e5362d 100644 --- a/src/mono/mono/mini/mini-posix.c +++ b/src/mono/mono/mini/mini-posix.c @@ -218,7 +218,7 @@ MONO_SIG_HANDLER_SIGNATURE (mono_chain_signal) * sigaction.sa_handler == SIG_DFL. This is used to propagate the crash to the OS. */ void -mono_chain_signal_to_default_sigsegv_handler () +mono_chain_signal_to_default_sigsegv_handler (void) { struct sigaction *saved_handler = (struct sigaction *)get_saved_signal_handler (SIGSEGV); diff --git a/src/mono/mono/mini/mini-runtime.h b/src/mono/mono/mini/mini-runtime.h index dc757726199fb..7779909bd944e 100644 --- a/src/mono/mono/mini/mini-runtime.h +++ b/src/mono/mono/mini/mini-runtime.h @@ -678,7 +678,7 @@ void MONO_SIG_HANDLER_SIGNATURE (mono_sigsegv_signal_handler); void MONO_SIG_HANDLER_SIGNATURE (mono_sigint_signal_handler) ; void MONO_SIG_HANDLER_SIGNATURE (mono_sigterm_signal_handler) ; gboolean MONO_SIG_HANDLER_SIGNATURE (mono_chain_signal); -void mono_chain_signal_to_default_sigsegv_handler (); +void mono_chain_signal_to_default_sigsegv_handler (void); #if defined (HOST_WASM) diff --git a/src/mono/mono/mini/mini-wasm.c b/src/mono/mono/mini/mini-wasm.c index 2305f338ed06c..4a9eb21b137ad 100644 --- a/src/mono/mono/mini/mini-wasm.c +++ b/src/mono/mono/mini/mini-wasm.c @@ -588,7 +588,7 @@ MONO_SIG_HANDLER_SIGNATURE (mono_chain_signal) } void -mono_chain_signal_to_default_sigsegv_handler () +mono_chain_signal_to_default_sigsegv_handler (void) { g_error ("mono_chain_signal_to_default_sigsegv_handler not supported on WASM"); } diff --git a/src/mono/mono/mini/mini-windows.c b/src/mono/mono/mini/mini-windows.c index 94056dad20bbf..cb79586c98a5e 100644 --- a/src/mono/mono/mini/mini-windows.c +++ b/src/mono/mono/mini/mini-windows.c @@ -253,7 +253,7 @@ MONO_SIG_HANDLER_SIGNATURE (mono_chain_signal) } void -mono_chain_signal_to_default_sigsegv_handler () +mono_chain_signal_to_default_sigsegv_handler (void) { g_error ("mono_chain_signal_to_default_sigsegv_handler not supported on Windows"); }