使用gdb调试多进程与多线程程序

来源:互联网 发布:java poin型变量 编辑:程序博客网 时间:2024/06/05 19:33

高能预警


本文主要介绍了如何使用linux环境下的代码调试工具—gdb来调试多进程与多线程程序,主要内容有

1. 问题引入2. 调试方法介绍及代码实例3. gdb常用命令总结4. 一些大神们关于此主题的介绍并附链接

——>全篇阅读(不包括链接)大概需要8min<——

读完本文后,你可以用简单的方法调试多线程多进程程序。对几种调试方法也会有一种宏观认识。


问题引入


先来看一张图:

1

图中,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

下面是他们各个选项组合所代表的含义:

2

从3和4可以看出,改变两个选项设置调试多进程,实际上只是从宏观上实现。同一时刻gdb只能操作一个进程,另一个进程只能被阻塞。

接下来通过代码来看看选项的设置方法和具体的调试过程。

首先调试多进程:

Step1:查看是否达到环境要求

内核版本:
1
GDB版本:
3

可以看到,环境达到要求,所以可以进行操作。

Step2:编写多进程代码

首先看看fork函数的原型及返回值介绍:

4

编写代码:

5

运行代码确保代码编写无误:

8

Step3:开始调试

然后调试多线程

Step1:编写代码

10

运行代码保证代码编写无误:

6

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)


gdb常用命令总结


请移步:陈皓大神gdb调试系列


大神链接


1.3种方法综合讲解

IBM:使用 GDB 调试多进程程序

百度文库:多进程 多线程调试方法 GDB调试 .

2.法1讲解:

高科大神:gdb调试多进程和多线程命令

CSDN:Linux多进程和多线程的一次gdb调试实例

百度:GDB调试-多进程与多线程程序

原创粉丝点击