gdb命令中attach使用

[测试程序]
咱们先看看咱们的测试程序:
/* 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

至此,咱们调试完毕。
shell

相关文章
相关标签/搜索