欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

GDB调试工具

程序员文章站 2022-06-03 22:40:04
...

1.GDB 它是由 Richard Stallman(开源软件运动的领路人)开发的GNU项目调试器( GNU Project Debugger)。
2. gdb中每创建的一个断点都被标识为从 1 开始的唯一整数标识符。这个标识符用来执行该断点上的各种操作。

/* 示例代码  文件名a.c  可执行程序名: g++ a.c -o a -g*/
  1 #include <stdio.h>
  2 #include <string.h>
  3 #include <stdlib.h>
  4 #include <string>
  5 #include <iostream>
  6 using namespace std;
  7 
  8 class Test
  9 {
 10 public:
 11     Test(int a, int b):m_a(a),m_b(b){}
 12     ~Test(){};
 13 
 14     void DisplayMemData()
 15     {
 16         std::cout<<m_a<<","<<m_b<<std::endl;
 17     }
 18 
 19     //重载函数
 20     void setTestMem(int a)
 21     {
 22         m_a = a;
 23     }
 24 
 25     void setTestMem(int a, int b)
 26     {
 27         m_a = a;
 28         m_b = b;
 29     }
 30 
 31 private:
 32     int m_a;
 33     int m_b;
 34 };
 35 int main()
 36 {
 37     Test t(10,20);
 38     t.DisplayMemData();
 39     std::cout<<"---------------------"<<std::endl;
 40     t.setTestMem(100,200);
 41     t.DisplayMemData();
 42     std::cout<<"---------------------"<<std::endl;
 43     t.setTestMem(600);
 44     t.DisplayMemData();
 45 
 46     return 0;
 47 }

当创建一个断点时,gdb 会提示该断点的编号信息。如:(gdb) break 38, 则提示:Breakpoint 1 at 0x400923: file a.cpp, line 38.
查看所有断点:info breakpoints(简写: i b)
删除断点:delete 断点标识符列表, 如: delete 1 3 4
设置断点:
方法一: break function(表示在函数function的入口处打断点)
方法二: break line_number(在当前活动源代码的 line_number 处设置断点)
方法三: break filename: line_ number(在源代码文件filename的line_number处设置断点。如果filename不在当前工作目录中,可以给出其相对路径或绝对路径)
方法四: break filename: function(在文件filename的function函数入口处设置断点。重载函数或同名静态函数需要使用该断点方式

上面4种方式设置的断点的有效性直到 delete ,禁用或退出gdb为止。而另外一种所谓的临时断点有效性,则是首次到达之后,就会被删除。其命令:tbreak, 使用方式和 break相似。如:

(gdb) tbreak 37
Temporary breakpoint 1 at 0x40090d: file a.cpp, line 37.
(gdb) info breakpoints 
Num     Type           Disp Enb Address            What
1       breakpoint     del  y   0x000000000040090d in main() at a.cpp:37
(gdb) 

hbreak 设置硬件辅助断点。它是可以在内存中设置的断点,不需要修改该内存位置的内容。
thbreak 设置临时硬件辅助断点。

3. 当程序中的某行代码被断点(break)多次时候,只有一次生效。而且在多个断点的代码行上,触发中断的断点将是标识符编号最小的断点
4. 当 gdb 调试终端不退出时,即没有 quit时;若此时该程序代码被修改了。当重新在gdb的调试终端中run的时候,这些所有的断点都将保存而不会丢失。而且会自动重新加载新的修改编译后的代码

//终端1  文件名b.c g++ b.c -o b -g -O3  可执行文件名:b
 1 #include <iostream>
  2 using namespace std;
  3 int main()
  4 {
  5     int i = 5;
  6     return 0;
  7 } 

//使用gdb开始调试
[email protected]:~/work/testCode$ gdb b
GNU gdb (GDB) 7.6.1
Copyright (C) 2013 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-unknown-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /data1/lixiaogang5/work/testCode/b...done.
(gdb) list
1	#include <iostream>
2	using namespace std;
3	int main()
4	{
5		int i = 5;
6		return 0;
7	}
(gdb) break 5
Breakpoint 1 at 0x400540: /data1/lixiaogang5/work/testCode/b.cpp:5. (2 locations)
(gdb) 

//此时在终端2中修改了代码为:
  1 #include <iostream>
  2 using namespace std;
  3 int main()
  4 {
  5     int i = 5;
  6     std::cout<<i<<std::endl;
  7     return 0;
  8 }

//然后在终端1中继续 r 的时候,则会提示并重新加载修改后的程序。
(gdb) r
`/data1/lixiaogang5/work/testCode/b' has changed; re-reading symbols.
Starting program: /data1/lixiaogang5/work/testCode/b 

Breakpoint 1, main () at b.cpp:6
6		std::cout<<i<<std::endl;
(gdb) 

//可以看到之前设置的断点1仍然保存着。而且提示已更新。

5. 删除gdb断点
(1)clear 清楚gdb将要执行的下一个指令处断点。
(2)delete breakpoint_list 删除断点使用数字表示符,可以是一个断点,也可以是断点列表
(3)delete 删除所有断点. 如下所示:

(gdb) list
1	#include <iostream>
2	using namespace std;
3	int main()
4	{
5		int i = 5;
6		std::cout<<i<<std::endl;
7		return 0;
8	}
(gdb) break 5
Breakpoint 2 at 0x400644: file b.cpp, line 5.
(gdb) break 6
Note: breakpoint 2 also set at pc 0x400644.
Breakpoint 3 at 0x400644: file b.cpp, line 6.
(gdb) info b
Num     Type           Disp Enb Address            What
2       breakpoint     keep y   0x0000000000400644 in main() at b.cpp:5
3       breakpoint     keep y   0x0000000000400644 in main() at b.cpp:6
(gdb) delete 
删除所有断点吗? (y or n) y
(gdb) info b
No breakpoints or watchpoints.

6. gdb 禁用断点
disable breakpoint-list 命令禁用断点(空格分隔的列表),不带任何参数的disable将禁用所有的断点。

(gdb) list
1	#include <iostream>
2	using namespace std;
3	int main()
4	{
5		int i = 5;
6		std::cout<<i<<std::endl;
7		return 0;
8	}
(gdb) b 5  //在程序的第5行出加断点
Breakpoint 1 at 0x400644: file b.cpp, line 5.
(gdb) info breakpoints 
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x0000000000400644 in main() at b.cpp:5
(gdb) r
Starting program: /data1/lixiaogang5/work/testCode/b 

Breakpoint 1, main () at b.cpp:6
6		std::cout<<i<<std::endl;
(gdb) disable 1  //现在禁用该断点 ,重新 run 时候,该断点被禁用,忽略,直接执行打印
(gdb) r
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /data1/lixiaogang5/work/testCode/b 
5
[Inferior 1 (process 26428) exited normally]
(gdb) 

enable breakpoint-list 命令启用断点(空格分隔的列表),不带任何参数的enable将启用所有的断点

(gdb) enable 1
(gdb) info b
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x0000000000400644 in main() at b.cpp:5
(gdb) r
Starting program: /data1/lixiaogang5/work/testCode/b 

Breakpoint 1, main () at b.cpp:6
6		std::cout<<i<<std::endl;
(gdb) n
5
8	}