`
weiyinchao88
  • 浏览: 1234565 次
文章分类
社区版块
存档分类
最新评论

用GDB调试多进程程序

 
阅读更多

有一段时间没有写技术方面的东西了^_^。众所周知,GDB是Unix/Linux下调试程序的龙头老大,GDB功能强大,我们在平时多使用其一些最基本的功能,而且一般调试的都是单进程的程序。最近一个项目中的问题让我接触如何使用GDB调试多进程程序,更确切的是说调试调用fork的多进程程序。

使用GDB最好的文档就是其名为'Debugging with GDB'的参考手册。手册中有一小章节提到了如何调试多进程程序。一般情况下,如果被gdb调试的程序中调用fork派生出一个新的子进程,这时gdb调试的仍然还是父进程,其子进程的执行不被理会。如果之前你在子进程的执行routine上设置了断点,那么当子进程执行到那个断点时,子进程会因为收到一个SIGTRAP信号而自行终止,除非你在子进程中拦截了该信号。

那么使用GDB该如何调试多进程程序呢?在其参考手册中提供了一种通用方法,这里说说(GDB在某些平台上如HP-UX,还提供了更简便的方法,不过不具备通用性,这里不说):

[测试程序]
我们先看看我们的测试程序:
/* in eg1.c */

int wib(int no1, int no2)
{
int result, diff;
diff = no1 - no2;
result = no1 / diff;
return result;
}

int main()
{
pid_t pid;

pid = fork();
if (pid <0) {
printf("fork err/n");
exit(-1);
} else if (pid == 0) {
/* in child process */
sleep(60); ------------------ (!)

int value = 10;
int div = 6;
int total = 0;
int i = 0;
int result = 0;

for (i = 0; i < 10; i++) {
result = wib(value, div);
total += result;
div++;
value--;
}

printf("%d wibed by %d equals %d/n", value, div, total);
exit(0);
} else {
/* in parent process */
sleep(4);
wait(-1);
exit(0);
}
}
该测试程序中子进程运行过程中会在wib函数中出现一个'除0'异常。现在我们就要调试该子进程。

[调试原理]
不知道大家发现没有,在(!)处在我们的测试程序在父进程fork后,子进程调用sleep睡了60秒。这就是关键,这个sleep本来是不该存在于子进程代码中的,而是而了使用GDB调试后加入的,它是我们调试的一个关键点。为什么要让子进程刚刚运行就开始sleep呢?因为我们要在子进程睡眠期间,利用shell命令获取其process id,然后再利用gdb调试外部进程的方法attach到该process id上,调试该进程。

[调试过程]
我觉上面的调试原理的思路已经很清晰了,剩下的就是如何操作的问题了。我们来实践一次吧!
我所使用的环境是Solaris OS 9.0/GCC 3.2/GDB 6.1。

GDB调试程序的前提条件就是你编译程序时必须加入调试符号信息,即使用'-g'编译选项。首先编译我们的源程序'gcc -g -o eg1 eg1.c'。编译好之后,我们就有了我们的调试目标eg1。由于我们在调试过程中需要多个工具配合,所以你最好多打开几个终端窗口,另外一点需要注意的是最好在eg1的working directory下执行gdb程序,否则gdb回提示'No symbol table is loaded'。你还得手工load symbol table。好了,下面我们就'按部就班'的开始调试我们的eg1。

执行eg1:
eg1 & --- 让eg1后台运行吧。

查找进程id:
ps -fu YOUR_USER_NAME

运行gdb:
gdb
(gdb) attach xxxxx --- xxxxx为利用ps命令获得的子进程process id
(gdb) stop --- 这点很重要,你需要先暂停那个子进程,然后设置一些断点和一些Watch
(gdb) break 37 -- 在result = wib(value, div);这行设置一个断点,可以使用list命令察看源代码
Breakpoint 1 at 0x10808: file eg1.c, line 37.
(gdb) continue
Continuing.

Breakpoint 1, main () at eg1.c:37
37 result = wib(value, div);
(gdb) step
wib (no1=10, no2=6) at eg1.c:13
13 diff = no1 - no2;
(gdb) continue
Continuing.

Breakpoint 1, main () at eg1.c:37
37 result = wib(value, div);
(gdb) step
wib (no1=9, no2=7) at eg1.c:13
13 diff = no1 - no2;
(gdb) continue
Continuing.

Breakpoint 1, main () at eg1.c:37
37 result = wib(value, div);
(gdb) step
wib (no1=8, no2=8) at eg1.c:13
13 diff = no1 - no2;
(gdb) next
14 result = no1 / diff;
(gdb) print diff
$6 = 0 ------- 除数为0,我们找到罪魁祸首了。
(gdb) next
Program received signal SIGFPE, Arithmetic exception.
0xff29d830 in .div () from /usr/lib/libc.so.1

至此,我们调试完毕。

上面仅仅是一个简单的多进程程序,在我们平时开发的多进程程序远远比这个复杂,但是调试基本原理是不变,有一些技巧则需要我们在实践中慢慢摸索。

分享到:
评论

相关推荐

    gdb 多进程程序调试

    本文将深入探讨如何使用GNU调试器(gdb)来调试多进程程序,并详细介绍gdb提供的各种功能以及其在不同操作系统中的应用。 #### 一、gdb简介 gdb(GNU Debugger)是一款广泛使用的开源调试器,支持多种编程语言如C...

    GDB调试程序[陈皓]&GDB调试工具指南

    在《GDB调试程序[陈皓]》中,作者陈皓可能详细介绍了如何使用GDB来调试程序。他可能会涵盖如何启动GDB、加载目标程序、设置断点、单步执行、查看和修改变量值、以及如何处理多线程和共享库的问题。此外,陈皓可能还...

    Debugging with GDB 用GDB调试多线程程序

    ### 使用GDB调试多线程程序 在Linux环境下,GDB(GNU调试器)是进行程序调试的强大工具,尤其在处理复杂多线程程序时,GDB提供了丰富的功能来帮助开发者定位和解决问题。本文将详细介绍如何利用GDB的特性来有效地...

    GDB调试程序文档

    ### GDB调试程序知识点 #### 一、GDB概述 - **定义**: GDB(GNU Debugger)是一款由GNU项目开发的开源调试工具,主要用于调试C、C++等语言编写的程序。 - **特点**: - 命令行界面:用户通过命令行交互的方式来控制...

    GDB基本调试原理及三种调试方式

    **GDB调试原理** GDB,全称GNU Debugger,是一个强大的源代码级调试工具,用于检查和调试C、C++等编程语言编写的程序。它的主要功能在于帮助开发者找到并修复程序中的错误(bug),以及深入理解程序的执行流程和...

    GDB调试参考手册

    手册还说明了如何调试已经在运行的进程,如何终止子进程,以及如何调试多线程程序和进程的分支(forks)。 手册中还专门有一部分讲解了使用GDB设置断点(breakpoints)、观察点(watchpoints)和捕获点...

    GDB--gdb调试.pdf

    - **多进程与多线程调试**:GDB支持对包含多个进程或线程的复杂程序进行调试,使用相应的命令可以切换和控制不同进程或线程的状态。 ### 运行程序下的调试技巧 对于已经在运行的进程,GDB提供了特殊的方法进行调试...

    Linux下gdb调试工具指南

    - **多进程调试**:当程序包含多个进程时,GDB的`attach`命令可以帮助跟踪特定进程的运行情况。 - **远程调试**:通过网络连接远程主机上的程序,GDB的远程调试功能为分布式系统的调试提供了便利。 #### GDB脚本化...

    使用gdb进行调试 gdb

    - **高级调试功能**:GDB提供了一系列高级功能,如信号跟踪、核心转储分析、多进程调试等,这些都是图形界面调试器难以匹敌的。 #### 实战示例解析 通过一个具体的示例来深入理解GDB的使用方法。以下是对一个简单...

    gdb调试(个人收集的丰富的GDB调试资料)

    - **多进程调试**:支持同时跟踪多个进程的行为,这对于复杂系统的调试非常有帮助。 #### 调试示例 以下通过一个简单的C程序来演示如何使用GDB进行调试: ```c #include int func(int n) { int sum = 0, i; ...

    GDB调试多线程

    调试多进程** 对于多进程应用程序,GDB同样提供了相应的工具和策略。由于子进程继承了父进程的部分状态,但又具有独立的地址空间,因此跟踪子进程需要额外的技巧: - **跟踪子进程**:GDB本身并不直接支持跟踪子...

    Linux GDB调试文档

    总结来看,一个合格的Linux C/C++后台开发者应该掌握GDB调试技术,利用这一强大的工具来增强开发过程中的问题诊断和解决能力。GDB的版本不断更新,其功能也在不断增强,例如在*.*.*.**版本中,特别强调了对多线程和...

    GDB调试器的使用说明文档

    ### GDB调试器的核心知识点详解 #### 一、GDB简介 GDB(GNU Debugger)是一款由...虽然GDB的命令行界面可能不如图形界面直观,但它提供了更丰富的调试功能和更大的灵活性,尤其适用于复杂的多线程或多进程程序的调试。

    用GDB调试程序

    - **多进程/多线程调试**:支持同时调试多个进程或线程,这对于多线程程序的调试非常重要。 通过掌握GDB的各种功能和命令,开发者可以有效地定位和解决问题,提高程序的质量和稳定性。希望这篇详细介绍能够帮助你更...

    Ubuntu GDB调试例子

    为了使编译后的程序能够支持GDB调试,编译时需要加上 `-g` 参数,例如使用GCC编译器时可以这样写:`gcc -o test_gdb test_gdb.c -g` **5. 列出源代码** - **命令形式:** `list` - **功能解释:** 列出源代码的一...

    GDB调试手册(GNU C程序调试必备)

    《GDB调试手册》是GNU项目为C程序员提供的一...总之,《GDB调试手册》深入浅出地讲解了gdb的各种功能和使用技巧,是每个C程序员进行高效程序调试不可或缺的资源。无论是初学者还是经验丰富的开发者,都能从中受益匪浅。

    用GDB调试程序(Debugging with GDB)

    - 在现代软件开发中,多线程或多进程的应用非常普遍,gdb能够有效地调试这类程序。 #### 二、gdb的基本命令概览 - **启动gdb** - `gdb [options] program` - 其中`program`是需要调试的程序名称。 - **加载程序...

    gdb调试官方文档

    GDB官方文档通常会介绍其使用的命令、调试会话的流程、程序运行控制、数据观察和修改、以及多线程和多进程程序的调试方法。 在官方文档中,您会发现GDB调试的概览,包含了一些自由软件的概念,以及如何进行GDB会话...

    gdb调试器详解(中文版)

    #### 十二、用GDB调试不同语言编写的程序 gdb支持多种语言的调试,包括但不限于C/C++。 ```bash (gdb) set language c++ ``` 以上只是gdb部分功能的介绍,更多高级特性还需读者在实践中不断探索。通过熟练掌握gdb...

    gdb调试工具

    9. **调试多线程程序**:GDB可以同时跟踪多个线程,查看每个线程的状态,这对于处理并发和同步问题特别有用。 10. **核心转储分析**:当程序异常退出时,可以生成核心转储文件,GDB可以分析这些文件以确定崩溃发生...

Global site tag (gtag.js) - Google Analytics