标签:
 [测试程序]
 我们先看看我们的测试程序:
 /* 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
 
 至此,我们调试完毕。
标签:
原文地址:http://www.cnblogs.com/djzny/p/4956752.html