Skip to content

Commit 599c02d

Browse files
[release/8.0-staging] [mono] Chain SIGSEGV native crashes to the default SIGSEGV handler (#110866)
* Consider SIG_DFL handlers for chaining SIGSEGV signals * cleanup --------- Co-authored-by: Ivan Povazan <[email protected]>
1 parent 771cecf commit 599c02d

File tree

5 files changed

+48
-5
lines changed

5 files changed

+48
-5
lines changed

src/mono/mono/mini/mini-posix.c

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -188,14 +188,15 @@ save_old_signal_handler (int signo, struct sigaction *old_action)
188188
*
189189
* Call the original signal handler for the signal given by the arguments, which
190190
* should be the same as for a signal handler. Returns TRUE if the original handler
191-
* was called, false otherwise.
191+
* was called, false otherwise. NOTE: sigaction.sa_handler == SIG_DFL handlers are not considered.
192192
*/
193193
gboolean
194194
MONO_SIG_HANDLER_SIGNATURE (mono_chain_signal)
195195
{
196196
int signal = MONO_SIG_HANDLER_GET_SIGNO ();
197197
struct sigaction *saved_handler = (struct sigaction *)get_saved_signal_handler (signal);
198198

199+
// Ignores chaining to default signal handlers i.e. when saved_handler->sa_handler == SIG_DFL
199200
if (saved_handler && saved_handler->sa_handler) {
200201
if (!(saved_handler->sa_flags & SA_SIGINFO)) {
201202
saved_handler->sa_handler (signal);
@@ -209,6 +210,27 @@ MONO_SIG_HANDLER_SIGNATURE (mono_chain_signal)
209210
return FALSE;
210211
}
211212

213+
214+
/*
215+
* mono_chain_signal_to_default_sigsegv_handler:
216+
*
217+
* Call the original SIGSEGV signal handler in cases when the original handler is
218+
* sigaction.sa_handler == SIG_DFL. This is used to propagate the crash to the OS.
219+
*/
220+
void
221+
mono_chain_signal_to_default_sigsegv_handler (void)
222+
{
223+
struct sigaction *saved_handler = (struct sigaction *)get_saved_signal_handler (SIGSEGV);
224+
225+
if (saved_handler && saved_handler->sa_handler == SIG_DFL) {
226+
sigaction (SIGSEGV, saved_handler, NULL);
227+
raise (SIGSEGV);
228+
} else {
229+
g_async_safe_printf ("\nFailed to chain SIGSEGV signal to the default handler.\n");
230+
}
231+
}
232+
233+
212234
MONO_SIG_HANDLER_FUNC (static, sigabrt_signal_handler)
213235
{
214236
MonoJitInfo *ji = NULL;
@@ -348,8 +370,14 @@ add_signal_handler (int signo, MonoSignalHandler handler, int flags)
348370

349371
/* if there was already a handler in place for this signal, store it */
350372
if (! (previous_sa.sa_flags & SA_SIGINFO) &&
351-
(SIG_DFL == previous_sa.sa_handler)) {
352-
/* it there is no sa_sigaction function and the sa_handler is default, we can safely ignore this */
373+
(SIG_DFL == previous_sa.sa_handler) && signo != SIGSEGV) {
374+
/*
375+
* If there is no sa_sigaction function and the sa_handler is default,
376+
* it means the currently registered handler for this signal is the default one.
377+
* For signal chaining, we need to store the default SIGSEGV handler so that the crash
378+
* is properly propagated, while default handlers for other signals are ignored and
379+
* are not considered.
380+
*/
353381
} else {
354382
if (mono_do_signal_chaining)
355383
save_old_signal_handler (signo, &previous_sa);

src/mono/mono/mini/mini-runtime.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3895,7 +3895,8 @@ MONO_SIG_HANDLER_FUNC (, mono_sigsegv_signal_handler)
38953895
mono_handle_native_crash (mono_get_signame (SIGSEGV), &mctx, (MONO_SIG_HANDLER_INFO_TYPE*)info);
38963896

38973897
if (mono_do_crash_chaining) {
3898-
mono_chain_signal (MONO_SIG_HANDLER_PARAMS);
3898+
if (!mono_chain_signal (MONO_SIG_HANDLER_PARAMS))
3899+
mono_chain_signal_to_default_sigsegv_handler ();
38993900
return;
39003901
}
39013902
}
@@ -3905,7 +3906,8 @@ MONO_SIG_HANDLER_FUNC (, mono_sigsegv_signal_handler)
39053906
} else {
39063907
mono_handle_native_crash (mono_get_signame (SIGSEGV), &mctx, (MONO_SIG_HANDLER_INFO_TYPE*)info);
39073908
if (mono_do_crash_chaining) {
3908-
mono_chain_signal (MONO_SIG_HANDLER_PARAMS);
3909+
if (!mono_chain_signal (MONO_SIG_HANDLER_PARAMS))
3910+
mono_chain_signal_to_default_sigsegv_handler ();
39093911
return;
39103912
}
39113913
}

src/mono/mono/mini/mini-runtime.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -673,6 +673,7 @@ void MONO_SIG_HANDLER_SIGNATURE (mono_crashing_signal_handler) ;
673673
void MONO_SIG_HANDLER_SIGNATURE (mono_sigsegv_signal_handler);
674674
void MONO_SIG_HANDLER_SIGNATURE (mono_sigint_signal_handler) ;
675675
gboolean MONO_SIG_HANDLER_SIGNATURE (mono_chain_signal);
676+
void mono_chain_signal_to_default_sigsegv_handler (void);
676677

677678
#if defined (HOST_WASM)
678679

src/mono/mono/mini/mini-wasm.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -576,6 +576,12 @@ MONO_SIG_HANDLER_SIGNATURE (mono_chain_signal)
576576
return FALSE;
577577
}
578578

579+
void
580+
mono_chain_signal_to_default_sigsegv_handler (void)
581+
{
582+
g_error ("mono_chain_signal_to_default_sigsegv_handler not supported on WASM");
583+
}
584+
579585
gboolean
580586
mono_thread_state_init_from_handle (MonoThreadUnwindState *tctx, MonoThreadInfo *info, void *sigctx)
581587
{

src/mono/mono/mini/mini-windows.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,12 @@ MONO_SIG_HANDLER_SIGNATURE (mono_chain_signal)
252252
return TRUE;
253253
}
254254

255+
void
256+
mono_chain_signal_to_default_sigsegv_handler (void)
257+
{
258+
g_error ("mono_chain_signal_to_default_sigsegv_handler not supported on Windows");
259+
}
260+
255261
#if !HAVE_EXTERN_DEFINED_NATIVE_CRASH_HANDLER
256262
#ifndef MONO_CROSS_COMPILE
257263
void

0 commit comments

Comments
 (0)