Just as the title says, one process forks waits for its child to receive a SIGSTOP (self sent by the child) but it does not wake up after as if it didn't receive any SIGCHLD (but it actually did, tested with strace).
Anyone any ideas?
int main() {
if (fork()) {
wait(NULL);
write(1, "Bye\n", 4);
} else {
kill(getpid(), SIGSTOP);
write(1, "Hello\n", 6);
}
return 0;
}
They both hang, whereas only the child should.
Suspends the calling process until any one of its child processes ends. More precisely, wait() suspends the calling process until the system obtains status information on the ended child. If the system already has status information on a completed child process when wait() is called, wait() returns immediately.
Difference between wait and waitpid():Wait() waits for any child process but waitpid() waits for a specific child equal to pid. By default waitpid() waits for the only terminated child where as wait() waits for both terminated or a signaled child.
Returned value If successful, waitpid() returns a value of the process (usually a child) whose status information has been obtained. If WNOHANG was given, and if there is at least one process (usually a child) whose status information is not available, waitpid() returns 0.
wait(NULL) will block the parent process until any of its children has finished. If the child terminates before the parent process reaches wait(NULL) then the child process turns to a zombie process until its parent waits on it and its released from memory.
The specification for wait
says that it reports only children that have exited, not children that have stopped. You should use
waitpid(-1, 0, WUNTRACED);
instead.
The flag name WUNTRACED
is a little cryptic - why isn't it WSTOPPED
? This is a point where the standardized wait*
API brushes up against the not-standardized ptrace
API. Compare POSIX's definition of WUNTRACED
…
- WUNTRACED
- The status of any child processes specified by pid that are stopped, and whose status has not yet been reported since they stopped, shall also be reported to the requesting process.
… with its documentation in the Linux manpage …
- WUNTRACED
- also return if a child has stopped (but not traced via ptrace(2)). Status for traced children which have stopped is provided even if this option is not specified.
So basically the default behavior of wait*
has a special case embedded in it for the convenience of people writing debuggers (people writing debuggers will take every convenience they can get) and that special case has been around for so long that it affected the names chosen for waitpid
's flags. (I don't know one way or the other, but I would not be surprised to learn that ptrace
stops are older than job control stops.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With