Skip to content
This repository has been archived by the owner on May 4, 2018. It is now read-only.

Commit

Permalink
unix: fix SIGCHLD race in process.c
Browse files Browse the repository at this point in the history
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 (;;);
    }
  • Loading branch information
bnoordhuis committed Aug 13, 2012
1 parent 9d7e300 commit 758a769
Showing 1 changed file with 2 additions and 1 deletion.
3 changes: 2 additions & 1 deletion src/unix/process.c
Expand Up @@ -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) {
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit 758a769

Please sign in to comment.