daemon status 27c (#20088)
* have a more meaningful fatal.function on signals without a root cause * set worker job id idle id to WORKER_UTILIZATION_MAX_JOB_TYPES
Costa Tsaousis committed
Apr 8, 2025 at 21:57 UTC
2b88dd847536586f7c637b5303d04b2cbce7c25e
3 files changed
+23
-6
src/daemon/status-file.c
+14
-1
@@ -1327,7 +1327,8 @@ static void daemon_status_file_save_twice_if_we_can_get_stack_trace(BUFFER *wb,
1327
1328
// Store the first netdata function from the stack trace if available
1329
const char *first_nd_fn = capture_stack_trace_root_cause_function();
1330
- if (first_nd_fn && *first_nd_fn && !ds->fatal.function[0])
1330
+ if (first_nd_fn && *first_nd_fn &&
1331
+ (!ds->fatal.function[0] || strncmp(ds->fatal.function, "thread:", 7) == 0))
1332
safecpy(ds->fatal.function, first_nd_fn);
1333
1334
if(buffer_strlen(wb) > 0) {
@@ -1448,6 +1449,18 @@ bool daemon_status_file_deadly_signal_received(EXIT_REASON reason, SIGNAL_CODE c
1449
1450
copy_and_clean_thread_name_if_empty(&session_status, nd_thread_tag_async_safe());
1451
1452
+ if(!session_status.fatal.function[0] ||
1453
+ strncmp(session_status.fatal.function, "startup(", 8) == 0 ||
1454
+ strncmp(session_status.fatal.function, "shutdown(", 9) == 0) {
1455
+ size_t len = 0;
1456
+ len = strcatz(session_status.fatal.function, len, "thread:", sizeof(session_status.fatal.function));
1457
+ len = strcatz(session_status.fatal.function, len, session_status.fatal.thread, sizeof(session_status.fatal.function));
1458
+ if(session_status.fatal.worker_job_id <= WORKER_UTILIZATION_MAX_JOB_TYPES) {
1459
+ len = strcatz(session_status.fatal.function, len, ":", sizeof(session_status.fatal.function));
1460
+ len += print_uint64(&session_status.fatal.function[len], session_status.fatal.worker_job_id);
1461
+ }
1462
+ }
1463
+
1464
dsf_release(session_status);
1465
1466
// the buffer should already be allocated, so this should normally do nothing
src/libnetdata/log/nd_log-stacktrace.c
+8
-5
@@ -298,6 +298,8 @@ bool capture_stack_trace_available(void) {
298
299
NEVER_INLINE
300
void capture_stack_trace(BUFFER *wb) {
301
+ root_cause_function[0] = '\0';
302
+
303
if (!backtrace_state) {
304
buffer_strcat(wb, NO_STACK_TRACE_PREFIX "libbacktrace not initialized");
305
return;
@@ -354,6 +356,8 @@ NEVER_INLINE
356
void capture_stack_trace(BUFFER *wb) {
357
// this function is async-signal-safe, if the buffer has enough space to hold the stack trace
358
359
+ root_cause_function[0] = '\0';
360
+
361
unw_cursor_t cursor;
362
unw_context_t context;
363
size_t frames = 0;
@@ -446,6 +450,8 @@ void capture_stack_trace(BUFFER *wb) {
450
char **messages;
451
int size, i;
452
453
+ root_cause_function[0] = '\0';
454
+
455
size = backtrace(array, _countof(array));
456
messages = backtrace_symbols(array, size);
457
@@ -518,6 +524,8 @@ bool capture_stack_trace_is_async_signal_safe(void) {
524
525
NEVER_INLINE
526
void capture_stack_trace(BUFFER *wb) {
527
+ root_cause_function[0] = '\0';
528
+
529
buffer_strcat(wb, NO_STACK_TRACE_PREFIX "no back-end available");
530
531
// probably we can have something like this?
@@ -545,13 +553,8 @@ bool stack_trace_formatter(BUFFER *wb, void *data __maybe_unused) {
553
554
in_stack_trace = true;
555
548
- root_cause_function[0] = '\0';
549
-
556
capture_stack_trace(wb);
557
552
- if(!root_cause_function[0])
553
- strncpyz(root_cause_function, "unknown_root_cause_function", sizeof(root_cause_function) - 1);
554
-
558
in_stack_trace = false; // Ensure the flag is reset
559
return true;
560
}
src/libnetdata/worker_utilization/worker_utilization.c
+1
@@ -241,6 +241,7 @@ static void worker_is_idle_with_time(usec_t now) {
241
ALWAYS_INLINE void worker_is_idle(void) {
242
if(likely(!worker || worker->last_action != WORKER_BUSY)) return;
243
244
+ last_job_id = WORKER_UTILIZATION_MAX_JOB_TYPES;
245
worker_is_idle_with_time(worker_now_monotonic_usec());
246
}
247