From 616f85a9f5f1abb0a4c8fbc399342c39cc092e82 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 be8f83d396872d..69cd349ee74e15 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 0318c3d1689bcc..10815aceaf996c 100644 --- a/src/mono/mono/mini/mini-runtime.c +++ b/src/mono/mono/mini/mini-runtime.c @@ -3895,7 +3895,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; } } @@ -3905,7 +3906,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 19826d4c3f86b1..d715c6b8232198 100644 --- a/src/mono/mono/mini/mini-runtime.h +++ b/src/mono/mono/mini/mini-runtime.h @@ -673,6 +673,7 @@ void MONO_SIG_HANDLER_SIGNATURE (mono_crashing_signal_handler) ; void MONO_SIG_HANDLER_SIGNATURE (mono_sigsegv_signal_handler); void MONO_SIG_HANDLER_SIGNATURE (mono_sigint_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 21174bec0d860d..0ca72ba5d7eeaa 100644 --- a/src/mono/mono/mini/mini-wasm.c +++ b/src/mono/mono/mini/mini-wasm.c @@ -576,6 +576,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 f5d81c537a6910..d3b8cf314826c0 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 bb74f4636ef577af72336de274a57de4b14b138d 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 69cd349ee74e15..c0d79661aa8289 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 d715c6b8232198..dd07918269cf4c 100644 --- a/src/mono/mono/mini/mini-runtime.h +++ b/src/mono/mono/mini/mini-runtime.h @@ -673,7 +673,7 @@ void MONO_SIG_HANDLER_SIGNATURE (mono_crashing_signal_handler) ; void MONO_SIG_HANDLER_SIGNATURE (mono_sigsegv_signal_handler); void MONO_SIG_HANDLER_SIGNATURE (mono_sigint_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 0ca72ba5d7eeaa..00e97c95f4f2e1 100644 --- a/src/mono/mono/mini/mini-wasm.c +++ b/src/mono/mono/mini/mini-wasm.c @@ -577,7 +577,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 d3b8cf314826c0..b049428de79ce4 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"); }