diff --git a/src/mono/configure.ac b/src/mono/configure.ac index df94e2d25b8fd2..09e3192852c8fa 100644 --- a/src/mono/configure.ac +++ b/src/mono/configure.ac @@ -2936,6 +2936,23 @@ if test x$host_win32 = xno; then ]) fi + dnl ******************************** + dnl *** Checks for sys_signame *** + dnl ******************************** + AC_MSG_CHECKING(for sys_signame) + AC_TRY_LINK([ + #include + ], [ + const char *signame = sys_signame[0]; + ], [ + # Yes, we have it... + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_SYSSIGNAME, 1, [Have sys_signame]) + ], [ + AC_MSG_RESULT(no) + ]) + + dnl ******************************** dnl *** Checks for semaphore lib *** dnl ******************************** diff --git a/src/mono/mono/metadata/icall.c b/src/mono/mono/metadata/icall.c index e3357c03f7ee0e..bfb217dceb40eb 100644 --- a/src/mono/mono/metadata/icall.c +++ b/src/mono/mono/metadata/icall.c @@ -118,6 +118,7 @@ #include "icall-decl.h" #include "mono/utils/mono-threads-coop.h" #include "mono/metadata/icall-signatures.h" +#include "mono/utils/mono-signal-handler.h" //#define MONO_DEBUG_ICALLARRAY @@ -6525,7 +6526,7 @@ ves_icall_Mono_Runtime_SendMicrosoftTelemetry (const char *payload, guint64 port hashes.offset_rich_hash = unportable_hash; // Tells mono that we want to send the HANG EXC_TYPE. - const char *signal = "SIGTERM"; + const char *signal = mono_get_signame (SIGTERM); gboolean success = mono_merp_invoke (crashed_pid, signal, payload, &hashes); if (!success) { diff --git a/src/mono/mono/mini/exceptions-amd64.c b/src/mono/mono/mini/exceptions-amd64.c index a551ea0cabc1cc..cd0397ef39ed24 100644 --- a/src/mono/mono/mini/exceptions-amd64.c +++ b/src/mono/mono/mini/exceptions-amd64.c @@ -66,7 +66,7 @@ static LONG CALLBACK seh_unhandled_exception_filter(EXCEPTION_POINTERS* ep) #endif if (mono_dump_start ()) - mono_handle_native_crash ("SIGSEGV", NULL, NULL); + mono_handle_native_crash (mono_get_signame (SIGSEGV), NULL, NULL); return EXCEPTION_CONTINUE_SEARCH; } @@ -876,7 +876,7 @@ altstack_handle_and_restore (MonoContext *ctx, MonoObject *obj, guint32 flags) if (!ji || (!stack_ovf && !nullref)) { if (mono_dump_start ()) - mono_handle_native_crash ("SIGSEGV", ctx, NULL); + mono_handle_native_crash (mono_get_signame (SIGSEGV), ctx, NULL); // if couldn't dump or if mono_handle_native_crash returns, abort abort (); } diff --git a/src/mono/mono/mini/exceptions-ppc.c b/src/mono/mono/mini/exceptions-ppc.c index d14f8383eba915..867dd1eae0f832 100644 --- a/src/mono/mono/mini/exceptions-ppc.c +++ b/src/mono/mono/mini/exceptions-ppc.c @@ -676,7 +676,7 @@ mono_arch_handle_altstack_exception (void *sigctx, MONO_SIG_HANDLER_INFO_TYPE *s } if (!ji) if (mono_dump_start ()) - mono_handle_native_crash ("SIGSEGV", (MonoContext*)sigctx, siginfo); + mono_handle_native_crash (mono_get_signame (SIGSEGV), (MonoContext*)sigctx, siginfo); /* setup a call frame on the real stack so that control is returned there * and exception handling can continue. * The frame looks like: diff --git a/src/mono/mono/mini/exceptions-x86.c b/src/mono/mono/mini/exceptions-x86.c index 467a4bda47cf98..22e54bc9258a51 100644 --- a/src/mono/mono/mini/exceptions-x86.c +++ b/src/mono/mono/mini/exceptions-x86.c @@ -67,7 +67,7 @@ static LONG CALLBACK seh_unhandled_exception_filter(EXCEPTION_POINTERS* ep) } #endif if (mono_dump_start ()) - mono_handle_native_crash ("SIGSEGV", NULL, NULL); + mono_handle_native_crash (mono_get_signame (SIGSEGV), NULL, NULL); return EXCEPTION_CONTINUE_SEARCH; } @@ -1140,7 +1140,7 @@ mono_arch_handle_altstack_exception (void *sigctx, MONO_SIG_HANDLER_INFO_TYPE *s MonoContext mctx; mono_sigctx_to_monoctx (sigctx, &mctx); if (mono_dump_start ()) - mono_handle_native_crash ("SIGSEGV", &mctx, siginfo); + mono_handle_native_crash (mono_get_signame (SIGSEGV), &mctx, siginfo); else abort (); } diff --git a/src/mono/mono/mini/mini-posix.c b/src/mono/mono/mini/mini-posix.c index fd32733317bb80..2d11b566a4513e 100644 --- a/src/mono/mono/mini/mini-posix.c +++ b/src/mono/mono/mini/mini-posix.c @@ -231,7 +231,7 @@ MONO_SIG_HANDLER_FUNC (static, sigabrt_signal_handler) return; mono_sigctx_to_monoctx (ctx, &mctx); if (mono_dump_start ()) - mono_handle_native_crash ("SIGABRT", &mctx, info); + mono_handle_native_crash (mono_get_signame (info->si_signo), &mctx, info); else abort (); } @@ -240,6 +240,7 @@ MONO_SIG_HANDLER_FUNC (static, sigabrt_signal_handler) MONO_SIG_HANDLER_FUNC (static, sigterm_signal_handler) { #ifndef DISABLE_CRASH_REPORTING + MONO_SIG_HANDLER_INFO_TYPE *info = MONO_SIG_HANDLER_GET_INFO (); MONO_SIG_HANDLER_GET_CONTEXT; // Note: this is only run from the non-controlling thread @@ -252,7 +253,7 @@ MONO_SIG_HANDLER_FUNC (static, sigterm_signal_handler) // running. Returns FALSE on unrecoverable error. if (mono_dump_start ()) { // Process was killed from outside since crash reporting wasn't running yet. - mono_handle_native_crash ("SIGTERM", &mctx, NULL); + mono_handle_native_crash (mono_get_signame (info->si_signo), &mctx, NULL); } else { // Crash reporting already running and we got a second SIGTERM from as part of thread-summarizing if (!mono_threads_summarize_execute (&mctx, &output, &hashes, FALSE, NULL, 0)) @@ -437,6 +438,7 @@ mono_runtime_posix_install_handlers (void) sigset_t signal_set; sigemptyset (&signal_set); + mono_load_signames (); if (mini_debug_options.handle_sigint) { add_signal_handler (SIGINT, mono_sigint_signal_handler, SA_RESTART); sigaddset (&signal_set, SIGINT); @@ -446,7 +448,7 @@ mono_runtime_posix_install_handlers (void) sigaddset (&signal_set, SIGFPE); add_signal_handler (SIGQUIT, sigquit_signal_handler, SA_RESTART); sigaddset (&signal_set, SIGQUIT); - add_signal_handler (SIGILL, mono_sigill_signal_handler, 0); + add_signal_handler (SIGILL, mono_crashing_signal_handler, 0); sigaddset (&signal_set, SIGILL); add_signal_handler (SIGBUS, mono_sigsegv_signal_handler, 0); sigaddset (&signal_set, SIGBUS); @@ -454,6 +456,10 @@ mono_runtime_posix_install_handlers (void) add_signal_handler (SIGUSR2, sigusr2_signal_handler, SA_RESTART); sigaddset (&signal_set, SIGUSR2); } + add_signal_handler (SIGTRAP, mono_crashing_signal_handler, 0); + sigaddset (&signal_set, SIGTRAP); + add_signal_handler (SIGSYS, mono_crashing_signal_handler, 0); + sigaddset (&signal_set, SIGSYS); /* it seems to have become a common bug for some programs that run as parents * of many processes to block signal delivery for real time signals. diff --git a/src/mono/mono/mini/mini-runtime.c b/src/mono/mono/mini/mini-runtime.c index 6b4d396c9d9e6c..456568b179bd7f 100644 --- a/src/mono/mono/mini/mini-runtime.c +++ b/src/mono/mono/mini/mini-runtime.c @@ -3226,7 +3226,7 @@ MONO_SIG_HANDLER_FUNC (, mono_sigfpe_signal_handler) mono_sigctx_to_monoctx (ctx, &mctx); if (mono_dump_start ()) - mono_handle_native_crash ("SIGFPE", &mctx, info); + mono_handle_native_crash (mono_get_signame (SIGFPE), &mctx, info); if (mono_do_crash_chaining) { mono_chain_signal (MONO_SIG_HANDLER_PARAMS); goto exit; @@ -3239,7 +3239,7 @@ MONO_SIG_HANDLER_FUNC (, mono_sigfpe_signal_handler) MONO_EXIT_GC_UNSAFE_UNBALANCED; } -MONO_SIG_HANDLER_FUNC (, mono_sigill_signal_handler) +MONO_SIG_HANDLER_FUNC (, mono_crashing_signal_handler) { MonoContext mctx; MONO_SIG_HANDLER_INFO_TYPE *info = MONO_SIG_HANDLER_GET_INFO (); @@ -3250,12 +3250,15 @@ MONO_SIG_HANDLER_FUNC (, mono_sigill_signal_handler) mono_sigctx_to_monoctx (ctx, &mctx); if (mono_dump_start ()) - mono_handle_native_crash ("SIGILL", &mctx, info); +#if defined(HAVE_SIG_INFO) && !defined(HOST_WIN32) // info is a siginfo_t + mono_handle_native_crash (mono_get_signame (info->si_signo), &mctx, info); +#else + mono_handle_native_crash (mono_get_signame (SIGTERM), &mctx, info); +#endif if (mono_do_crash_chaining) { mono_chain_signal (MONO_SIG_HANDLER_PARAMS); return; } - } #if defined(MONO_ARCH_USE_SIGACTION) || defined(HOST_WIN32) @@ -3325,6 +3328,9 @@ MONO_SIG_HANDLER_FUNC (, mono_sigsegv_signal_handler) mono_aot_handle_pagefault (info->si_addr); return; } + int signo = info->si_signo; +#else + int signo = SIGSEGV; #endif /* The thread might no be registered with the runtime */ @@ -3332,7 +3338,7 @@ MONO_SIG_HANDLER_FUNC (, mono_sigsegv_signal_handler) if (!mono_do_crash_chaining && mono_chain_signal (MONO_SIG_HANDLER_PARAMS)) return; if (mono_dump_start()) - mono_handle_native_crash ("SIGSEGV", &mctx, info); + mono_handle_native_crash (mono_get_signame (signo), &mctx, info); if (mono_do_crash_chaining) { mono_chain_signal (MONO_SIG_HANDLER_PARAMS); return; @@ -3375,7 +3381,7 @@ MONO_SIG_HANDLER_FUNC (, mono_sigsegv_signal_handler) } else { // FIXME: This shouldn't run on the altstack if (mono_dump_start ()) - mono_handle_native_crash ("SIGSEGV", &mctx, info); + mono_handle_native_crash (mono_get_signame (SIGSEGV), &mctx, info); } #endif } @@ -3386,7 +3392,7 @@ MONO_SIG_HANDLER_FUNC (, mono_sigsegv_signal_handler) return; if (mono_dump_start ()) - mono_handle_native_crash ("SIGSEGV", &mctx, (MONO_SIG_HANDLER_INFO_TYPE*)info); + 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); @@ -3398,7 +3404,7 @@ MONO_SIG_HANDLER_FUNC (, mono_sigsegv_signal_handler) mono_arch_handle_exception (ctx, NULL); } else { if (mono_dump_start ()) - mono_handle_native_crash ("SIGSEGV", &mctx, (MONO_SIG_HANDLER_INFO_TYPE*)info); + mono_handle_native_crash (mono_get_signame (SIGSEGV), &mctx, (MONO_SIG_HANDLER_INFO_TYPE*)info); } #endif } diff --git a/src/mono/mono/mini/mini-runtime.h b/src/mono/mono/mini/mini-runtime.h index 91b80ab1e911a5..43b12ac63f7051 100644 --- a/src/mono/mono/mini/mini-runtime.h +++ b/src/mono/mono/mini/mini-runtime.h @@ -569,7 +569,7 @@ mono_is_addr_implicit_null_check (void *addr); #endif void MONO_SIG_HANDLER_SIGNATURE (mono_sigfpe_signal_handler) ; -void MONO_SIG_HANDLER_SIGNATURE (mono_sigill_signal_handler) ; +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); diff --git a/src/mono/mono/mini/mini-windows.c b/src/mono/mono/mini/mini-windows.c index 6a02867da6de32..673aeefeeede3b 100644 --- a/src/mono/mono/mini/mini-windows.c +++ b/src/mono/mono/mini/mini-windows.c @@ -193,7 +193,7 @@ mono_runtime_install_handlers (void) #ifndef MONO_CROSS_COMPILE win32_seh_init(); win32_seh_set_handler(SIGFPE, mono_sigfpe_signal_handler); - win32_seh_set_handler(SIGILL, mono_sigill_signal_handler); + win32_seh_set_handler(SIGILL, mono_crashing_signal_handler); win32_seh_set_handler(SIGSEGV, mono_sigsegv_signal_handler); if (mini_debug_options.handle_sigint) win32_seh_set_handler(SIGINT, mono_sigint_signal_handler); diff --git a/src/mono/mono/utils/Makefile.am b/src/mono/mono/utils/Makefile.am index 07befc3503d431..110065d4f818de 100644 --- a/src/mono/mono/utils/Makefile.am +++ b/src/mono/mono/utils/Makefile.am @@ -206,6 +206,7 @@ monoutils_sources = \ bsearch.h \ bsearch.c \ mono-signal-handler.h \ + mono-signal-handler.c \ mono-conc-hashtable.h \ mono-conc-hashtable.c \ json.h \ diff --git a/src/mono/mono/utils/mono-merp.c b/src/mono/mono/utils/mono-merp.c index f12438c03e6712..cf78dbf63d4e60 100644 --- a/src/mono/mono/utils/mono-merp.c +++ b/src/mono/mono/utils/mono-merp.c @@ -40,6 +40,7 @@ #include #include #include +#include static const char * kernel_version_string (void) @@ -272,21 +273,27 @@ get_merp_exctype (MERPExcType exc) static MERPExcType parse_exception_type (const char *signal) { - if (!strcmp (signal, "SIGSEGV")) + if (!strcmp (signal, mono_get_signame (SIGSEGV))) return MERP_EXC_SIGSEGV; - if (!strcmp (signal, "SIGFPE")) + if (!strcmp (signal, mono_get_signame (SIGFPE))) return MERP_EXC_SIGFPE; - if (!strcmp (signal, "SIGILL")) + if (!strcmp (signal, mono_get_signame (SIGILL))) return MERP_EXC_SIGILL; - if (!strcmp (signal, "SIGABRT")) + if (!strcmp (signal, mono_get_signame (SIGABRT))) return MERP_EXC_SIGABRT; + if (!strcmp (signal, mono_get_signame (SIGTRAP))) + return MERP_EXC_SIGTRAP; + + if (!strcmp (signal, mono_get_signame (SIGSYS))) + return MERP_EXC_SIGSYS; + // Force quit == hang? // We need a default for this - if (!strcmp (signal, "SIGTERM")) + if (!strcmp (signal, mono_get_signame (SIGTERM))) return MERP_EXC_HANG; // FIXME: There are no other such signal diff --git a/src/mono/mono/utils/mono-signal-handler.c b/src/mono/mono/utils/mono-signal-handler.c new file mode 100644 index 00000000000000..8f0d6481bee6a0 --- /dev/null +++ b/src/mono/mono/utils/mono-signal-handler.c @@ -0,0 +1,78 @@ +#include "config.h" +#include +#include +#include "mono/utils/mono-signal-handler.h" + +struct mono_sigpair +{ + int signo; + const char* signame; +}; + +#if !defined (HAVE_SYSSIGNAME) +static struct mono_sigpair mono_signames[] = +{ + {SIGABRT, "SIGABRT"}, +#if defined (SIGKILL) + {SIGKILL, "SIGKILL"}, +#endif +#if defined (SIGTRAP) + {SIGTRAP, "SIGTRAP"}, +#endif +#if defined (SIGSYS) + {SIGSYS, "SIGSYS"}, +#endif + {SIGSEGV, "SIGSEGV"}, +#if defined (SIGQUIT) + {SIGQUIT, "SIGQUIT"}, +#endif + {SIGFPE, "SIGFPE"}, + {SIGILL, "SIGILL"}, +#if defined (SIGBUS) + {SIGBUS, "SIGBUS"} // How come this is seems not available on Android, but is used unconditionally in mini-posix.c:mono_runtime_posix_install_handlers ? +#endif +}; +#endif + +static struct mono_sigpair *sigpair_buf; +static int sigpair_buflen; + +void +mono_load_signames () +{ + if (sigpair_buf) + return; +#if defined (HAVE_SYSSIGNAME) + sigpair_buflen = sizeof (sys_signame) / sizeof (sys_signame [0]); + sigpair_buf = (struct mono_sigpair *) g_malloc (sigpair_buflen * sizeof (struct mono_sigpair)); + struct mono_sigpair *cur = sigpair_buf; + for (int i = 0; i < sigpair_buflen; ++i) + { + cur->signo = i; + cur->signame = sys_signame [i]; + cur++; + } + +#else + sigpair_buflen = sizeof (mono_signames) / sizeof (mono_signames [0]); + sigpair_buf = mono_signames; +#endif + +} + +const char * +mono_get_signame (int signo) +{ + const char *result = "UNKNOWN"; + struct mono_sigpair *cur = sigpair_buf; + for (int i = 0; i < sigpair_buflen; ++i) + { + if (cur->signo == signo) + { + result = cur->signame; + break; + } + cur++; + } + return result; +} diff --git a/src/mono/mono/utils/mono-signal-handler.h b/src/mono/mono/utils/mono-signal-handler.h index 80ea049239a3db..0b2b38482b2570 100644 --- a/src/mono/mono/utils/mono-signal-handler.h +++ b/src/mono/mono/utils/mono-signal-handler.h @@ -10,6 +10,7 @@ #define __MONO_SIGNAL_HANDLER_H__ #include "config.h" +#include /* * When a signal is delivered to a thread on a Krait Android device @@ -78,6 +79,7 @@ */ #ifdef HOST_WIN32 +#include #define MONO_SIG_HANDLER_INFO_TYPE MonoWindowsSigHandlerInfo typedef struct { /* Set to FALSE to indicate chained signal handler needs run. @@ -99,4 +101,7 @@ typedef struct { #define MONO_SIG_HANDLER_GET_INFO() (_info) #define MONO_SIG_HANDLER_GET_CONTEXT void *ctx = context; +void mono_load_signames (void); +const char * mono_get_signame (int signo); + #endif // __MONO_SIGNAL_HANDLER_H__ diff --git a/src/mono/msvc/libmonoutils-common.targets b/src/mono/msvc/libmonoutils-common.targets index 210c41e0493524..8c39996b1c621e 100644 --- a/src/mono/msvc/libmonoutils-common.targets +++ b/src/mono/msvc/libmonoutils-common.targets @@ -174,6 +174,7 @@ + diff --git a/src/mono/msvc/libmonoutils-common.targets.filters b/src/mono/msvc/libmonoutils-common.targets.filters index 9c26c4a93e2e13..0c00124958b689 100644 --- a/src/mono/msvc/libmonoutils-common.targets.filters +++ b/src/mono/msvc/libmonoutils-common.targets.filters @@ -403,6 +403,9 @@ Header Files$(MonoUtilsFilterSubFolder)\common + + Source Files$(MonoUtilsFilterSubFolder)\common + Header Files$(MonoUtilsFilterSubFolder)\common