corelight / zeekjs

ZeekJS - Experimental JavaScript support for Zeek.
BSD 3-Clause "New" or "Revised" License
9 stars 4 forks source link

signal handling: Not working and triggering 100% cpu when no timers are active #11

Open awelzel opened 2 years ago

awelzel commented 2 years ago

Running zeek with the following script and sending SIGUSR1, once the timer has expired, the zeek process spins at 100% CPU usage and the signal handler is not invoked anymore.

process.on('SIGUSR1', () => {
  console.log('Got SIGUSR1');
})

setTimeout(() => {
  console.log("timer");
}, 10000);
console.log("Ready");
$ zeek -B main-loop ./examples/signal.js exit_only_after_terminate=T
[ DEBUG ] Init: Node initialized. Compiled with v16.13.1
[ DEBUG ] Init: V8 initialized. Version 9.4.146.24-node.14
Ready
Got SIGUSR1
Got SIGUSR1
Got SIGUSR1
Got SIGUSR1
Got SIGUSR1
Got SIGUSR1
Got SIGUSR1
Got SIGUSR1
Got SIGUSR1
Got SIGUSR1
Got SIGUSR1
timer$ zeek ./examples/signal.js exit_only_after_terminate=T
[ DEBUG ] Init: Node initialized. Compiled with v16.13.1
[ DEBUG ] Init: V8 initialized. Version 9.4.146.24-node.14
Ready
Got SIGUSR1
Got SIGUSR1
Got SIGUSR1
Got SIGUSR1
Got SIGUSR1
Got SIGUSR1
Got SIGUSR1
Got SIGUSR1
Got SIGUSR1
Got SIGUSR1
Got SIGUSR1
timer
Got SIGUSR1

Got SIGUSR1

Looking at -B main-loop indicates the uv loop is always ready to be consumed.

Might be triggered by UV_RUN_NOWAIT that we're using currently?

awelzel commented 2 years ago

Hmm, nope. It's just that when the timer expires, the uv_loop isn't considered alive anymore and uv_run() doesn't actually process the signal handles.

Running a HTTP server or scheduling a timer again and again band-aids this.

This was initially observed when resizing the terminal which sends SIGWINCH and zeek would start spinning at 100% CPU.

awelzel commented 2 years ago

We could maybe manually uv_ref() signal handles when exit_only_after_terminate=T (or just always) to avoid this scenario.