Restore SIGCHLD signal handler after being replaced by libuv (#9107)
Markos Fountoulakis committed
May 20, 2020 at 17:25 UTC
ae0d6007f1b2caf32202c95bd47a3e5ccfe80fa0
3 files changed
+24
daemon/main.c
+8
@@ -1384,6 +1384,14 @@ int main(int argc, char **argv) {
1384
1385
// fork the spawn server
1386
spawn_init();
1387
+ /*
1388
+ * Libuv uv_spawn() uses SIGCHLD internally:
1389
+ * https://github.com/libuv/libuv/blob/cc51217a317e96510fbb284721d5e6bc2af31e33/src/unix/process.c#L485
1390
+ * and inadvertently replaces the netdata signal handler which was setup during initialization.
1391
+ * Thusly, we must explicitly restore the signal handler for SIGCHLD.
1392
+ * Warning: extreme care is needed when mixing and matching POSIX and libuv.
1393
+ */
1394
+ signals_restore_SIGCHLD();
1395
1396
// ------------------------------------------------------------------------
1397
// initialize rrd, registry, health, rrdpush, etc.
daemon/signals.c
+15
@@ -111,6 +111,21 @@ void signals_init(void) {
111
}
112
}
113
114
+void signals_restore_SIGCHLD(void)
115
+{
116
+ struct sigaction sa;
117
+
118
+ if (reaper_enabled == 0)
119
+ return;
120
+
121
+ sa.sa_flags = 0;
122
+ sigfillset(&sa.sa_mask);
123
+ sa.sa_handler = signal_handler;
124
+
125
+ if(sigaction(SIGCHLD, &sa, NULL) == -1)
126
+ error("SIGNAL: Failed to change signal handler for: SIGCHLD");
127
+}
128
+
129
void signals_reset(void) {
130
struct sigaction sa;
131
sigemptyset(&sa.sa_mask);
daemon/signals.h
+1
@@ -6,6 +6,7 @@
6
extern void signals_init(void);
7
extern void signals_block(void);
8
extern void signals_unblock(void);
9
+extern void signals_restore_SIGCHLD(void);
10
extern void signals_reset(void);
11
extern void signals_handle(void) NORETURN;
12