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



我正在调试一个程序,该程序重复使用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);

相关内容

最新更新