基础能力系列 - GDB的使用

GDB是“GNU Symblic Debugger”的缩写,是GNU自由软件下的一个产品,随着版本不断地更新迭代,目前最新的GDB版本不仅可以调试C语言程序,还可以调试C++、Go、Rust、Object-C等编译型语言

将涵盖以下内容:

0.编译优化

为提高程序的运行效率和性能,编译器在编译程序时,往往会对源程序进行优化,比如常量折叠、缓存、内联展开等。

在编译程序时,可以通过参数来控制编译优化级别,一般可分为如下等级:

  • -O0:不对程序进行编译优化,默认的优化等级
  • -O1:可以减少目标文件的体积和程序执行时间
  • -O2:在-O1优化的基础上,编译器不执行循环展开和函数内联,增加了代码的性能
  • -Os:在-O2优化的基础上,专门优化目标文件的大小
  • -O3:在-O2优化的基础上,打开了-finline-functions, -funswitch-loops等标签

1.编译时打开调试功能(c++)

想要源码级调试,就需要在编译程序时选中:debug选项(-g),生成的debug模式下的可执行文件a.out就包含了各种调试信息,其中最重要的一个信息就是:二进制机器指令和源程序代码之间的对应关系

gcc -g -O0 main.c -o a.out

2.进入调试

gdb a.out

基础命令

set args -xxx 	//设置命令行参数

r				//run
q				//quit (不退出的话,按r可以再次运行)

设置断点

b 行号				   //打断点 指定行号
b main					//打断点 指定函数名
b application.cpp:420	//打断点 指定文件名:行号
l						//list 查看部分源代码

info b					//查看断点信息
disable b 1				//停用第1个断点
enable b 1				//启用第1个断点
clear 					//清除当前行上的的断点

进入断点后, 查看与调试

where					//查看现在在哪儿
l						//查看上下文源代码
bt						//查看堆栈
info locals				//查看局部变量
info frame 				//查看堆栈帧信息

la src					//==可视化调试源代码==
ctrl+x+a				//关闭可视化窗口

p 变量名		  		  //print 打印变量的值
p/x 变量名		  		  //16进制打印变量的值

#单步调试
n						//单条语句执行 (不进入函数内部)
s						//单条语句执行 (会进入函数内部)
finish					//跳出函数 (函数完整执行后返回)

回车键					  //重复执行上一条命令
c						//进入断点后,继续运行,直到遇到下一个断点会暂停

3.打数据断点(watch)

要先启动程序,找个合适的地方让程序暂停运行,然后就可以使用watch命令来设置观察对象(变量或表达式)了

通过watch设置的观察点对象或表达式遵循作用域规则。当程序运行的范围,超出要监控的变量的作用域时, 设置的观察点也会随之删除。

#监控变量
watch a[5]				//设置监控对象(变量或表达式),==发生变化时== 会中断
rwatch num				//当要观察的变量num ==被读时== 会中断
awatch num          	//当要观察的变量num ==被读或被写== 会中断
info watchpoints    	//查看当前设置的所有观察点

#监控地址
p &sum 					//打印变量的地址
watch *0x7fffffffdaa0   //监控这个地址的写操作

注意:

  • 当监控的变量(表达式)为局部变量(表达式)时,一旦局部变量(表达式)失效,则监控操作也随即失效;
  • 如果监控的是一个指针变量(例如 *p),则 watch *pwatch p 是有区别的,前者监控的是 p 所指数据的变化情况,而后者监控的是 p 指针本身有没有改变指向;
  • 这 3 个监控命令还可以用于监控数组中元素值的变化情况,例如对于 a[10] 这个数组,watch a 表示只要 a 数组中存储的数据发生改变,程序就会停止执行。

4.gdb调试golang

gdb是linux系统自带的调试器,它不仅支持C/C++调试,也支持GO程序调试。

配置gdb

#打开gdb初始化配置文件 
vim ~/.gdbinit 

#增加一行,:wq!保存后退出 (通过 go env查看$GOROOT,替换它)
add-auto-load-safe-path $GOROOT/src/runtime/runtime-gdb.py

编译时打开调试功能

 go build -gcflags "-N -l" main.go

gdb调试

使用gdb启动go程序

gdb main
go程序专门使用的命令
info goroutines 		// 查看 goroutines 信息
goroutine 1 bt 			// 查看指定序号的 goroutine 调用堆栈

5.rust-gdb调试rust

编译时打开调试功能

cargo build 默认会以 debug 模式进行构建,所以含有用于调试的 symbol,需要注意的是 cargo install 会以 release 模式构建,需要 cargo install --debug

rust-gdb调试

rust-gdb target/debug/xxx
rust程序专门使用的命令
info args				//查看局部变量
frame					//相当于where

往期精彩回顾:
区块链知识系列
密码学系列
零知识证明系列
共识系列
公链调研系列
比特币系列
以太坊系列
EOS系列
Filecoin系列
联盟链系列
Fabric系列
智能合约系列
Token系列

猜你喜欢

转载自blog.csdn.net/wcc19840827/article/details/124944555