Skip to content

Commit fe862d0

Browse files
YYChen01988lemnik
andauthored
Report signal codes on native crashes (#2135)
* feat(signal) add more detail for signal * fix(test) fixed fail e2e tests * feat(signal) signal code message update and add param for bsg_native_signal_code_names * feat(signal) signal code message update and add param for bsg_native_signal_code_names * test(ndk): added ILLOPC as a possible sig_code for the trap() test * refactor(ndk): refactored the signal-code messages to be built with macros to reduce possible mistakes * chore(changelog): added CHANGELOG entry for #2135 --------- Co-authored-by: jason <[email protected]>
1 parent 0f4b1d5 commit fe862d0

File tree

4 files changed

+127
-17
lines changed

4 files changed

+127
-17
lines changed

CHANGELOG.md

+7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
# Changelog
22

3+
## TBD
4+
5+
### Enhancements
6+
7+
* Native crashes will now include their signal code (where applicable) in the error message
8+
[#2135](https://github.com/bugsnag/bugsnag-android/pull/2135)
9+
310
## 6.11.0 (2025-01-22)
411

512
### Enhancements

bugsnag-plugin-android-ndk/src/main/jni/handlers/signal_handler.c

+101-9
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
#include "../utils/string.h"
1717
#include "../utils/threads.h"
1818
#define BSG_HANDLED_SIGNAL_COUNT 6
19-
19+
#define BSG_SIGNAL_CODE_COUNT 15
2020
/**
2121
* Function to capture signals and write reports to disk
2222
* @param signum The captured signal number
@@ -48,6 +48,17 @@ struct sigaction *bsg_global_sigaction;
4848
/* the previous signal handler array */
4949
struct sigaction *bsg_global_sigaction_previous;
5050

51+
#define MSG_SIGILL "Illegal instruction"
52+
#define MSG_SIGTRAP "Trace/breakpoint trap"
53+
#define MSG_SIGABRT "Abort program"
54+
#define MSG_SIGBUS "Bus error (bad memory access)"
55+
#define MSG_SIGFPE "Floating-point exception"
56+
#define MSG_SIGSEGV "Segmentation violation (invalid memory reference)"
57+
58+
#define xstr(s) str(s)
59+
#define str(s) #s
60+
#define SIG_CODE_MESSAGE(msg, code) (msg ", code " xstr(code) " (" #code ")")
61+
5162
/**
5263
* Native signals which will be captured by the Bugsnag signal handler™
5364
*/
@@ -56,12 +67,88 @@ static const int bsg_native_signals[BSG_HANDLED_SIGNAL_COUNT + 1] = {
5667
static const char bsg_native_signal_names[BSG_HANDLED_SIGNAL_COUNT + 1][8] = {
5768
"SIGILL", "SIGTRAP", "SIGABRT", "SIGBUS", "SIGFPE", "SIGSEGV"};
5869
static const char bsg_native_signal_msgs[BSG_HANDLED_SIGNAL_COUNT + 1][60] = {
59-
"Illegal instruction",
60-
"Trace/breakpoint trap",
61-
"Abort program",
62-
"Bus error (bad memory access)",
63-
"Floating-point exception",
64-
"Segmentation violation (invalid memory reference)"};
70+
MSG_SIGILL, MSG_SIGTRAP, MSG_SIGABRT, MSG_SIGBUS, MSG_SIGFPE, MSG_SIGSEGV};
71+
72+
static const char
73+
bsg_native_signal_code_names[BSG_HANDLED_SIGNAL_COUNT +
74+
1][BSG_SIGNAL_CODE_COUNT + 1][72] = {
75+
{SIG_CODE_MESSAGE(MSG_SIGILL, ILL_ILLOPC),
76+
SIG_CODE_MESSAGE(MSG_SIGILL, ILL_ILLOPN),
77+
SIG_CODE_MESSAGE(MSG_SIGILL, ILL_ILLADR),
78+
SIG_CODE_MESSAGE(MSG_SIGILL, ILL_ILLTRP),
79+
SIG_CODE_MESSAGE(MSG_SIGILL, ILL_PRVOPC),
80+
SIG_CODE_MESSAGE(MSG_SIGILL, ILL_PRVREG),
81+
SIG_CODE_MESSAGE(MSG_SIGILL, ILL_COPROC),
82+
SIG_CODE_MESSAGE(MSG_SIGILL, ILL_BADSTK),
83+
SIG_CODE_MESSAGE(MSG_SIGILL, ILL_BADIADDR),
84+
SIG_CODE_MESSAGE(MSG_SIGILL, __ILL_BREAK),
85+
SIG_CODE_MESSAGE(MSG_SIGILL, __ILL_BNDMOD)},
86+
{SIG_CODE_MESSAGE(MSG_SIGTRAP, TRAP_BRKPT),
87+
SIG_CODE_MESSAGE(MSG_SIGTRAP, TRAP_TRACE),
88+
SIG_CODE_MESSAGE(MSG_SIGTRAP, TRAP_BRANCH),
89+
SIG_CODE_MESSAGE(MSG_SIGTRAP, TRAP_HWBKPT),
90+
SIG_CODE_MESSAGE(MSG_SIGTRAP, TRAP_UNK),
91+
SIG_CODE_MESSAGE(MSG_SIGTRAP, TRAP_PERF)},
92+
{0},
93+
{SIG_CODE_MESSAGE(MSG_SIGBUS, BUS_ADRALN),
94+
SIG_CODE_MESSAGE(MSG_SIGBUS, BUS_ADRERR),
95+
SIG_CODE_MESSAGE(MSG_SIGBUS, BUS_OBJERR),
96+
SIG_CODE_MESSAGE(MSG_SIGBUS, BUS_MCEERR_AR),
97+
SIG_CODE_MESSAGE(MSG_SIGBUS, BUS_MCEERR_AO)},
98+
{SIG_CODE_MESSAGE(MSG_SIGFPE, FPE_INTDIV),
99+
SIG_CODE_MESSAGE(MSG_SIGFPE, FPE_INTOVF),
100+
SIG_CODE_MESSAGE(MSG_SIGFPE, FPE_FLTDIV),
101+
SIG_CODE_MESSAGE(MSG_SIGFPE, FPE_FLTOVF),
102+
SIG_CODE_MESSAGE(MSG_SIGFPE, FPE_FLTUND),
103+
SIG_CODE_MESSAGE(MSG_SIGFPE, FPE_FLTRES),
104+
SIG_CODE_MESSAGE(MSG_SIGFPE, FPE_FLTINV),
105+
SIG_CODE_MESSAGE(MSG_SIGFPE, FPE_FLTSUB),
106+
SIG_CODE_MESSAGE(MSG_SIGFPE, __FPE_DECOVF),
107+
SIG_CODE_MESSAGE(MSG_SIGFPE, __FPE_DECDIV),
108+
SIG_CODE_MESSAGE(MSG_SIGFPE, __FPE_DECERR),
109+
SIG_CODE_MESSAGE(MSG_SIGFPE, __FPE_INVASC),
110+
SIG_CODE_MESSAGE(MSG_SIGFPE, __FPE_INVDEC),
111+
SIG_CODE_MESSAGE(MSG_SIGFPE, FPE_FLTUNK),
112+
SIG_CODE_MESSAGE(MSG_SIGFPE, FPE_CONDTRAP)},
113+
{SIG_CODE_MESSAGE(MSG_SIGSEGV, SEGV_MAPERR),
114+
SIG_CODE_MESSAGE(MSG_SIGSEGV, SEGV_ACCERR),
115+
SIG_CODE_MESSAGE(MSG_SIGSEGV, SEGV_BNDERR),
116+
SIG_CODE_MESSAGE(MSG_SIGSEGV, SEGV_PKUERR),
117+
SIG_CODE_MESSAGE(MSG_SIGSEGV, SEGV_ACCADI),
118+
SIG_CODE_MESSAGE(MSG_SIGSEGV, SEGV_ADIDERR),
119+
SIG_CODE_MESSAGE(MSG_SIGSEGV, SEGV_ADIPERR),
120+
SIG_CODE_MESSAGE(MSG_SIGSEGV, SEGV_MTEAERR),
121+
SIG_CODE_MESSAGE(MSG_SIGSEGV, SEGV_MTESERR)}};
122+
123+
static const int bsg_native_signal_codes[BSG_HANDLED_SIGNAL_COUNT +
124+
1][BSG_SIGNAL_CODE_COUNT + 1] = {
125+
{ILL_ILLOPC, ILL_ILLOPN, ILL_ILLADR, ILL_ILLTRP, ILL_PRVOPC, ILL_PRVREG,
126+
ILL_COPROC, ILL_BADSTK, ILL_BADIADDR, __ILL_BREAK, __ILL_BNDMOD},
127+
{TRAP_BRKPT, TRAP_TRACE, TRAP_BRANCH, TRAP_HWBKPT, TRAP_UNK, TRAP_PERF},
128+
{BUS_ADRALN, BUS_ADRERR, BUS_OBJERR, BUS_MCEERR_AR, BUS_MCEERR_AO},
129+
{FPE_INTDIV, FPE_INTOVF, FPE_FLTDIV, FPE_FLTOVF, FPE_FLTUND, FPE_FLTRES,
130+
FPE_FLTINV, FPE_FLTSUB, __FPE_DECOVF, __FPE_DECDIV, __FPE_DECERR,
131+
__FPE_INVASC, __FPE_INVDEC, FPE_FLTUNK, FPE_CONDTRAP},
132+
{SEGV_MAPERR, SEGV_ACCERR, SEGV_BNDERR, SEGV_PKUERR, SEGV_ACCADI,
133+
SEGV_ADIDERR, SEGV_ADIPERR, SEGV_MTEAERR, SEGV_MTESERR}};
134+
135+
static const char *
136+
bsg_get_signal_code_description(const int signal,
137+
const int signal_code) __asyncsafe {
138+
for (int i = 0; i < BSG_HANDLED_SIGNAL_COUNT; i++) {
139+
if (bsg_native_signals[i] == signal) {
140+
for (int j = 0; j < BSG_SIGNAL_CODE_COUNT; j++) {
141+
if (bsg_native_signal_codes[i][j] == signal_code) {
142+
return bsg_native_signal_code_names[i][j];
143+
} else if (*bsg_native_signal_code_names[i][j] == 0) {
144+
// NULL in the signal_code_name array indicates no more known codes
145+
break;
146+
}
147+
}
148+
}
149+
}
150+
return NULL;
151+
}
65152

66153
bool bsg_handler_install_signal(bsg_environment *env) {
67154
if (bsg_global_env != NULL) {
@@ -195,12 +282,17 @@ void bsg_handle_signal(int signum, siginfo_t *info,
195282

196283
for (int i = 0; i < BSG_HANDLED_SIGNAL_COUNT; i++) {
197284
const int signal = bsg_native_signals[i];
285+
const int signal_code = info->si_code;
198286
if (signal == signum) {
199287
bsg_strncpy(bsg_global_env->next_event.error.errorClass,
200288
(char *)bsg_native_signal_names[i],
201289
sizeof(bsg_global_env->next_event.error.errorClass));
202-
bsg_strncpy(bsg_global_env->next_event.error.errorMessage,
203-
(char *)bsg_native_signal_msgs[i],
290+
const char *error_message =
291+
bsg_get_signal_code_description(signal, signal_code);
292+
if (error_message == NULL || *error_message == 0) {
293+
error_message = (char *)bsg_native_signal_msgs[i];
294+
}
295+
bsg_strncpy(bsg_global_env->next_event.error.errorMessage, error_message,
204296
sizeof(bsg_global_env->next_event.error.errorMessage));
205297
break;
206298
}

features/full_tests/native_crash_handling.feature

+9-4
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,11 @@ Feature: Native crash reporting
5252
| SIGILL |
5353
| SIGTRAP |
5454
And the exception "message" equals one of:
55-
| Illegal instruction |
56-
| Trace/breakpoint trap |
55+
| Illegal instruction |
56+
| Trace/breakpoint trap |
57+
| Illegal instruction, code 4 (ILL_ILLTRP) |
58+
| Illegal instruction, code 1 (ILL_ILLOPC) |
59+
| Trace/breakpoint trap, code 1 (TRAP_BRKPT) |
5760
And the exception "type" equals "c"
5861
And the event "severity" equals "error"
5962
And the event "unhandled" is true
@@ -132,8 +135,10 @@ Feature: Native crash reporting
132135
| SIGILL |
133136
| SIGTRAP |
134137
And the exception "message" equals one of:
135-
| Illegal instruction |
136-
| Trace/breakpoint trap |
138+
| Illegal instruction |
139+
| Trace/breakpoint trap |
140+
| Illegal instruction, code 1 (ILL_ILLOPC) |
141+
| Trace/breakpoint trap, code 1 (TRAP_BRKPT) |
137142
And the exception "type" equals "c"
138143
And the first significant stack frames match:
139144
| something_innocuous | libmonochrome.so | (ignore) |

features/full_tests/native_signal_raise.feature

+10-4
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@ Feature: Raising native signals
1010
And the error payload contains a completed unhandled native report
1111
And the exception "errorClass" equals "SIGILL"
1212
And the exception "message" equals one of:
13-
| Illegal instruction |
14-
| Trace/breakpoint trap |
13+
| Illegal instruction |
14+
| Trace/breakpoint trap |
15+
| Illegal instruction, code 4 (ILL_ILLTRP) |
16+
| Trace/breakpoint trap, code 5 (TRAP_UNK) |
1517
And the exception "type" equals "c"
1618
And the event "severity" equals "error"
1719
And the event "unhandled" is true
@@ -55,7 +57,9 @@ Feature: Raising native signals
5557
And I wait to receive an error
5658
And the error payload contains a completed unhandled native report
5759
And the exception "errorClass" equals "SIGFPE"
58-
And the exception "message" equals "Floating-point exception"
60+
And the exception "message" equals one of:
61+
| Floating-point exception |
62+
| Floating-point exception, code 8 (FPE_FLTSUB) |
5963
And the exception "type" equals "c"
6064
And the event "severity" equals "error"
6165
And the event "unhandled" is true
@@ -66,7 +70,9 @@ Feature: Raising native signals
6670
And I wait to receive an error
6771
And the error payload contains a completed unhandled native report
6872
And the exception "errorClass" equals "SIGTRAP"
69-
And the exception "message" equals "Trace/breakpoint trap"
73+
And the exception "message" equals one of:
74+
| Trace/breakpoint trap |
75+
| Trace/breakpoint trap, code 5 (TRAP_UNK) |
7076
And the exception "type" equals "c"
7177
And the event "severity" equals "error"
7278
And the event "unhandled" is true

0 commit comments

Comments
 (0)