Skip to content

Commit 635a990

Browse files
committed
[runtime] Report crash when receiving crashing signals
The default handlers for SIGTRAP, SIGSYS on macOS and Linux crash the process, so we now have Mono report this. This change also changes the presentation of the signal name on the stacktrace report dumped on error (from e.g. "SIGSEGV" to "segv").
1 parent 6f5e5af commit 635a990

15 files changed

+149
-24
lines changed

src/mono/configure.ac

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2936,6 +2936,23 @@ if test x$host_win32 = xno; then
29362936
])
29372937
fi
29382938

2939+
dnl ********************************
2940+
dnl *** Checks for sys_signame ***
2941+
dnl ********************************
2942+
AC_MSG_CHECKING(for sys_signame)
2943+
AC_TRY_LINK([
2944+
#include <signal.h>
2945+
], [
2946+
const char *signame = sys_signame[0];
2947+
], [
2948+
# Yes, we have it...
2949+
AC_MSG_RESULT(yes)
2950+
AC_DEFINE(HAVE_SYSSIGNAME, 1, [Have sys_signame])
2951+
], [
2952+
AC_MSG_RESULT(no)
2953+
])
2954+
2955+
29392956
dnl ********************************
29402957
dnl *** Checks for semaphore lib ***
29412958
dnl ********************************

src/mono/mono/metadata/icall.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@
118118
#include "icall-decl.h"
119119
#include "mono/utils/mono-threads-coop.h"
120120
#include "mono/metadata/icall-signatures.h"
121+
#include "mono/utils/mono-signal-handler.h"
121122

122123
//#define MONO_DEBUG_ICALLARRAY
123124

@@ -6525,7 +6526,7 @@ ves_icall_Mono_Runtime_SendMicrosoftTelemetry (const char *payload, guint64 port
65256526
hashes.offset_rich_hash = unportable_hash;
65266527

65276528
// Tells mono that we want to send the HANG EXC_TYPE.
6528-
const char *signal = "SIGTERM";
6529+
const char *signal = mono_get_signame (SIGTERM);
65296530

65306531
gboolean success = mono_merp_invoke (crashed_pid, signal, payload, &hashes);
65316532
if (!success) {

src/mono/mono/mini/exceptions-amd64.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ static LONG CALLBACK seh_unhandled_exception_filter(EXCEPTION_POINTERS* ep)
6666
#endif
6767

6868
if (mono_dump_start ())
69-
mono_handle_native_crash ("SIGSEGV", NULL, NULL);
69+
mono_handle_native_crash (mono_get_signame (SIGSEGV), NULL, NULL);
7070

7171
return EXCEPTION_CONTINUE_SEARCH;
7272
}
@@ -876,7 +876,7 @@ altstack_handle_and_restore (MonoContext *ctx, MonoObject *obj, guint32 flags)
876876

877877
if (!ji || (!stack_ovf && !nullref)) {
878878
if (mono_dump_start ())
879-
mono_handle_native_crash ("SIGSEGV", ctx, NULL);
879+
mono_handle_native_crash (mono_get_signame (SIGSEGV), ctx, NULL);
880880
// if couldn't dump or if mono_handle_native_crash returns, abort
881881
abort ();
882882
}

src/mono/mono/mini/exceptions-ppc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -676,7 +676,7 @@ mono_arch_handle_altstack_exception (void *sigctx, MONO_SIG_HANDLER_INFO_TYPE *s
676676
}
677677
if (!ji)
678678
if (mono_dump_start ())
679-
mono_handle_native_crash ("SIGSEGV", (MonoContext*)sigctx, siginfo);
679+
mono_handle_native_crash (mono_get_signame (SIGSEGV), (MonoContext*)sigctx, siginfo);
680680
/* setup a call frame on the real stack so that control is returned there
681681
* and exception handling can continue.
682682
* The frame looks like:

src/mono/mono/mini/exceptions-x86.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ static LONG CALLBACK seh_unhandled_exception_filter(EXCEPTION_POINTERS* ep)
6767
}
6868
#endif
6969
if (mono_dump_start ())
70-
mono_handle_native_crash ("SIGSEGV", NULL, NULL);
70+
mono_handle_native_crash (mono_get_signame (SIGSEGV), NULL, NULL);
7171

7272
return EXCEPTION_CONTINUE_SEARCH;
7373
}
@@ -1140,7 +1140,7 @@ mono_arch_handle_altstack_exception (void *sigctx, MONO_SIG_HANDLER_INFO_TYPE *s
11401140
MonoContext mctx;
11411141
mono_sigctx_to_monoctx (sigctx, &mctx);
11421142
if (mono_dump_start ())
1143-
mono_handle_native_crash ("SIGSEGV", &mctx, siginfo);
1143+
mono_handle_native_crash (mono_get_signame (SIGSEGV), &mctx, siginfo);
11441144
else
11451145
abort ();
11461146
}

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

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ MONO_SIG_HANDLER_FUNC (static, sigabrt_signal_handler)
231231
return;
232232
mono_sigctx_to_monoctx (ctx, &mctx);
233233
if (mono_dump_start ())
234-
mono_handle_native_crash ("SIGABRT", &mctx, info);
234+
mono_handle_native_crash (mono_get_signame (info->si_signo), &mctx, info);
235235
else
236236
abort ();
237237
}
@@ -240,6 +240,7 @@ MONO_SIG_HANDLER_FUNC (static, sigabrt_signal_handler)
240240
MONO_SIG_HANDLER_FUNC (static, sigterm_signal_handler)
241241
{
242242
#ifndef DISABLE_CRASH_REPORTING
243+
MONO_SIG_HANDLER_INFO_TYPE *info = MONO_SIG_HANDLER_GET_INFO ();
243244
MONO_SIG_HANDLER_GET_CONTEXT;
244245

245246
// Note: this is only run from the non-controlling thread
@@ -252,7 +253,7 @@ MONO_SIG_HANDLER_FUNC (static, sigterm_signal_handler)
252253
// running. Returns FALSE on unrecoverable error.
253254
if (mono_dump_start ()) {
254255
// Process was killed from outside since crash reporting wasn't running yet.
255-
mono_handle_native_crash ("SIGTERM", &mctx, NULL);
256+
mono_handle_native_crash (mono_get_signame (info->si_signo), &mctx, NULL);
256257
} else {
257258
// Crash reporting already running and we got a second SIGTERM from as part of thread-summarizing
258259
if (!mono_threads_summarize_execute (&mctx, &output, &hashes, FALSE, NULL, 0))
@@ -437,6 +438,7 @@ mono_runtime_posix_install_handlers (void)
437438

438439
sigset_t signal_set;
439440
sigemptyset (&signal_set);
441+
mono_load_signames ();
440442
if (mini_debug_options.handle_sigint) {
441443
add_signal_handler (SIGINT, mono_sigint_signal_handler, SA_RESTART);
442444
sigaddset (&signal_set, SIGINT);
@@ -446,14 +448,18 @@ mono_runtime_posix_install_handlers (void)
446448
sigaddset (&signal_set, SIGFPE);
447449
add_signal_handler (SIGQUIT, sigquit_signal_handler, SA_RESTART);
448450
sigaddset (&signal_set, SIGQUIT);
449-
add_signal_handler (SIGILL, mono_sigill_signal_handler, 0);
451+
add_signal_handler (SIGILL, mono_crashing_signal_handler, 0);
450452
sigaddset (&signal_set, SIGILL);
451453
add_signal_handler (SIGBUS, mono_sigsegv_signal_handler, 0);
452454
sigaddset (&signal_set, SIGBUS);
453455
if (mono_jit_trace_calls != NULL) {
454456
add_signal_handler (SIGUSR2, sigusr2_signal_handler, SA_RESTART);
455457
sigaddset (&signal_set, SIGUSR2);
456458
}
459+
add_signal_handler (SIGTRAP, mono_crashing_signal_handler, 0);
460+
sigaddset (&signal_set, SIGTRAP);
461+
add_signal_handler (SIGSYS, mono_crashing_signal_handler, 0);
462+
sigaddset (&signal_set, SIGSYS);
457463

458464
/* it seems to have become a common bug for some programs that run as parents
459465
* of many processes to block signal delivery for real time signals.

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

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3226,7 +3226,7 @@ MONO_SIG_HANDLER_FUNC (, mono_sigfpe_signal_handler)
32263226

32273227
mono_sigctx_to_monoctx (ctx, &mctx);
32283228
if (mono_dump_start ())
3229-
mono_handle_native_crash ("SIGFPE", &mctx, info);
3229+
mono_handle_native_crash (mono_get_signame (SIGFPE), &mctx, info);
32303230
if (mono_do_crash_chaining) {
32313231
mono_chain_signal (MONO_SIG_HANDLER_PARAMS);
32323232
goto exit;
@@ -3239,7 +3239,7 @@ MONO_SIG_HANDLER_FUNC (, mono_sigfpe_signal_handler)
32393239
MONO_EXIT_GC_UNSAFE_UNBALANCED;
32403240
}
32413241

3242-
MONO_SIG_HANDLER_FUNC (, mono_sigill_signal_handler)
3242+
MONO_SIG_HANDLER_FUNC (, mono_crashing_signal_handler)
32433243
{
32443244
MonoContext mctx;
32453245
MONO_SIG_HANDLER_INFO_TYPE *info = MONO_SIG_HANDLER_GET_INFO ();
@@ -3250,12 +3250,15 @@ MONO_SIG_HANDLER_FUNC (, mono_sigill_signal_handler)
32503250

32513251
mono_sigctx_to_monoctx (ctx, &mctx);
32523252
if (mono_dump_start ())
3253-
mono_handle_native_crash ("SIGILL", &mctx, info);
3253+
#if defined(HAVE_SIG_INFO) && !defined(HOST_WIN32) // info is a siginfo_t
3254+
mono_handle_native_crash (mono_get_signame (info->si_signo), &mctx, info);
3255+
#else
3256+
mono_handle_native_crash (mono_get_signame (SIGTERM), &mctx, info);
3257+
#endif
32543258
if (mono_do_crash_chaining) {
32553259
mono_chain_signal (MONO_SIG_HANDLER_PARAMS);
32563260
return;
32573261
}
3258-
32593262
}
32603263

32613264
#if defined(MONO_ARCH_USE_SIGACTION) || defined(HOST_WIN32)
@@ -3325,14 +3328,17 @@ MONO_SIG_HANDLER_FUNC (, mono_sigsegv_signal_handler)
33253328
mono_aot_handle_pagefault (info->si_addr);
33263329
return;
33273330
}
3331+
int signo = info->si_signo;
3332+
#else
3333+
int signo = SIGSEGV;
33283334
#endif
33293335

33303336
/* The thread might no be registered with the runtime */
33313337
if (!mono_domain_get () || !jit_tls) {
33323338
if (!mono_do_crash_chaining && mono_chain_signal (MONO_SIG_HANDLER_PARAMS))
33333339
return;
33343340
if (mono_dump_start())
3335-
mono_handle_native_crash ("SIGSEGV", &mctx, info);
3341+
mono_handle_native_crash (mono_get_signame (signo), &mctx, info);
33363342
if (mono_do_crash_chaining) {
33373343
mono_chain_signal (MONO_SIG_HANDLER_PARAMS);
33383344
return;
@@ -3375,7 +3381,7 @@ MONO_SIG_HANDLER_FUNC (, mono_sigsegv_signal_handler)
33753381
} else {
33763382
// FIXME: This shouldn't run on the altstack
33773383
if (mono_dump_start ())
3378-
mono_handle_native_crash ("SIGSEGV", &mctx, info);
3384+
mono_handle_native_crash (mono_get_signame (SIGSEGV), &mctx, info);
33793385
}
33803386
#endif
33813387
}
@@ -3386,7 +3392,7 @@ MONO_SIG_HANDLER_FUNC (, mono_sigsegv_signal_handler)
33863392
return;
33873393

33883394
if (mono_dump_start ())
3389-
mono_handle_native_crash ("SIGSEGV", &mctx, (MONO_SIG_HANDLER_INFO_TYPE*)info);
3395+
mono_handle_native_crash (mono_get_signame (SIGSEGV), &mctx, (MONO_SIG_HANDLER_INFO_TYPE*)info);
33903396

33913397
if (mono_do_crash_chaining) {
33923398
mono_chain_signal (MONO_SIG_HANDLER_PARAMS);
@@ -3398,7 +3404,7 @@ MONO_SIG_HANDLER_FUNC (, mono_sigsegv_signal_handler)
33983404
mono_arch_handle_exception (ctx, NULL);
33993405
} else {
34003406
if (mono_dump_start ())
3401-
mono_handle_native_crash ("SIGSEGV", &mctx, (MONO_SIG_HANDLER_INFO_TYPE*)info);
3407+
mono_handle_native_crash (mono_get_signame (SIGSEGV), &mctx, (MONO_SIG_HANDLER_INFO_TYPE*)info);
34023408
}
34033409
#endif
34043410
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -569,7 +569,7 @@ mono_is_addr_implicit_null_check (void *addr);
569569
#endif
570570

571571
void MONO_SIG_HANDLER_SIGNATURE (mono_sigfpe_signal_handler) ;
572-
void MONO_SIG_HANDLER_SIGNATURE (mono_sigill_signal_handler) ;
572+
void MONO_SIG_HANDLER_SIGNATURE (mono_crashing_signal_handler) ;
573573
void MONO_SIG_HANDLER_SIGNATURE (mono_sigsegv_signal_handler);
574574
void MONO_SIG_HANDLER_SIGNATURE (mono_sigint_signal_handler) ;
575575
gboolean MONO_SIG_HANDLER_SIGNATURE (mono_chain_signal);

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ mono_runtime_install_handlers (void)
193193
#ifndef MONO_CROSS_COMPILE
194194
win32_seh_init();
195195
win32_seh_set_handler(SIGFPE, mono_sigfpe_signal_handler);
196-
win32_seh_set_handler(SIGILL, mono_sigill_signal_handler);
196+
win32_seh_set_handler(SIGILL, mono_crashing_signal_handler);
197197
win32_seh_set_handler(SIGSEGV, mono_sigsegv_signal_handler);
198198
if (mini_debug_options.handle_sigint)
199199
win32_seh_set_handler(SIGINT, mono_sigint_signal_handler);

src/mono/mono/utils/Makefile.am

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ monoutils_sources = \
206206
bsearch.h \
207207
bsearch.c \
208208
mono-signal-handler.h \
209+
mono-signal-handler.c \
209210
mono-conc-hashtable.h \
210211
mono-conc-hashtable.c \
211212
json.h \

src/mono/mono/utils/mono-merp.c

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#include <mono/utils/json.h>
4141
#include <mono/utils/mono-state.h>
4242
#include <utils/mono-threads-debug.h>
43+
#include <utils/mono-signal-handler.h>
4344

4445
static const char *
4546
kernel_version_string (void)
@@ -272,21 +273,27 @@ get_merp_exctype (MERPExcType exc)
272273
static MERPExcType
273274
parse_exception_type (const char *signal)
274275
{
275-
if (!strcmp (signal, "SIGSEGV"))
276+
if (!strcmp (signal, mono_get_signame (SIGSEGV)))
276277
return MERP_EXC_SIGSEGV;
277278

278-
if (!strcmp (signal, "SIGFPE"))
279+
if (!strcmp (signal, mono_get_signame (SIGFPE)))
279280
return MERP_EXC_SIGFPE;
280281

281-
if (!strcmp (signal, "SIGILL"))
282+
if (!strcmp (signal, mono_get_signame (SIGILL)))
282283
return MERP_EXC_SIGILL;
283284

284-
if (!strcmp (signal, "SIGABRT"))
285+
if (!strcmp (signal, mono_get_signame (SIGABRT)))
285286
return MERP_EXC_SIGABRT;
286287

288+
if (!strcmp (signal, mono_get_signame (SIGTRAP)))
289+
return MERP_EXC_SIGTRAP;
290+
291+
if (!strcmp (signal, mono_get_signame (SIGSYS)))
292+
return MERP_EXC_SIGSYS;
293+
287294
// Force quit == hang?
288295
// We need a default for this
289-
if (!strcmp (signal, "SIGTERM"))
296+
if (!strcmp (signal, mono_get_signame (SIGTERM)))
290297
return MERP_EXC_HANG;
291298

292299
// FIXME: There are no other such signal
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
#include "config.h"
2+
#include <signal.h>
3+
#include <string.h>
4+
#include "mono/utils/mono-signal-handler.h"
5+
6+
struct mono_sigpair
7+
{
8+
int signo;
9+
const char* signame;
10+
};
11+
12+
#if !defined (HAVE_SYSSIGNAME)
13+
static struct mono_sigpair mono_signames[] =
14+
{
15+
{SIGABRT, "SIGABRT"},
16+
#if defined (SIGKILL)
17+
{SIGKILL, "SIGKILL"},
18+
#endif
19+
#if defined (SIGTRAP)
20+
{SIGTRAP, "SIGTRAP"},
21+
#endif
22+
#if defined (SIGSYS)
23+
{SIGSYS, "SIGSYS"},
24+
#endif
25+
{SIGSEGV, "SIGSEGV"},
26+
#if defined (SIGQUIT)
27+
{SIGQUIT, "SIGQUIT"},
28+
#endif
29+
{SIGFPE, "SIGFPE"},
30+
{SIGILL, "SIGILL"},
31+
#if defined (SIGBUS)
32+
{SIGBUS, "SIGBUS"} // How come this is seems not available on Android, but is used unconditionally in mini-posix.c:mono_runtime_posix_install_handlers ?
33+
#endif
34+
};
35+
#endif
36+
37+
static struct mono_sigpair *sigpair_buf;
38+
static int sigpair_buflen;
39+
40+
void
41+
mono_load_signames ()
42+
{
43+
if (sigpair_buf)
44+
return;
45+
#if defined (HAVE_SYSSIGNAME)
46+
sigpair_buflen = sizeof (sys_signame) / sizeof (sys_signame [0]);
47+
sigpair_buf = (struct mono_sigpair *) g_malloc (sigpair_buflen * sizeof (struct mono_sigpair));
48+
struct mono_sigpair *cur = sigpair_buf;
49+
for (int i = 0; i < sigpair_buflen; ++i)
50+
{
51+
cur->signo = i;
52+
cur->signame = sys_signame [i];
53+
cur++;
54+
}
55+
56+
#else
57+
sigpair_buflen = sizeof (mono_signames) / sizeof (mono_signames [0]);
58+
sigpair_buf = mono_signames;
59+
#endif
60+
61+
}
62+
63+
const char *
64+
mono_get_signame (int signo)
65+
{
66+
const char *result = "UNKNOWN";
67+
struct mono_sigpair *cur = sigpair_buf;
68+
for (int i = 0; i < sigpair_buflen; ++i)
69+
{
70+
if (cur->signo == signo)
71+
{
72+
result = cur->signame;
73+
break;
74+
}
75+
cur++;
76+
}
77+
return result;
78+
}

src/mono/mono/utils/mono-signal-handler.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#define __MONO_SIGNAL_HANDLER_H__
1111

1212
#include "config.h"
13+
#include <glib.h>
1314

1415
/*
1516
* When a signal is delivered to a thread on a Krait Android device
@@ -78,6 +79,7 @@
7879
*/
7980

8081
#ifdef HOST_WIN32
82+
#include <windows.h>
8183
#define MONO_SIG_HANDLER_INFO_TYPE MonoWindowsSigHandlerInfo
8284
typedef struct {
8385
/* Set to FALSE to indicate chained signal handler needs run.
@@ -99,4 +101,7 @@ typedef struct {
99101
#define MONO_SIG_HANDLER_GET_INFO() (_info)
100102
#define MONO_SIG_HANDLER_GET_CONTEXT void *ctx = context;
101103

104+
void mono_load_signames (void);
105+
const char * mono_get_signame (int signo);
106+
102107
#endif // __MONO_SIGNAL_HANDLER_H__

src/mono/msvc/libmonoutils-common.targets

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@
174174
<ClInclude Include="$(MonoSourceLocation)\mono\utils\bsearch.h" />
175175
<ClCompile Include="$(MonoSourceLocation)\mono\utils\bsearch.c" />
176176
<ClInclude Include="$(MonoSourceLocation)\mono\utils\mono-signal-handler.h" />
177+
<ClCompile Include="$(MonoSourceLocation)\mono\utils\mono-signal-handler.c" />
177178
<ClInclude Include="$(MonoSourceLocation)\mono\utils\mono-conc-hashtable.h" />
178179
<ClCompile Include="$(MonoSourceLocation)\mono\utils\mono-conc-hashtable.c" />
179180
<ClInclude Include="$(MonoSourceLocation)\mono\utils\json.h" />

0 commit comments

Comments
 (0)