disable UNW_LOCAL_ONLY on static builds (#19858)
* disable UNW_LOCAL_ONLY on static builds * disable stack traces with logs; get stack traces on deadly conditions only after saving status file * signal handler safety only when UNW_LOCAL_ONLY is set * removed warning
Costa Tsaousis committed
Mar 13, 2025 at 20:51 UTC
b942b581a56780658819a4c8ee25b7939c7db795
4 files changed
+32
-9
packaging/cmake/config.cmake.h.in
+1
@@ -13,6 +13,7 @@
13
#cmakedefine OS_LINUX
14
#cmakedefine OS_MACOS
15
#cmakedefine OS_WINDOWS
16
+#cmakedefine STATIC_BUILD
17
18
// required compilation options
19
src/daemon/daemon-status-file.c
+21
-8
@@ -1115,6 +1115,22 @@ void daemon_status_file_check_crash(void) {
1115
}
1116
}
1117
1118
+static void daemon_status_file_save_again_if_we_can_get_stack_trace(void) {
1119
+ if(!session_status.fatal.stack_trace[0]) {
1120
+ buffer_flush(static_save_buffer);
1121
+ capture_stack_trace(static_save_buffer);
1122
+
1123
+ if(buffer_strlen(static_save_buffer) > 0) {
1124
+ strncpyz(
1125
+ session_status.fatal.stack_trace,
1126
+ buffer_tostring(static_save_buffer),
1127
+ sizeof(session_status.fatal.stack_trace) - 1);
1128
+
1129
+ daemon_status_file_save(static_save_buffer, &session_status, false);
1130
+ }
1131
+ }
1132
+}
1133
+
1134
// --------------------------------------------------------------------------------------------------------------------
1135
// ng_log() hook for receiving fatal message information
1136
@@ -1156,6 +1172,8 @@ void daemon_status_file_register_fatal(const char *filename, const char *functio
1172
freez((void *)message);
1173
freez((void *)errno_str);
1174
freez((void *)stack_trace);
1175
+
1176
+ daemon_status_file_save_again_if_we_can_get_stack_trace();
1177
}
1178
1179
// --------------------------------------------------------------------------------------------------------------------
@@ -1181,6 +1199,7 @@ static void daemon_status_file_out_of_memory(void) {
1199
dsf_release(session_status);
1200
1201
daemon_status_file_save(static_save_buffer, &session_status, false);
1202
+ daemon_status_file_save_again_if_we_can_get_stack_trace();
1203
}
1204
1205
void daemon_status_file_deadly_signal_received(EXIT_REASON reason) {
@@ -1202,14 +1221,8 @@ void daemon_status_file_deadly_signal_received(EXIT_REASON reason) {
1221
// save what we know already
1222
daemon_status_file_save(static_save_buffer, &session_status, false);
1223
1205
- bool can_safely_capture_stack_trace = reason != EXIT_REASON_SIGABRT || capture_stack_trace_is_async_signal_safe();
1206
-
1207
- if(can_safely_capture_stack_trace && !session_status.fatal.stack_trace[0]) {
1208
- buffer_flush(static_save_buffer);
1209
- capture_stack_trace(static_save_buffer);
1210
- strncpyz(session_status.fatal.stack_trace, buffer_tostring(static_save_buffer), sizeof(session_status.fatal.stack_trace) - 1);
1211
- daemon_status_file_save(static_save_buffer, &session_status, false);
1212
- }
1224
+ if(reason != EXIT_REASON_SIGABRT || capture_stack_trace_is_async_signal_safe())
1225
+ daemon_status_file_save_again_if_we_can_get_stack_trace();
1226
}
1227
1228
bool daemon_status_file_has_last_crashed(void) {
src/libnetdata/log/nd_log-stacktrace.c
+6
@@ -7,7 +7,9 @@ bool nd_log_forked = false;
7
#define NO_STACK_TRACE_PREFIX "stack trace not available: "
8
9
#if defined(HAVE_LIBUNWIND)
10
+#if !defined(STATIC_BUILD)
11
#define UNW_LOCAL_ONLY
12
+#endif
13
#include <libunwind.h>
14
15
void capture_stack_trace_init(void) {
@@ -19,7 +21,11 @@ void capture_stack_trace_flush(void) {
21
}
22
23
bool capture_stack_trace_is_async_signal_safe(void) {
24
+#if defined(STATIC_BUILD)
25
+ return false;
26
+#else
27
return true;
28
+#endif
29
}
30
31
void capture_stack_trace(BUFFER *wb) {
src/libnetdata/log/nd_log.c
+4
-1
@@ -268,8 +268,11 @@ static void nd_logger(const char *file, const char *function, const unsigned lon
268
269
// set the common fields that are automatically set by the logging subsystem
270
271
- if(likely(!thread_log_fields[NDF_STACK_TRACE].entry.set) && priority <= NDLP_WARNING)
271
+#if 0
272
+ // getting stack traces is crashing on some architectures, so we get them only for daemon status file
273
+ if(likely(!thread_log_fields[NDF_STACK_TRACE].entry.set) && priority <= NDLP_ALERT) // only on fatal errors
274
thread_log_fields[NDF_STACK_TRACE].entry = ND_LOG_FIELD_CB(NDF_STACK_TRACE, stack_trace_formatter, NULL);
275
+#endif
276
277
if(likely(!thread_log_fields[NDF_INVOCATION_ID].entry.set))
278
thread_log_fields[NDF_INVOCATION_ID].entry = ND_LOG_FIELD_UUID(NDF_INVOCATION_ID, &nd_log.invocation_id);