Here's what happens in the parent:
- Fork a child.
- Send SIGUSR1 to the child.
- Wait for a signal.
Here's what happens in the child:
- Wait for a signal.
- Print
Child
.
- Call
kill(0, SIGUSR1)
(0 being the value of pid
in the child). Calling kill
with a process ID of 0 sends the signal to every process in the process group of the process that calls kill
.
- Wait for a signal.
There are several possible behaviors for your program, depending on the order in which the parent and the child system calls are executed. Depending on the exact version of your operating system, on the fine-tuning of various kernel parameters, on how loaded your system is, and on random chance, you may or may not observe different behavior if you run the program several times or under a debugger.
If the parent starts faster than the child, you may see this:
- Parent sends SIGUSR1 to the child.
- Child receives SIGUSR1 and prints
Catched
.
- Child calls
pause
.
- Parent calls
pause
.
With this execution order, both the parent and the child end up waiting forever (it's a deadlock).
If the child starts faster than the parent, you may see this:
- Child calls
pause
.
- Parent sends SIGUSR1 to the child.
- Parent calls
pause
.
- Child is unblocked and prints
Catched
.
- Child prints
Child
.
- Child sends SIGUSR1 to the process group.
- Child prints
Catched
.
- Child calls
pause
.
- Parent is unblocked and prints
Catched
.
- Parent exits.
I don't think there's a way for the child to exit: it calls pause
twice, and while it can receive up to two signals, one of these is sent from itself (the one from kill(0,SIGUSR1)
) and that one is delivered synchronously, not during the execution of pause
.
This program is probably not what you meant to write, but since you don't describe the expected behavior, it's impossible to tell what you did mean to write. I do note that you do not follow the usual structure of a program that forks:
pid = fork();
if (pid < 0) {
/*error handling*/
} else if (pid == 0) {
/*child code*/
exit(...); /*Usually, what follows the if is specific to the parent.*/
}
Best Answer
The child process inherits signal handlers from the parent, but not the pending signal.
After forking try installing the signal handler for
SIGTRAP
at a place in code where the child process executes after forking. If you don't handleSIGTRAP
, the default action is that the child is terminated.If you want to debug the child process, you must use
follow-fork-mode
. You must set the mode usingHowever, now only the child can be debugged, and the parent runs unchecked.
There is an alternative way of debugging the child process.
After
fork()
is executed, put asleep()
call in the code where the child executes, get the PID of the child using theps
utility, then attach the PID.Now, you can debug the child process, like any other process.
After debugging, you can detach the PID using