daemon status 18b (#19884)
* add the fault address on signals * set sentry message/title on fatal()
Costa Tsaousis committed
Mar 17, 2025 at 12:36 UTC
0cf1e50130b599c039400f623e272580e68db24e
4 files changed
+30
-3
src/daemon/daemon-status-file.c
+14
-1
@@ -272,6 +272,12 @@ static void daemon_status_file_to_json(BUFFER *wb, DAEMON_STATUS_FILE *ds) {
272
273
if(ds->v >= 17)
274
buffer_json_member_add_boolean(wb, "sentry", ds->fatal.sentry);
275
+
276
+ if(ds->v >= 18) {
277
+ char buf[UINT64_HEX_MAX_LENGTH];
278
+ print_uint64_hex(buf, ds->fatal.fault_address);
279
+ buffer_json_member_add_string(wb, "fault_address", buf);
280
+ }
281
}
282
buffer_json_object_close(wb);
283
@@ -378,6 +384,10 @@ static bool daemon_status_file_from_json(json_object *jobj, void *data, BUFFER *
384
if(version >= 18) {
385
JSONC_PARSE_INT64_OR_ERROR_AND_RETURN(jobj, path, "reliability", ds->reliability, error, required_v18);
386
JSONC_PARSE_TXT2CHAR_OR_ERROR_AND_RETURN(jobj, path, "stack_traces", ds->stack_traces, error, required_v18);
387
+
388
+ char buf[UINT64_HEX_MAX_LENGTH];
389
+ JSONC_PARSE_TXT2CHAR_OR_ERROR_AND_RETURN(jobj, path, "fault_address", buf, error, required_v18);
390
+ ds->fatal.fault_address = str2ull_encoded(buf);
391
}
392
});
393
@@ -1361,7 +1371,7 @@ static void daemon_status_file_out_of_memory(void) {
1371
daemon_status_file_save_twice_if_we_can_get_stack_trace(static_save_buffer, &session_status, true);
1372
}
1373
1364
-bool daemon_status_file_deadly_signal_received(EXIT_REASON reason, SIGNAL_CODE code, bool chained_handler) {
1374
+bool daemon_status_file_deadly_signal_received(EXIT_REASON reason, SIGNAL_CODE code, void *fault_address, bool chained_handler) {
1375
FUNCTION_RUN_ONCE_RET(true);
1376
1377
// IMPORTANT: NO LOCKS OR ALLOCATIONS HERE, THIS FUNCTION IS CALLED FROM SIGNAL HANDLERS
@@ -1376,6 +1386,9 @@ bool daemon_status_file_deadly_signal_received(EXIT_REASON reason, SIGNAL_CODE c
1386
if(code)
1387
session_status.fatal.signal_code = code;
1388
1389
+ if(fault_address)
1390
+ session_status.fatal.fault_address = (uintptr_t)fault_address;
1391
+
1392
if(!session_status.fatal.thread_id)
1393
session_status.fatal.thread_id = gettid_cached();
1394
src/daemon/daemon-status-file.h
+2
-1
@@ -88,6 +88,7 @@ typedef struct daemon_status_file {
88
char thread[ND_THREAD_TAG_MAX + 1];
89
pid_t thread_id;
90
SIGNAL_CODE signal_code;
91
+ uintptr_t fault_address;
92
bool sentry; // true when the error was also reported to sentry
93
} fatal;
94
@@ -104,7 +105,7 @@ typedef struct daemon_status_file {
105
void daemon_status_file_update_status(DAEMON_STATUS status);
106
107
// returns true when the event is duplicate and should not be reported again
107
-bool daemon_status_file_deadly_signal_received(EXIT_REASON reason, SIGNAL_CODE code, bool chained_handler);
108
+bool daemon_status_file_deadly_signal_received(EXIT_REASON reason, SIGNAL_CODE code, void *fault_address, bool chained_handler);
109
110
// check for a crash
111
void daemon_status_file_check_crash(void);
src/daemon/sentry-native/sentry-native.c
+7
@@ -6,6 +6,7 @@
6
#include "sentry.h"
7
8
static char sentry_path[FILENAME_MAX] = "";
9
+static char g_sentry_event_message[512] = {0};
10
11
bool nd_sentry_crash_report_enabled = true;
12
@@ -90,6 +91,10 @@ static sentry_value_t nd_sentry_on_hook(sentry_value_t event) {
91
nd_sentry_set_tag("thread", daemon_status_file_get_fatal_thread());
92
nd_sentry_set_tag_uint64("thread_id", daemon_status_file_get_fatal_thread_id());
93
94
+ // set the title of the event
95
+ if(g_sentry_event_message[0])
96
+ sentry_value_set_by_key(event, "message", sentry_value_new_string(g_sentry_event_message));
97
+
98
return event;
99
}
100
@@ -229,6 +234,8 @@ void nd_sentry_add_fatal_message_as_breadcrumb(void) {
234
const char *function = daemon_status_file_get_fatal_function();
235
if(!function || !*function)
236
function = "unknown";
237
+ else
238
+ strncpyz(g_sentry_event_message, function, sizeof(g_sentry_event_message) - 1);
239
240
nd_sentry_set_tag_uptime();
241
src/daemon/signal-handler.c
+7
-1
@@ -65,7 +65,13 @@ void nd_signal_handler(int signo, siginfo_t *info, void *context __maybe_unused)
65
66
// Update the status file
67
SIGNAL_CODE sc = info ? signal_code(signo, info->si_code) : 0;
68
- if(daemon_status_file_deadly_signal_received(signals_waiting[i].reason, sc, chained_handler)) {
68
+
69
+ // Get fault address based on signal type
70
+ void *fault_address = NULL;
71
+ if (info && (signo == SIGSEGV || signo == SIGBUS || signo == SIGILL || signo == SIGFPE))
72
+ fault_address = info->si_addr;
73
+
74
+ if(daemon_status_file_deadly_signal_received(signals_waiting[i].reason, sc, fault_address, chained_handler)) {
75
// this is a duplicate event, do not send it to sentry
76
#ifdef ENABLE_SENTRY
77
nd_sentry_crash_report(false);