status file 22b (#19957)
* show the pointers when pgc contains a different address * anonymize stack traces when generating hashes * parse fault_address * keep stack traces filenames after /src/
Costa Tsaousis committed
Mar 24, 2025 at 22:43 UTC
db6ce59b33a1487078b5cf250ad8385ce1467c8e
3 files changed
+39
-37
src/daemon/daemon-status-file.c
+17
-5
@@ -90,6 +90,15 @@ static void set_stack_trace_message_if_empty(DAEMON_STATUS_FILE *ds, const char
90
// --------------------------------------------------------------------------------------------------------------------
91
// json generation
92
93
+static void stack_trace_anonymize(char *s) {
94
+ char *p = s;
95
+ while (*p && (p = strstr(p, "0x"))) {
96
+ p[1] = '0';
97
+ p += 2;
98
+ while(isxdigit((uint8_t)*p)) *p++ = '0';
99
+ }
100
+}
101
+
102
static uint64_t daemon_status_file_hash(DAEMON_STATUS_FILE *ds, const char *msg, const char *cause) {
103
// IMPORTANT: NO LOCKS OR ALLOCATIONS HERE, THIS FUNCTION IS CALLED FROM SIGNAL HANDLERS
104
// THIS FUNCTION MUST USE ONLY ASYNC-SIGNAL-SAFE OPERATIONS
@@ -147,6 +156,8 @@ static uint64_t daemon_status_file_hash(DAEMON_STATUS_FILE *ds, const char *msg,
156
if(cause)
157
strncpyz(to_hash.cause, cause, sizeof(to_hash.cause) - 1);
158
159
+ stack_trace_anonymize(to_hash.stack_trace);
160
+
161
uint64_t hash = fnv1a_hash_bin64(&to_hash, sizeof(to_hash));
162
163
dsf_release(*ds);
@@ -407,10 +418,6 @@ static bool daemon_status_file_from_json(json_object *jobj, void *data, BUFFER *
418
if(version >= 18) {
419
JSONC_PARSE_INT64_OR_ERROR_AND_RETURN(jobj, path, "reliability", ds->reliability, error, required_v18);
420
JSONC_PARSE_TXT2CHAR_OR_ERROR_AND_RETURN(jobj, path, "stack_traces", ds->stack_traces, error, required_v18);
410
-
411
- char buf[UINT64_HEX_MAX_LENGTH];
412
- JSONC_PARSE_TXT2CHAR_OR_ERROR_AND_RETURN(jobj, path, "fault_address", buf, error, required_v18);
413
- ds->fatal.fault_address = str2ull_encoded(buf);
421
}
422
});
423
@@ -484,8 +491,13 @@ static bool daemon_status_file_from_json(json_object *jobj, void *data, BUFFER *
491
if(version >= 17)
492
JSONC_PARSE_TXT2ENUM_OR_ERROR_AND_RETURN(jobj, path, "sentry", SIGNAL_CODE_2id_h, ds->fatal.sentry, error, required_v17);
493
487
- if(version >= 18)
494
+ if(version >= 18) {
495
JSONC_PARSE_UINT64_OR_ERROR_AND_RETURN(jobj, path, "thread_id", ds->fatal.thread_id, error, required_v18);
496
+
497
+ char buf[UINT64_HEX_MAX_LENGTH];
498
+ JSONC_PARSE_TXT2CHAR_OR_ERROR_AND_RETURN(jobj, path, "fault_address", buf, error, required_v18);
499
+ ds->fatal.fault_address = str2ull_encoded(buf);
500
+ }
501
});
502
503
// Parse the last posted object
src/database/engine/cache.c
+4
-2
@@ -1018,8 +1018,10 @@ static void remove_this_page_from_index_unsafe(PGC *cache, PGC_PAGE *page, size_
1018
1019
PGC_PAGE *found_page = *page_ptr;
1020
if(unlikely(found_page != page))
1021
- fatal("DBENGINE CACHE: page with start time '%ld' of metric '%lu' in section '%lu' should exist, but the index returned a different address.",
1022
- page->start_time_s, page->metric_id, page->section);
1021
+ fatal("DBENGINE CACHE: page with start time '%ld' of metric '%lu' in section '%lu' should exist, "
1022
+ "but the index returned a different address (expected %p, got %p).",
1023
+ page->start_time_s, page->metric_id, page->section,
1024
+ page, found_page);
1025
1026
JudyAllocThreadPulseReset();
1027
src/libnetdata/log/nd_log-stacktrace.c
+18
-30
@@ -22,7 +22,7 @@ typedef struct {
22
} backtrace_data_t;
23
24
// Common function to format and add a stack frame to the buffer
25
-static void add_stack_frame(backtrace_data_t *bt_data, const char *function,
25
+static void add_stack_frame(backtrace_data_t *bt_data, uintptr_t pc, const char *function,
26
const char *filename, int lineno) {
27
BUFFER *wb = bt_data->wb;
28
@@ -45,16 +45,23 @@ static void add_stack_frame(backtrace_data_t *bt_data, const char *function,
45
else
46
buffer_strcat(wb, "<unknown>");
47
48
+ if(pc) {
49
+ buffer_strcat(wb, " [");
50
+ buffer_print_uint64_hex(wb, pc);
51
+ buffer_putc(wb, ']');
52
+ }
53
+
54
if (filename && *filename) {
55
buffer_strcat(wb, " (");
56
51
- // Strip path from filename - find the last slash
52
- const char *base_filename = filename;
53
- const char *last_slash = strrchr(filename, '/');
54
- if (last_slash)
55
- base_filename = last_slash + 1;
57
+ const char *f = strstr(filename, "/src/");
58
+ if (f) {
59
+ const char *f2 = strstr(f + 1, "/src/");
60
+ if(f2) f = f2;
61
+ }
62
+ if(!f) f = filename;
63
57
- buffer_strcat(wb, base_filename);
64
+ buffer_strcat(wb, f);
65
66
if (lineno > 0) {
67
buffer_strcat(wb, ":");
@@ -93,18 +100,18 @@ static void bt_error_handler(void *data, const char *msg, int errnum) {
100
len = strcatz(error_buf, len, sizeof(error_buf), strerror(errnum));
101
}
102
96
- add_stack_frame(bt_data, function, error_buf, 0);
103
+ add_stack_frame(bt_data, 0, function, error_buf, 0);
104
}
105
106
// Full callback for libbacktrace
100
-static int bt_full_handler(void *data, uintptr_t pc __maybe_unused,
107
+static int bt_full_handler(void *data, uintptr_t pc,
108
const char *filename, int lineno,
109
const char *function) {
110
backtrace_data_t *bt_data = (backtrace_data_t *)data;
111
if (!bt_data)
112
return 0;
113
107
- add_stack_frame(bt_data, function, filename, lineno);
114
+ add_stack_frame(bt_data, pc, function, filename, lineno);
115
116
return 0; // Continue backtrace
117
}
@@ -297,29 +304,10 @@ void capture_stack_trace(BUFFER *wb) {
304
if(added)
305
buffer_putc(wb, '\n');
306
300
-#if defined(OS_MACOS)
301
- // remove the address part
302
- char *p = strstr(messages[i], "0x");
303
- char *e = p ? strchr(p, ' ') : NULL;
304
- if (e) {
305
- e++;
306
- buffer_putc(wb, '#');
307
- buffer_print_uint64(wb, added);
308
- buffer_putc(wb, ' ');
309
- buffer_strcat(wb, e);
310
- }
311
- else
312
- buffer_strcat(wb, messages[i]);
313
-#else
307
buffer_putc(wb, '#');
308
buffer_print_uint64(wb, i);
309
buffer_putc(wb, ' ');
317
-
318
- // remove the address part
319
- char *p = strstr(messages[i], " [");
320
- size_t len = p ? (size_t)(p - messages[i]) : strlen(messages[i]);
321
- buffer_fast_strcat(wb, messages[i], len);
322
-#endif
310
+ buffer_strcat(wb, messages[i]);
311
added++;
312
}
313
}