📜  标记 gdb 跟随 fork (1)

📅  最后修改于: 2023-12-03 15:40:27.027000             🧑  作者: Mango

标记 gdb 跟随 fork

在调试过程中,我们经常会遇到子进程的创建。默认情况下,GDB并不会跟随子进程的执行,这就导致了我们在调试父进程时无法看到子进程执行过程的问题。为了解决这个问题,我们可以使用GDB的fork跟随功能。

开启fork跟随功能

要使用GDB的fork跟随功能,我们需要在GDB中使用"set follow-fork-mode"命令来设置:

set follow-fork-mode child

这将使GDB在父进程调用fork()创建子进程时,自动切换到子进程上。如果要禁用跟随功能,可以将参数设置为parent。

使用 fork 跟随功能

当我们开启fork跟随功能后,可以使用下面的命令来控制进程执行方式:

  • continue: 让程序继续执行,如果程序进入子进程,则会切换到子进程上。
  • next: 执行下一行代码,如果下一行代码在子进程中,则会切换到子进程上。
示例代码

下面是一个示例代码,我们使用fork创建了一个子进程,然后在子进程中跑了一个死循环。

#include <stdio.h>
#include <unistd.h>

int main(void) {
    pid_t pid = fork();

    if (pid == 0) {
        // 子进程中
        printf("I'm Child\n");
        while (1);
    } else if (pid > 0) {
        // 父进程中
        printf("I'm Parent\n");
        sleep(10);
    }

    return 0;
}

我们可以通过下面的步骤来调试这个程序:

  1. 编译程序,并使用GDB启动程序
    gcc -g -o fork_test fork_test.c
    gdb fork_test
    
  2. 设置fork跟随模式
    set follow-fork-mode child
    
  3. 开始调试
    (gdb) break main
    (gdb) run
    
  4. 执行到fork()函数,程序会在此处停止,并等待输入命令。首先我们可以输入continue命令,让程序继续执行。
    (gdb) continue
    
  5. 程序会被切换到子进程上,此时可以在子进程中执行下面的命令。
    >>> ps
    PID TTY          TIME CMD
    169772 pts/0    00:00:00 fork_test
    169773 pts/0    00:00:00 fork_test <defunct>
    169899 pts/0    00:00:00 ps
    
    >>> quit
    
  6. 程序结束。
总结

使用GDB的fork跟随功能,可以方便地跟踪子进程的执行过程,帮助我们快速定位问题。同时,我们也需要注意fork跟随的开销,避免对调试性能造成影响。