unix: fix SIGCHLD race in process.c
Start the SIGCHLD signal watcher before calling fork(). There was a very subtle
race where a child process could quit (and generate a SIGCHILD) before the
signal handler was installed.
To reproduce, call uv_spawn() repeatedly with the below x86_64 program:
// compile with `gcc -O2 -nostdlib`
void _start(void)
{
// syscall(SYS_exit, 0)
__asm__ __volatile__ (
"xorq %rdi, %rdi;"
"xorq %rax, %rax;"
"mov $0x3c, %al;"
"syscall;"
);
for (;;);
}
This commit is contained in:
parent
9d7e300364
commit
758a76922b
@ -400,6 +400,8 @@ int uv_spawn(uv_loop_t* loop,
|
||||
if (uv__make_pipe(signal_pipe, 0))
|
||||
goto error;
|
||||
|
||||
uv_signal_start(&loop->child_watcher, uv__chld, SIGCHLD);
|
||||
|
||||
pid = fork();
|
||||
|
||||
if (pid == -1) {
|
||||
@ -440,7 +442,6 @@ int uv_spawn(uv_loop_t* loop,
|
||||
|
||||
q = uv__process_queue(loop, pid);
|
||||
ngx_queue_insert_tail(q, &process->queue);
|
||||
uv_signal_start(&loop->child_watcher, uv__chld, SIGCHLD);
|
||||
|
||||
process->pid = pid;
|
||||
process->exit_cb = options.exit_cb;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user