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

时间:2011-09-30 07:59:19

标签: process 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→...,不停止并提示我,并停在收到信号的第一个孩子N上。

1 个答案:

答案 0 :(得分:3)

如果您要调试的信号是SIGSEGV(或导致程序核心转储的其他信号之一),最简单的解决方案可能是让子转储核心,并发布 - 调试。

否则,你可能想捕捉信号,沿着child 23435 caught signal 2; execute gdb /proc/23435 23435的行打印一条消息,然后用例如暂停孩子。

while(1) sleep(1);