@cryptotaxi247 / netdata-1 / commits / e30c3a52d

add handling for sigabrt in the status file (#19769)

* add handling for sigabrt * remove empty statement warning

Costa Tsaousis committed Mar 4, 2025 at 19:04 UTC e30c3a52d140d7c22ddf32bb49b5431ea7ace05a
5 files changed +30 -24
src/daemon/daemon-status-file.c
+2 -1
@@ -1116,7 +1116,8 @@ void daemon_status_file_deadly_signal_received(EXIT_REASON reason) {
1116 // save what we know already
1117 daemon_status_file_save(static_save_buffer, &session_status, false);
1118
1119 - if(!session_status.fatal.stack_trace[0]) {
1119 + // we cannot get a stack trace on SIGABRT - it may deadlock forever
1120 + if(reason != EXIT_REASON_SIGABRT && !session_status.fatal.stack_trace[0]) {
1121 buffer_flush(static_save_buffer);
1122 capture_stack_trace(static_save_buffer);
1123 strncpyz(session_status.fatal.stack_trace, buffer_tostring(static_save_buffer), sizeof(session_status.fatal.stack_trace) - 1);
src/daemon/main.c
+2 -2
@@ -185,7 +185,7 @@ int help(int exitcode) {
185 */
186
187 #define delta_startup_time(msg) \
188 - { \
188 + do { \
189 usec_t now_ut = now_monotonic_usec(); \
190 if(prev_msg) \
191 netdata_log_info("NETDATA STARTUP: in %7llu ms, %s - next: %s", (now_ut - last_ut) / USEC_PER_MS, prev_msg, msg); \
@@ -194,7 +194,7 @@ int help(int exitcode) {
194 last_ut = now_ut; \
195 prev_msg = msg; \
196 daemon_status_file_startup_step("startup(" msg ")"); \
197 - }
197 + } while(0)
198
199 int buffer_unittest(void);
200 int pgc_unittest(void);
src/daemon/signals.c
+11 -8
@@ -9,7 +9,7 @@ typedef enum signal_action {
9 NETDATA_SIGNAL_EXIT_CLEANLY,
10 NETDATA_SIGNAL_REOPEN_LOGS,
11 NETDATA_SIGNAL_RELOAD_HEALTH,
12 - NETDATA_SIGNAL_FATAL,
12 + NETDATA_SIGNAL_DEADLY,
13 } SIGNAL_ACTION;
14
15 static struct {
@@ -25,10 +25,11 @@ static struct {
25 { SIGTERM, "SIGTERM", 0, NETDATA_SIGNAL_EXIT_CLEANLY, EXIT_REASON_SIGTERM },
26 { SIGHUP, "SIGHUP", 0, NETDATA_SIGNAL_REOPEN_LOGS, EXIT_REASON_NONE },
27 { SIGUSR2, "SIGUSR2", 0, NETDATA_SIGNAL_RELOAD_HEALTH, EXIT_REASON_NONE },
28 - { SIGBUS, "SIGBUS", 0, NETDATA_SIGNAL_FATAL, EXIT_REASON_SIGBUS },
29 - { SIGSEGV, "SIGSEGV", 0, NETDATA_SIGNAL_FATAL, EXIT_REASON_SIGSEGV },
30 - { SIGFPE, "SIGFPE", 0, NETDATA_SIGNAL_FATAL, EXIT_REASON_SIGFPE },
31 - { SIGILL, "SIGILL", 0, NETDATA_SIGNAL_FATAL, EXIT_REASON_SIGILL },
28 + { SIGBUS, "SIGBUS", 0, NETDATA_SIGNAL_DEADLY, EXIT_REASON_SIGBUS },
29 + { SIGSEGV, "SIGSEGV", 0, NETDATA_SIGNAL_DEADLY, EXIT_REASON_SIGSEGV },
30 + { SIGFPE, "SIGFPE", 0, NETDATA_SIGNAL_DEADLY, EXIT_REASON_SIGFPE },
31 + { SIGILL, "SIGILL", 0, NETDATA_SIGNAL_DEADLY, EXIT_REASON_SIGILL },
32 + { SIGABRT, "SIGABRT", 0, NETDATA_SIGNAL_DEADLY, EXIT_REASON_SIGABRT },
33
34 // terminator
35 { 0, "NONE", 0, NETDATA_SIGNAL_END_OF_LIST, 0 }
@@ -46,7 +47,7 @@ static void signal_handler(int signo) {
47 if(unlikely(signals_waiting[i].signo == signo)) {
48 signals_waiting[i].count++;
49
49 - if(signals_waiting[i].action == NETDATA_SIGNAL_FATAL) {
50 + if(signals_waiting[i].action == NETDATA_SIGNAL_DEADLY) {
51 // Update the status file
52 daemon_status_file_deadly_signal_received(signals_waiting[i].reason);
53
@@ -61,6 +62,7 @@ static void signal_handler(int signo) {
62 }
63
64 // Reset the signal's disposition to the default handler.
65 +
66 struct sigaction sa;
67 sa.sa_handler = SIG_DFL;
68 sigemptyset(&sa.sa_mask);
@@ -91,6 +93,7 @@ static void posix_signals_default_mask(void) {
93 sigdelset(&sigset, SIGSEGV);
94 sigdelset(&sigset, SIGFPE);
95 sigdelset(&sigset, SIGILL);
96 + sigdelset(&sigset, SIGABRT);
97
98 if(pthread_sigmask(SIG_BLOCK, &sigset, NULL) != 0)
99 netdata_log_error("SIGNAL: cannot apply the default mask for signals");
@@ -184,10 +187,10 @@ void nd_process_signals(void) {
187 exit(0);
188 break;
189
187 - case NETDATA_SIGNAL_FATAL:
190 + case NETDATA_SIGNAL_DEADLY:
191 nd_log_limits_unlimited();
192 daemon_status_file_deadly_signal_received(signals_waiting[i].reason);
190 - fatal("SIGNAL: Received %s. netdata now exits.", name);
193 + _exit(1);
194 break;
195
196 default:
src/libnetdata/exit/exit_initiated.c
+1
@@ -9,6 +9,7 @@ ENUM_STR_MAP_DEFINE(EXIT_REASON) = {
9 { EXIT_REASON_SIGSEGV, "signal-segmentation-fault"},
10 { EXIT_REASON_SIGFPE, "signal-floating-point-exception"},
11 { EXIT_REASON_SIGILL, "signal-illegal-instruction"},
12 + { EXIT_REASON_SIGABRT, "signal-abort"},
13 { EXIT_REASON_OUT_OF_MEMORY, "out-of-memory"},
14 { EXIT_REASON_ALREADY_RUNNING, "already-running"},
15
src/libnetdata/exit/exit_initiated.h
+14 -13
@@ -14,36 +14,37 @@ typedef enum {
14 EXIT_REASON_SIGSEGV = (1 << 1),
15 EXIT_REASON_SIGFPE = (1 << 2),
16 EXIT_REASON_SIGILL = (1 << 3),
17 - EXIT_REASON_OUT_OF_MEMORY = (1 << 4),
18 - EXIT_REASON_ALREADY_RUNNING = (1 << 5),
17 + EXIT_REASON_SIGABRT = (1 << 4),
18 + EXIT_REASON_OUT_OF_MEMORY = (1 << 5),
19 + EXIT_REASON_ALREADY_RUNNING = (1 << 6),
20
21 // abnormal termination via a fatal message
21 - EXIT_REASON_FATAL = (1 << 6), // a fatal message
22 + EXIT_REASON_FATAL = (1 << 7), // a fatal message
23
24 // normal termination via APIs
24 - EXIT_REASON_API_QUIT = (1 << 7), // developer only
25 - EXIT_REASON_CMD_EXIT = (1 << 8), // netdatacli
25 + EXIT_REASON_API_QUIT = (1 << 8), // developer only
26 + EXIT_REASON_CMD_EXIT = (1 << 9), // netdatacli
27
28 // signals - normal termination
28 - EXIT_REASON_SIGQUIT = (1 << 9), // rare, but graceful
29 - EXIT_REASON_SIGTERM = (1 << 10), // received on Linux, FreeBSD, MacOS
30 - EXIT_REASON_SIGINT = (1 << 11), // received on Windows on normal termination
29 + EXIT_REASON_SIGQUIT = (1 << 10), // rare, but graceful
30 + EXIT_REASON_SIGTERM = (1 << 11), // received on Linux, FreeBSD, MacOS
31 + EXIT_REASON_SIGINT = (1 << 12), // received on Windows on normal termination
32
33 // windows specific, service stop
33 - EXIT_REASON_SERVICE_STOP = (1 << 12),
34 + EXIT_REASON_SERVICE_STOP = (1 << 13),
35
36 // automatically detect when exit_initiated_set() is called
37 // supports Linux, FreeBSD, MacOS, Windows
37 - EXIT_REASON_SYSTEM_SHUTDOWN = (1 << 13),
38 + EXIT_REASON_SYSTEM_SHUTDOWN = (1 << 14),
39
40 // netdata update
40 - EXIT_REASON_UPDATE = (1 << 14),
41 + EXIT_REASON_UPDATE = (1 << 15),
42 } EXIT_REASON;
43
44 #define EXIT_REASON_NORMAL (EXIT_REASON_SIGINT|EXIT_REASON_SIGTERM|EXIT_REASON_SIGQUIT|EXIT_REASON_API_QUIT|EXIT_REASON_CMD_EXIT|EXIT_REASON_SERVICE_STOP|EXIT_REASON_SYSTEM_SHUTDOWN|EXIT_REASON_UPDATE)
44 -#define EXIT_REASON_ABNORMAL (EXIT_REASON_SIGBUS|EXIT_REASON_SIGSEGV|EXIT_REASON_SIGFPE|EXIT_REASON_SIGILL|EXIT_REASON_FATAL|EXIT_REASON_OUT_OF_MEMORY)
45 +#define EXIT_REASON_ABNORMAL (EXIT_REASON_SIGBUS|EXIT_REASON_SIGSEGV|EXIT_REASON_SIGFPE|EXIT_REASON_SIGILL|EXIT_REASON_SIGABRT|EXIT_REASON_FATAL|EXIT_REASON_OUT_OF_MEMORY)
46
46 -#define is_deadly_signal(reason) ((reason) & (EXIT_REASON_SIGBUS|EXIT_REASON_SIGSEGV|EXIT_REASON_SIGFPE|EXIT_REASON_SIGILL))
47 +#define is_deadly_signal(reason) ((reason) & (EXIT_REASON_SIGBUS|EXIT_REASON_SIGSEGV|EXIT_REASON_SIGFPE|EXIT_REASON_SIGILL|EXIT_REASON_SIGABRT))
48 #define is_exit_reason_normal(reason) (((reason) & EXIT_REASON_NORMAL) && !((reason) & EXIT_REASON_ABNORMAL))
49
50 typedef struct web_buffer BUFFER;