本文共 1495 字,大约阅读时间需要 4 分钟。
本文主要介绍了如何使用linux环境下的代码调试工具—gdb来调试多进程与多线程程序,主要内容有:
1. 问题引入2. 调试方法介绍及代码实例3. gdb常用命令总结4. 一些大神们关于此主题的介绍并附链接
——>全篇阅读(不包括链接)大概需要8min<——
读完本文后,你可以用简单的方法调试多线程多进程程序。对几种调试方法也会有一种宏观认识。
先来看一张图:
图中,Proc1通过调用fork函数产生子进程 Proc2,Proc2 又再次调用它产生子进程Proc3。这显然是一个多进程程序。
但是,默认设置下,GDB不支持多进程程序调试。在调试多进程程序时GDB只会调试主进程,即proc1。例如,使用GDB调试某个进程,如果该进程fork了子进程,GDB会继续调试该进程,子进程会不受干扰地运行下去。
注:GDB默认支持调试多线程
那么问题来了,如何使用 GDB 调试子进程 proc2 或者 proc3 呢?
这就是本博文要讲的主题。
总的来说,用gdb调试多进程与多线程有3种方法。
Solution1:follow-fork-mode
首先,这种方法对linux环境是有限制的:
在2.5.60版Linux内核及以后,GDB7.0版本以上的linux环境对使用fork/vfork创建子进程的程序提供了follow-fork-mode选项来支持多进程调试。
首先认识两个选项:
follow-fork-mode(同步进程模式):这个模式有两个选项:parent和child。默认值为parent
detach-on-fork(分离进程):这个模式也有两个选项:on和off 。默认值为on下面是他们各个选项组合所代表的含义:
从3和4可以看出,改变两个选项设置调试多进程,实际上只是从宏观上实现。同一时刻gdb只能操作一个进程,另一个进程只能被阻塞。
接下来通过代码来看看选项的设置方法和具体的调试过程。
首先调试多进程:
Step1:查看是否达到环境要求
内核版本:
GDB版本:可以看到,环境达到要求,所以可以进行操作。
Step2:编写多进程代码
首先看看fork函数的原型及返回值介绍:
编写代码:
运行代码确保代码编写无误:
Step3:开始调试
然后调试多线程:
Step1:编写代码
运行代码保证代码编写无误:
Solution2:Attach子进程
Solution3:GDB wrapper
很多时候,父进程 fork 出子进程,子进程会紧接着调用 exec族函数进行程序替换来执行新的代码。对于这种情况,我们也可以使用gdb wrapper 方法。它的优点是不用添加额外代码。
其基本原理是以gdb调用待执行代码作为一个新的整体来被exec函数执行,使得待执行代码始终处于gdb的控制中,这样我们自然能够调试该子进程代码。
这种方法可以参考文末的大神链接,博主技术太low,还不会实现。。。
小结
上述三种方法各有优缺点,因此适应于不同的场合和环境:
1.follow-fork-mode方法:方便易用,对系统内核和GDB版本有限制,适合于较为简单的多进程与多线程系统
2.attach子进程方法:灵活强大,但需要添加额外代码,适合于各种复杂情况,特别是守护进程
3.GDB wrapper方法:专用于fork+exec模式,不用添加额外代码,但需要X环境支持(xterm/VNC)
请移步:
1.3种方法综合讲解
IBM:
百度文库:
2.法1讲解:
高科大神:
CSDN:
百度: