GDB 调试技巧

5 篇文章 0 订阅

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.1
Copyright (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 main
Breakpoint 1 at 0x40070c: file gdbtest.cpp, line 23.
(gdb) b print
Breakpoint 2 at 0x4006a5: file gdbtest.cpp, line 7.
(gdb) info breakpoints
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x000000000040070c in main() at gdbtest.cpp:23
2       breakpoint     keep y   0x00000000004006a5 in print() at gdbtest.cpp:7
(gdb) r
Starting 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:23
23      int res = 0;
(gdb) l
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
(gdb) n
24      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 world5
31      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) n

Breakpoint 2, print () at gdbtest.cpp:7
7       int i,sum = 0;
(gdb) p sum
$2 = 0
(gdb) n
8       for ( i = 0; i < 30; i++)
(gdb) n
10          sum += i;
(gdb) n
8       for ( i = 0; i < 30; i++)
(gdb) u 39
sum = 435 
main () at gdbtest.cpp:39
39      return 0;
(gdb) u 39
sum = 435 
main () at gdbtest.cpp:39
39      return 0;
(gdb) q
A debugging session is active.

    Inferior 1 [process 106662] will be killed.

Quit anyway? (y or n) y

总结

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值