@cryptotaxi247 / netdata-1 / commits / 0cf1e5013

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);