我正在调试一个程序,该程序重复使用fork()
的典型过程,其中子进程执行一些委托任务,因为父进程调用waitpid()
等待子进程完成,然后继续。例如:
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. */
}
}
我想在GDB中运行程序并调试接收信号的子进程,无论有多少其他子进程成功完成并在它之前消失。
当然,我需要set follow-fork-mode child
,因为否则GDB不会查看子进程。但是,这单独将分离父进程,将GDB引导到第一个子进程,并在其退出时完成调试。
因此,我还需要set detach-on-fork off
来防止父节点被分离。但是,当第一个子进程退出时,这会导致GDB停止并给我一个提示,父进程被挂起。我可以使用inferior
来选择父节点并发布continue
,但是我需要为每个子节点这样做。如果第1000个子节点是接收信号的节点,并且我想要查看它,那么我需要重复这个过程999次。
所以我想知道是否有一种方法可以自动做到这一点,并让GDB遵循CPU将执行的内容,例如parent→child1→parent→child2→…,而不停止并提示我,并停止在接收信号的第一个childdn。
如果您想要调试的信号是SIGSEGV
(或导致程序转储内核的其他信号之一),最简单的解决方案可能是让子进程转储内核,并进行事后调试。
否则,您可能想要捕获该信号,沿着child 23435 caught signal 2; execute gdb /proc/23435 23435
行打印一条消息,然后挂起子进程,例如
while(1) sleep(1);