Linux - 使用gdb调试多进程程序

3/8/2017来源:ASP.NET技巧人气:1752

gdb是linux下一款调试器,常用来调试c/c++代码。对于多进程的程序,gdb是如何进行调试的呢?我们接下来一起学习:

方法一:attach pid 利用该命令attach到子进程然后进行调试。为方便调试,可以sleep,这样有充分的时间进行调试。 方法二:gdb wrapper 专用于fork+exec模式,不用添加额外代码,但需要X环境支持(xterm/VNC)。 方法三:follow-fork-mode 在默认设置下,gdb调试多进程程序是只进入主(父)进程调试的,进入子进程则需要设置: 1. set follow-fork-mode[parent | child] parent:fork之后继续调试父进程,子进程不受影响 child:fork之后调试子进程,父进程不受影响 2. set detach-on-fork [on|off] detach-on-fork参数表明gdb在fork之后是否断开(detach)某个进程的调试,或者交给gdb控制。 on:断开调试follow-fork-mode调试的指定进程 off:gdb将控制父进程和子进程。follow-fork-mode指定的进程将被调试,另一个进程置于暂停(suspended)状态。 3. 其他命令: 查看当前调试的fork进程的模式: show follow-fork-mode 查看detach-on-fork模式:show detach-on-fork - 查询正在调试的进程:info inferiors gdb会为每个进程分配唯一的num,带*的即表示正在被调试的进程 - 切换调试的进程: inferior num(num为进程编号) - 复制n个编号是infno的inferior结构:clone-inferior [-copies n] [infno] 如果不指定n的话,就只复制一个inferior;如果不指定infno,则就复制正在调试的inferior。 gdb将每一个被调试进程的执行状态记录在一个名为inferior的结构中。一般情况下一个inferior对应一个进程,每个不同的inferior有不同的地址空间。inferior有时候会在进程没有启动的时候就存在。 - 断开(detach)掉编号是infno的inferior:detach inferior infno 这个inferior还存在,可以再次用run命令执行它。 - kill掉infno号inferior:kill inferior infno 这个inferior仍然存在,可以再次用run等命令执行它。 - 删除一个infno号的inferior:remove-inferior infno 删除前需要先kill或者detach这个inferior,因为当一个inferior正在运行时不能被删除. - set schedule-multiple [on|off] off:只有当前inferior会执行。 on:全部是执行状态的inferior都会执行。 show schedule-multiple,查看schedule-multiple的状态。 - set follow-exec-mode [new|same] same:当发生exec的时候,在执行exec的inferior上控制子进程。 new:新建一个inferior给执行起来的子进程。而父进程的inferior仍然保留,当前保留的inferior的程序状态是没有执行。 - 查看follow-exec-mode设置的模式:show follow-exec-mode - 打开和关闭inferior状态的提示信息set PRint inferior-events [on|off] - 查看print inferior-events设置的状态:show print inferior-events - 显示当前gdb管理的地址空间的数目maint info program-spaces

以下述代码为例进行简单调试进行调试:

#include<stdio.h> #include<unistd.h> #include<stdlib.h> void procA() { int i=0; int sum=0; for(; i<5; i++) { sum += i; } printf("procA data is %d\n",sum); } void procB() { printf("this is procB\n"); } int main() { pid_t id; id = fork(); if(id < 0) { perror("fork"); return -1; } else if(id > 0) { //father process sleep(1); procA(); } else { //child process procB(); } return 0; }

这里写图片描述