GDB: debugging a child process after many fork()s
I'm debugging a program which repeats the typical procedure of using fork()
where the child process does some delegated task as the parent calls waitpid()
to wait for the child to finish and then continues. For example:
while (!finished) {
pid_t p = fork();
if (p < 0) {
perror("fork");
exit(EXIT_FAILURE);
}
else if (p == 0) {
/* Do something. For example: */
if (/* some (rare) condition */)
raise(SIGSEGV);
exit(EXIT_SUCCESS);
}
else {
int status;
pid_t w = waitpid(p, &status, 0);
if (w < 0) {
perror("waitpid");
exit(EXIT_FAILURE);
}
/* Do something. */
}
}
I'd like to run the program inside GDB and debug a child process that receives a signal, no matter how many other child processes successfully finished and vanished before it.
Of course, I need set follow-fork-mode child
, because otherwise GDB won't look into the child processes. But this alone will detach the parent, lead GDB to the first child, and finish debugging upon its exit.
Therefore, I also need set detach-on-fork off
to prevent the parent from being detached. However, this causes GDB to stop and give me a prompt, with the parent being suspended, when the first child exits. I could use inferior
to choose the parent and issue continue
, but I need to do this for every child. If the 1000th child is the one that receives the signal and that I want to look into, I need to repeat this process 999 times.
So I'm wondering if there is a way to, kind of, do this automatically and let GDB follow what the CPU would be executing, e.g. parent → child1 → parent → child2 → … , without stopping and prompting me, and stop at the first childN that receives a signal.
If the signal you'd like to debug is SIGSEGV
(or one of the other signals that causes the program to core dump), the easiest solution might be to just let the child dump core, and do post-mortem debugging.
Otherwise, you might want to catch the signal, print a message along the lines of child 23435 caught signal 2; execute gdb /proc/23435 23435
and then suspend the child with e.g.
while(1) sleep(1);
精彩评论