3

I'm using fork to create a process on a Mac platform, and wait for the child process to finish in the parent process. But the waitpid return -1 and errno is 4 (EINTR).

The example code, which can reproduce this problem, is as follows:

#include <iostream>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
int main(int argc, const char *argv[])
{
    pid_t pid = ::fork();
    if (pid == 0)
    {
        return 0;
    }

    int s = 0;
    if (::waitpid(pid, &s, 0) == -1)
    {
        printf("The errno is :%d\n", errno); // <<<The errno is 4(EINTR) in my machine.
        assert(false);  // <<<<This will be hit if run in debugger.
    }
    return 0;
}

When I run this code in GDB or LLDB the assert will always be hit. If not run in debugger it will not return -1.

I think there is something I don't understand about how debugger or fork/waitpid works. So can anyone explain why this happen?

ZijingWu
  • 3,350
  • 3
  • 25
  • 40

1 Answers1

3

The debugger is sending a signal to the process. As WhozCraig said, these should be handled by detecting EINTR and calling waitpid again in a loop. Be aware that when running the child process in the debugger, the debugger likely changes the parent process to the debugger's PID, so waitpid on the child PID will fail thinking the child process has exited, even though it has not. When the debugger exits, it restores the PPID of the child to the original parent's PID.

bu11d0zer
  • 433
  • 4
  • 13