GDB:在多次fork()后调试子进程

7

我正在调试一个程序,它重复使用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执行的内容,例如父进程→子进程1→父进程→子进程2→...,而不会停止并提示我,并在收到信号的第一个childN处停止。

你可以尝试使用GDB宏脚本来完成其中的一些操作。或者,你也可以修改代码,使得第1000个(或其他)子进程会产生核心转储文件,然后对该文件进行调试。 - P.T.
1个回答

4
如果您想调试的信号是SIGSEGV(或导致程序核心转储的其他信号之一),最简单的解决方案可能是让子进程转储核心,并进行事后调试。
否则,您可能需要捕获信号,打印类似于child 23435 caught signal 2; execute gdb /proc/23435 23435的消息,然后使用例如挂起子进程。
while(1) sleep(1);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接