GDB多进程调试

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

多进程调试命令: 1、默认设置下,在调试多进程程序时GDB只会调试主进程。但是设置follow-fork-mode的话,就可调试多个进程。 set follow-fork-mode parent|child: 进入gdb后默认调试的是parent,要想调试child的话,需要设置set follow-fork-mode child,然后进入调试。当然这种方式只能同时调试一个进程。 show follow-fork-mode:查看当前调试的fork的模式。

2、detach-on-fork on|off: 设置为on的话,只调试父进程或子进程其中一个,需要根据follow-fork-mode决定,这是默认模式。 设置成off的话,父子进程都在gdb的控制之下,其中一个进程正常调试,需要根据follow-fork-mode决定,另一个进程会被设置为暂停状态。 show detach-on-fork:查看detach-on-fork的模式。

扩展:GDB将每一个被调试程序的执行状态记录在一个名为inferior的结构中。一般情况下一个inferior对应一个进程,每个不同的inferior有不同的地址空间。inferior有时候会在进程没有启动的时候就存在。

3、info inferiors:显示GDB调试的所有inferior,GDB会为他们分配ID。其中带有*的进程是正在调试的inferior.

4、inferior num:切换到ID是num的inferior进行调试。

5、add-inferior [-copies n] [-exec executable]: 增加n个inferior并执行程序为executable。如果不指定n只增加一个inferior。如果不指定executable,则执行程序留空,增加后可使用file命令重新指定执行程序。这时候创建的inferior其关联的进程并没启动。

6、clone-inferior [-copies n] [infno]: 复制n个编号是infno的inferior。如果不指定n的话,就只复制一个inferior。如果不指定infno,则就复制正在调试的inferior。

7、 detach inferior infno: detach掉编号是infno的inferior。注意这个inferior还存在,可以再次用run命令执行它。

8、kill inferior infno: kill掉infno号inferior。注意这个inferior仍然存在,可以再次用run等命令执行它。

9、remove-inferior infno: 删除一个infno号的inferior。如果inferior正在运行,则不能删除,所以删除前需要先kill或者detach这个inferior。

10、set schedule-multiple on|off: 设为off:只有当前inferior会执行。 设为on:全部是执行状态的inferior都会执行。 这个选项类似于多线程调试里的set scheduler-locking选项 注意:如果scheduler-locking是指为on,即使schedule-multiple设置为on,也只有当前进程的当前线程会执行。

show schedule-multiple: 查看schedule-multiple的状态。

11、set follow-exec-mode new|same: 设置same:当发生exec的时候,在执行exec的inferior上控制子进程。 设置为new:新建一个inferior给执行起来的子进程。而父进程的inferior仍然保留,当前保留的inferior的程序状态是没有执行。 show follow-exec-mode:查看follow-exec-mode设置的模式。

12、set PRint inferior-events on|off:用来打开和关闭inferior状态的提示信息。 show print inferior-events :查看print inferior-events设置的状态。

13、maint info program-spaces: 用来显示当前GDB一共管理了多少地址空间。

示例:

#include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<sys/types.h> int main() { printf("this is one\n"); pid_t id=fork(); printf("this is tow\n"); if(id==0) { printf("this is child\n:%d ppid:%d\n",getpid(),getppid()); exit(1); } else { sleep(1); printf("this is father:%d\n",getpid()); waitpid(-1,NULL,0); } return 0; }

1、设置调试的模式 这里写图片描述

2、切换调试的进程 这里写图片描述 注意:带有*的进程是当前正在调试的进程