gdb调试工具的使用

时间:2022-12-18 10:51:59

1.gdb介绍

GDB是一个强大的命令行调试工具。大家知道命令行的强大就是在于,其可以形成执行序列,形成脚本。UNIX的软件全是命令行的,这给程序开发提代供了极大的便利,命令行软件的优势在于,它们可以非常容易的集成在一起,使用几个简单的已有工具的命令,就可以做出一个非常强大的功能。
于是UNⅨ下的软件比Windows下的软件更能有机地结合,各自发挥各自的长处,组合成更为强劲的功能。而Windows下的图形软件基本上是各自为营,互相不能调用,很不利于各种软件的相互集成。在这里并不是要和Windows做个什么比较,所谓“寸有所长,尺有所短”,图形化工具还有时不如命令行的地方。

2.gdb的常用命令

  • help(h)———按模块列出命令类
  • help class——查看某一类型的具体命令
  • list(l)———查看代码,可跟行号和函数名
  • quit(q)———退出gdb
  • run(r)———-全速运行程序
  • start———–单步执行,运行程序,停在第一行执行语句
  • next(n)———逐过程执行
  • step(s)———逐语句执行,遇到函数,跳到函数内执行
  • backtrace(bt)–查看函数的调用的栈帧和层级关系
  • info(i)———查看GDB内部局部变量的数值,info breakpoints切换函数的栈帧。
  • finish———-结束当前函数,返回到函数调用点
  • set————-设置变量的值 set var n = 100
  • run argv[1] argv[2]–调试时命令行传参
  • print(p)——–打印变量和地址
  • break(b)——–设置断点,可根据行号和函数名
  • delete(d)——-删除断点d breakpoints NUM
  • display———设置观察变量
  • undisplay——-取消观察变量
  • continue(c)—–继续全速运行剩下的代码
  • enable breakpoints ——-启用断点
  • disable breakpoints——-禁用断点
  • x —————–查看内存 x /20xw 显示20个单元,16进制,4字节每单元
  • watch————被设置观察点的变量发生修改时,打印显示

  • i watch———-显示观察点

  • core文件———ulimit -c 1024 开启core文件,调试时gdb a.out core

3.gdb工具的使用

要想使用gdb工具进行调试编译好的程序,需要gcc或者g++在编译程序的时候使用-g选项。
下面以一个循环链表程序用来调试。

  • help
(gdb) h
List of classes of commands:

aliases -- Aliases of other commands
breakpoints -- Making program stop at certain points
data -- Examining data
files -- Specifying and examining files
internals -- Maintenance commands
obscure -- Obscure features
running -- Running the program
stack -- Examining the stack
status -- Status inquiries
support -- Support facilities
tracepoints -- Tracing of program execution without stopping the program
user-defined -- User-defined commands

Type "help" followed by a class name for a list of commands in that class.
Type "help all" for the list of all commands.
Type "help" followed by command name for full 
documentation.
Type "apropos word" to search for commands related to "word".
Command name abbreviations are allowed if unambiguous.
(gdb) 
  • list [可以跟函数名也可以跟行号]

    (gdb) l
    6   
    7   typedef struct _Student
    8   {
    9       CircleListNode circlenode;
    10      int age;
    11  }Student;
    12  
    13  int main()
    14  {
    15      CircleList *list = CircleList_Create();
    (gdb)
  • break

(gdb) l
6   
7   typedef struct _Student
8   {
9       CircleListNode circlenode;
10      int age;
11  }Student;
12  
13  int main()
14  {
15      CircleList *list = CircleList_Create();
(gdb) b 15
Breakpoint 1 at 0x804884d: file test.c, line 15.
  • start
(gdb) start Temporary breakpoint 2 at 0x804884d: file test.c, line 15. Starting program: /home/cat/struct_data/a.out Breakpoint 1, main () at test.c:15 15 CircleList *list = CircleList_Create();
(gdb) 
  • step
(gdb) s
CircleList_Create () at circlelist.c:16
16      TCircleList *ret = (TCircleList *)malloc(sizeof(TCircleList));
(gdb) l 16
11      int length;
12  }TCircleList;
13  
14  CircleList* CircleList_Create()
15  {
16      TCircleList *ret = (TCircleList *)malloc(sizeof(TCircleList));
17      
18      if (ret == NULL)
19      {
20          return NULL;
(gdb) 
  • next
(gdb) n
18      if (ret == NULL)
(gdb) n
23      ret->header.next = NULL;
(gdb) 
24      ret->slider = NULL;
(gdb) 
25      ret->length = 0;
(gdb) 
27      return ret;
(gdb) 
28  }
(gdb) 
main () at test.c:19
19      int i = 0;
(gdb) l
14  {
15      CircleList *list = CircleList_Create();
16  
17      Student t1, t2, t3, t4;
18  
19      int i = 0;
20  
21      t1.age = 21;
22      t2.age = 22;
23      t3.age = 23;
(gdb) 

列举几个试试,其他的自己练习吧。