如果一个进程fork了多个进程,这时使用GBD工具对程序进行调试会如何呢?

实际上,GDB 没有对多进程程序调试提供直接支持。例如,使用GDB调试某个进程,如果该进程fork了子进程,GDB会继续调试该进程,子进程会不受干扰地运行下去。

如果你事先在子进程代码里设定了断点,子进程会收到SIGTRAP信号,如果没有对此信号进行捕捉处理,就会按默认的处理方式处理——终止进程。

那么该如何调试子进程呢?有3种方法:


1.follow-fork-mode

在2.5.60版Linux内核及以后,GDB对使用fork/vfork创建子进程的程序提供了follow-fork-mode选项来支持多进程调试:

follow-fork-mode的用法为:

set follow-fork-mode [parent|child]

  parent:调试父进程,子进程不受影响

  child:调试子进程,父进程不受影响

我们需要调试子进程,所以在启动gdb后,输入命令

set  follow-fork-mode  child

并在子进程代码处设置断点。此外还有detach-on-fork参数,指示GDB在fork之后是否断开(detach)某个进程的调试,或者都交由GDB控制:

set  detach-on-fork  [on | off]

  on: 断开调试follow-fork-mode指定的进程。

  off: gdb将控制父进程和子进程。follow-fork-mode指定的进程将被调试,另一个进程置于暂停(suspended)状态。

这两种模式支持需要GDB6.6及以上版本。由于follow-fork-mode的调试必然是从父进程开始的,对于fork多次,以至于出现孙进程或曾孙进程的系统,调试起来并不方便。


2.Attach子进程

GDB有附着(attach)到正在运行的进程的功能,即attach <pid>命令。因此我们可以利用该命令attach到子进程然后进行调试。

首先,要获得进程的ID,终端中使用命令:

ps  -ef | grep  YOUR_PROCESS_NAME

然后进入gdb使用命令

attach  pid

现在可以调试了。但是如果子进程一直在运行,那么attach上之后就不知道运行到哪里去了。一个办法是,在刚刚进入子进程程序段时加入一段睡眠程序,即调用sleep函数,使子进程进入一定时间的睡眠状态,确保在子进程睡眠状态结束之前要attach上子进程,之后在子进程代码段设置断点,然后就可以对子进程进行调试了。

Attach进程方法还是很方便的,它能够应付各种各样复杂的进程系统,比如孙子/曾孙进程,比如守护进程(daemon process),唯一需要的就是加入一小段代码。


3.GDB wrapper

很多时候,父进程 fork 出子进程,子进程会紧接着调用 exec族函数来执行新的代码。对于这种情况,我们也可以使用gdb wrapper 方法。它的优点是不用添加额外代码。

其基本原理是以gdb调用待执行代码作为一个新的整体来被exec函数执行,使得待执行代码始终处于gdb的控制中,这样我们自然能够调试该子进程代码。

这个方法适合fork+exec模式,需要需要X环境支持(xterm/VNC)。


参考资料:

https://www.ibm.com/developerworks/cn/linux/l-cn-gdbmp/

使用GDB调试产生多进程的程序的更多相关文章

  1. gdb调试运行时的程序小技巧

    使用gdb调试运行时的程序小技巧 标签: 未分类 gdb pstack | 发表时间:2012-10-15 04:32 | 作者:士豪 分享到: 出处:http://rdc.taobao.com/bl ...

  2. GDB 调试多线程多进程

    GDB是linux下的调试利器,在c/c++程序开发过程中必不可少的.这里总结一下多进程和多线程的调试方法和技巧. 多进程的调试: 如下示例 #include <sys/mman.h> # ...

  3. gdb调试多线程多进程

    多进程调试 我们使用gdb调试程序,gdb的调试默认是调试父进程的,如果要做到对父进程和子进程都做到调试,所以附加了调试子进程的功能. 设置条件 如果让gdb可以同时调试多个程序,只需要设置follo ...

  4. gdb调试带参数的程序 (转载)

    转自:http://www.cnblogs.com/rosesmall/archive/2012/04/10/2440514.html 一般来说GDB主要调试的是C/C++的程序.要调试C/C++的程 ...

  5. c/c++ gdb 调试带参数的程序

    直接gdb pgname 参数1 这种方式,参数1是不会带到gdb里的 1,首先启动程序 gdb pgname 2,设置程序的参数 set args 参数1

  6. gdb调试正在运行的程序

    1.ps aux | grep mxx.exe 查找可执行程序的进程id 2.gdb attach pid attach可执行程序的进程pid 3.continue/c 或者continue or c ...

  7. gdb 调试,当发现程序退出,需要定位程序退出位置时。

    在进入gdb后设置,执行下面语句 handle SIGSEGV nopass handle SIGSEGV nostop 执行程序,触发问题,gdb侧执行c 故障出现时,执行bt,显示堆栈调用.

  8. gdb调试正执行的程序

    参考,转载:http://biancheng.dnbcw.info/linux/391846.html

  9. 用GDB 调试Java程序

      陈皓 http://blog.csdn.net/haoel 背景 想要使用GDB调试程序,就需要用GNU的编译器编译程序.如:用GCC编译的C/C++的程序,才能用GDB调试.对于Java程序也是 ...

随机推荐

  1. 对象转json串.

    public static Object returnObject(String jsonStr, Class objClass) {if (jsonStr == null) {return null ...

  2. Linux内核调试方法总结之Kprobes

    Kprobes [用途][参考kernel/Documentation/kprobes.txt帮助文档] Kprobes是一个轻量级内核调试工具,同时又是其他一些更高级的内核调试工具(如perf和sy ...

  3. NLog记录日志到本地或数据库

    OperatorLog CREATE TABLE [dbo].[OperatorLog]( ,) NOT NULL, [Createdate] [DATETIME] NOT NULL DEFAULT ...

  4. 添加环境变量(path)

    使用命令提示符((cmd)(批处理)(Batch)(.bat))添加环境变量 永久环境变量 命令提示符下修改 ==注意:要使用管理员身份运行cmd== set PATH=%PATH%;要添加的路径 r ...

  5. 内置函数zip,map,even

    内置函数的补充:1.zip:l1 = ['a','b','c','e','f','g']l2 = [1,2,3]l3=['A','B','C']L4=['牛','牛','niu']#zip,就是把俩l ...

  6. nw打包vue项目exe更换图标

    web项目用nw打包好了之后发现没办法更换桌面显示图标问题,找了一下发现大多推荐Resource进行最后更换,试了第一次怎么也不管用,电脑重启了一下就行了...... 首先下载安装好了Resource ...

  7. 【Linux】limits.conf 不重启就生效或者不生效的原因

    前阵子,我要用到使LInux的文件打开数为65534个,而且需要永久生效,于是将配置写到了: vim /etc/security/limits.conf * soft nofile 65534* ha ...

  8. 【ABAP系列】SAP ABAP中使用for all entries in小结

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[ABAP系列]SAP ABAP中使用for a ...

  9. python基础-5.1几种常见的排序算法

    一.冒泡排序(BubbleSort) 步骤: 比较相邻的元素,如果第一个比第二个大,就交换他们两个. 循环一遍后,最大的数就“浮”到了列表最后的位置. 将剩下的数再次循环,直道所有的排序完成 def ...

  10. [Python3] 017 字典的内置方法

    目录 1. Python3 中如何查看 dict() 的内置方法 2. 少废话,上例子 (1) 清理大师 clear() (2) 拷贝君 copy() (3) get(key, default=Non ...