GDB 调试技巧

来源:互联网 发布:js控制embed视频播放 编辑:程序博客网 时间:2024/06/06 02:25

GDB 调试技巧

GDB 简介

在Windows环境下,在IDE中已经集成了调试的功能,并且使用自带的界面进行调试,方便简介。但是在linux系统上,特别是使用远程登录进行编辑,调试,却需要掌握以下基本的调试技巧。
GDB是GNU开源组织发布的一个强大的UNIX下的程序调试工具。或许,各位比较喜欢那种图形界面方式的,像VC、BCB等IDE的调试,但如果你是在UNIX平台下做软件,你会发现GDB这个调试工具有比VC、BCB的图形化调试器更强大的功能。一般来说,GDB主要帮忙你完成下面四个方面的功能:

  1. 启动你的程序,可以按照你的自定义的要求随心所欲的运行程序。
  2. 可让被调试的程序在你所指定的调置的断点处停住。(断点可以是条件表达式)
  3. 当程序被停住时,可以检查此时你的程序中所发生的事。
  4. 动态的改变你程序的执行环境。

GDB 基本调试命令

在GDB调试之前,首先要使用-g选项进行编辑链接生成可执行文件,然后进行调试。进入调试以后,首先可以使用help查看常用的命令,如果想要查看更多,使用help all 查看更加详细的命令。在下面,我就简单的列举一些常用的命令,在后面会用一个简单的例子来说明如何使用。在GDB命令中,可以使用缩写命令,下面括号内为简写命令。
1. break (b),在程序中添加断点。
2. list (l), 执行处的代码。
3. run (r) 运行程序
4. clear 清除断点
5. print (p) 打印变量的值 p a[$] p[$$] , $代表了最有一次操作的结果,$$ 代表倒数第二次的结果。 p a[0]@<5>打印连续数据项指定数目的数组元素,上述表达式就是打印a[0]-a[4]。
6. contiune (cont) 程序继续执行
7. next (n) 执行下一行代码
8. info 查看当前栈帧局部变量的值 ,info breakpoints 查看断点信息
info threads 查看当前线程
9. until 运行到
10. quit (q) 退出调试
11. step (s) 执行下一行语句,如果有函数调用,进入函数中。
12. frame (f) 查看当前栈局部变量的值
13. backtrace (bt) 查看各级函数调用以及参数
14. set args 设置运行时候的参数
15. show args 查看设置好的参数
16. display 命令告诉每次程序在断点位置时自动显示数组的内容。
17. command 修改断点设置,使程序不是在断点处停下来,而是显示要看的数据,然后继续执行。

例子

下面我们用一个简单的例子来测试一下常见的GDB调试过程:

源代码:

  1 #include <stdio.h>                                                                                                                 2 #include <pthread.h>  3 #include <stdlib.h>  4   5 void print()  6 {  7     int i,sum = 0;  8     for ( i = 0; i < 30; i++)  9     { 10         sum += i; 11     } 12     printf("sum = %d \n", sum); 13 } 14 void* threadFunction(void *) 15 { 16     int x = 5; 17     printf("hello world%d\n", x); 18  19 }  20 int main() 21 { 22     pthread_t  mythread ; 23     int res = 0; 24     res = pthread_create(&mythread, NULL, threadFunction, NULL); 25     if(res != 0) 26     { 27 #ifdef DEBUG 28         printf("thread create error\n"); 29 #endif 30     } 31     res = pthread_join(mythread, NULL); 32     if(res != 0) 33     { 34 #ifdef DEBUG 35         printf("thread join error\n"); 36 #endif 37     } 38     print(); 39     return 0; 40  41 }         

GDB 调试

GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1Copyright (C) 2014 Free Software Foundation, Inc.License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>This is free software: you are free to change and redistribute it.There is NO WARRANTY, to the extent permitted by law.  Type "show copying"and "show warranty" for details.This GDB was configured as "x86_64-linux-gnu".Type "show configuration" for configuration details.For bug reporting instructions, please see:<http://www.gnu.org/software/gdb/bugs/>.Find the GDB manual and other documentation resources online at:<http://www.gnu.org/software/gdb/documentation/>.For help, type "help".Type "apropos word" to search for commands related to "word"...Reading symbols from gdbtest...done.(gdb) b mainBreakpoint 1 at 0x40070c: file gdbtest.cpp, line 23.(gdb) b printBreakpoint 2 at 0x4006a5: file gdbtest.cpp, line 7.(gdb) info breakpointsNum     Type           Disp Enb Address            What1       breakpoint     keep y   0x000000000040070c in main() at gdbtest.cpp:232       breakpoint     keep y   0x00000000004006a5 in print() at gdbtest.cpp:7(gdb) rStarting program: /home/wyj/demo/suibian/gdbtest [Thread debugging using libthread_db enabled]Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".Breakpoint 1, main () at gdbtest.cpp:2323      int res = 0;(gdb) l18  19  }20  int main()21  {22      pthread_t  mythread ;23      int res = 0;24      res = pthread_create(&mythread, NULL, threadFunction, NULL);25      if(res != 0)26      {27  #ifdef DEBUG(gdb) n24      res = pthread_create(&mythread, NULL, threadFunction, NULL);(gdb) p res$1 = 0(gdb) info threads  Id   Target Id         Frame * 1    Thread 0x7ffff7fd7740 (LWP 106662) "gdbtest" main () at gdbtest.cpp:24(gdb) n[New Thread 0x7ffff77f6700 (LWP 106676)]hello world531      res = pthread_join(mythread, NULL);(gdb) info threads  Id   Target Id         Frame   2    Thread 0x7ffff77f6700 (LWP 106676) "gdbtest" 0x00007ffff78e272d in write ()    at ../sysdeps/unix/syscall-template.S:81* 1    Thread 0x7ffff7fd7740 (LWP 106662) "gdbtest" main () at gdbtest.cpp:31(gdb) n[Thread 0x7ffff77f6700 (LWP 106676) exited]38      print();(gdb) bt#0  main () at gdbtest.cpp:38(gdb) nBreakpoint 2, print () at gdbtest.cpp:77       int i,sum = 0;(gdb) p sum$2 = 0(gdb) n8       for ( i = 0; i < 30; i++)(gdb) n10          sum += i;(gdb) n8       for ( i = 0; i < 30; i++)(gdb) u 39sum = 435 main () at gdbtest.cpp:3939      return 0;(gdb) u 39sum = 435 main () at gdbtest.cpp:3939      return 0;(gdb) qA debugging session is active.    Inferior 1 [process 106662] will be killed.Quit anyway? (y or n) y

总结

上述的都是一些简单常用的调试技巧,如果需要更加复杂的调试,在GDB中使用help,如果有必要,使用linux man gdb,仔细看看,一切都比较简单了。

0 0
原创粉丝点击