GDB调试多进程程序

您所在的位置:网站首页 gdb单线程调试 GDB调试多进程程序

GDB调试多进程程序

2024-07-14 07:03| 来源: 网络整理| 查看: 265

GDB调试多进程程序

GDB调试器不只可以调试多线程程序,还可以调试多进程程序。对于 C 和 C++ 程序而言,多进程的实现往往借助的是头文件中的 fork() 函数或者 vfork() 函数。举个例子:

#include #include int main() { pid_t pid = fork(); if(pid == 0) { printf("this is child,pid = %d\n",getpid()); } else { printf("this is parent,pid = %d\n",getpid()); } return 0; }

可以看到,程序中包含 2 个进程,分别为父进程(又称主进程)和使用 fork() 函数分离出的子进程。事实上在多数 Linux 发行版系统中,GDB 并没有对多进程程序提供友好的调试功能。无论程序中调用了多少次 fork() 函数(或者 vfork() 函数),从父进程中分离出多少个子进程,GDB 默认只调试父进程,而不调试子进程。

GDB attach命令调试进程

首先,无论父进程还是子进程,都可以借助 attach 命令启动 GDB 调试它。attach 命令用于调试正在运行的进程,要知道对于每个运行的进程,操作系统都会为其配备一个独一无二的 ID 号。在得知目标子进程 ID 号的前提下,就可以借助 attach 命令来启动 GDB 对其进行调试。这里还需要解决一个问题,很多场景中子进程的执行时间都是一瞬而逝的,这意味着,我们可能还未查到它的进程 ID 号,该进程就已经执行完了,何谈借助 attach 命令对其调试呢?对于 C、C++ 多进程程序,解决该问题最简单直接的方法是,在目标进程所执行代码的开头位置,添加一段延时执行的代码。例如,将上面程序中if(pid==0)判断语句整体做如下修改:

if(pid == 0) { int num =10; while(num==10){ sleep(10); } printf("this is child,pid = %d\n",getpid()); }

可以看到,通过添加第 3~6 行代码,该进程执行时会直接进入死循环。这样做的好处有 2 个,其一是帮助 attach 命令成功捕捉到要调试的进程;其二是使用 GDB 调试该进程时,进程中真正的代码部分尚未得到执行,使得我们可以从头开始对进程中的代码进行调试。

进程都已经进行死循环了,后续代码还可以进行调试吗?当然可以,以上面示例中给出的死循环,我们只需用 print 命令临时修改 num 变量的值,即可使程序跳出循环,从而执行后续代码。

就以调试修改后的 myfork.c 程序(已将其编译为 myfork.exe 可执行文件)为例:

[root@bogon demo]# gdb myfork.exe -q Reading symbols from ~/demo/myfork.exe...done. (gdb) r Starting program: ~/demo/myfork.exe Detaching after fork from child process 5316.


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3