GDB——GDB的断点调试

那么我们应该如何使用GDB呢?GDB为我们提供了什么样的功能呢?我们可以参照图形界面调试器的基本功能,使用GDB来实现。例如:

问题:我们如何使用GDB设置断点,删除断点的操作?
- 通过函数名设置断点
1. break func_name [ if var = value ]
2. tbreak func_name [ if var = value ]
- 通过文件名行号设置断点
1. break file_name : line_num [ if var = value ]
2. tbreak file_name : line_num [ if var = value ]

这里写图片描述

注意:GDB中的断点调试分为软件断点和硬件断点两种类型:
- 软件断点:由非法指令异常实现(软件实现)
- 硬件断点:由硬件特性实现(数量有限)
- 数据断点:有硬件特性实现(数量有限)

通常情况下,我们使用的都是软件断点。那么,什么情况下我们需要用到硬件断点和数据断点呢?
1. 当代码位于只读存储器(Flash)时,只能通过硬件断点调试。
2. 硬件断点需要硬件支持,数量有限
3. GDB中通过hbreak命令支持硬件断点
4. hbreak与break使用方式完全一致

问题:在图形界面中我们常常使用到的操作有:查看特定变量的值,执行下一步代码,直接运行代码等等的操作。GDB中相关命令是怎么样的呢?
这里写图片描述

GDB操作过程:

PS C:\WorkSpace\exercise\VsCode> gcc -g .\test.c .\func.c -o .\test.exe
PS C:\WorkSpace\exercise\VsCode> gdb   < ----------启动GDB
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 "mingw32".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
(gdb) file test.exe     < ------------------ 指定GDB检测这个可执行文件
Reading symbols from C:\WorkSpace\exercise\VsCode\test.exe...done.
(gdb) set args Shaw   < ----------设置主函数输入参数args
(gdb) info break      < ----------打印程序断点信息
No breakpoints or watchpoints.
(gdb) break test.c:37  < ----------设置断点
Breakpoint 1 at 0x4014ba: file .\test.c, line 37.
(gdb) info break
Num     Type           Disp Enb Address    What
1       breakpoint     keep y   0x004014ba in main at .\test.c:37
(gdb) start         < ------------启动代码
Temporary breakpoint 2 at 0x401442: file .\test.c, line 25.
Starting program: C:\WorkSpace\exercise\VsCode/test.exe Shaw
[New Thread 10792.0x300c]
[New Thread 10792.0x3798]
Temporary breakpoint 2, main (argc=2, argv=0x651560) at .\test.c:25
25
(gdb) continue    < ------------- 继续执行代码
Continuing.
main() : begin...
argv[0] = C:\WorkSpace\exercise\VsCode/test.exe
argv[1] = Shaw
Breakpoint 1, main (argc=2, argv=0x651560) at .\test.c:37
37          }
(gdb) next       < ------------- 运行下一步
test_1() : 004013E0
38
(gdb) next
35              fa[i%3]();
(gdb) next

Breakpoint 1, main (argc=2, argv=0x651560) at .\test.c:37
37          }
(gdb) next
test_2() : 004013FC
38
(gdb) print i     < -------------- 打印变量值
$1 = 1
(gdb) set var i=100   < ----------------- 设置变量值
(gdb) countinue
Program received signal SIGSEGV, Segmentation fault.
0x00401539 in func () at .\func.c:7

问题:start和run有什么区别呢?

从实验现象我们可以知道:start后会在程序开始的时候打一个断点,而run则是直接运行代码。

问题:addr2line 和 gdb 也可以发现同样的段错误。那么两者有什么区别么?

实际上,addr2line是静态分析工具,在之前的实验我们也知道,我们使用addr2line打印错误位置时,需要用到core文件。这是一种事后分析的方式。
但是,GDB关注的是内存中正在运行的进程。所以gdb属于动态分析工具。所以GDB比addr2line使用更加方便。

版权声明:本文为small_prince_原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/small_prince_/article/details/80681684