gdb
2023-12-26 09:23:57 2 举报
AI智能生成
gdb调试
作者其他创作
大纲/内容
加载符号表
-s file
file为指定执行文件
-e file
从file加载符号表,并且file作为指定执行程序
-se file
加载指定core-dump文件(gdb [可执行程序] [core-dump文件])
-c file
从file执行GDB命令
-x file
选择文件
在使用gdb调试过程中,如果想将调试过程保存,可开启gdb日志功能
set logging 【on|off】
开启/关闭日志
set logging file 【path】
设置日志保存路径
on:覆盖
off:追加
set logging overwrite 【on|off】
日志写入模式
on:重定向到日志文件
off:终端
set logging redirect 【on|off】
日志输出
show logging
查看当前日志设置
日志输入
shell command string
shell命令
set args [para1] [para2]...[para3]
run [para1] [para2]...[para3]
程序传参
GDB运行程序
info thread
查看所有线程
id:gdb线程编号
thread 【id】
切换线程
ids:线程编号,all:所有线程
thread apply [ids] [command]
在多个线程上执行相同的命令
默认开启
分支主题
set print thread-events on
开启消息打印
set print thread-events off
关闭消息打印
show print thread-events
查看消息打印状态
new thread / thread exited消息打印
多线程调试
在项目调试过程遇到的问题:gdb在调试时收到内核终端信号时,gbd会停下来
停止调试
stop
不停止
nostop
打印
print
不打印
noprint
处理信号
pass
不处理信号
nopass
action
handle 【signal】 【action】
handle 【signal】
不停止,打印信号信息,执行信号处理函数
eg:
查看信号状态
收到内核中断信号,处理信号
信号屏蔽
作用:保存程序当前状态的一个快照
解决:在调试的时候不经意间跳过关键行。在关键行前设置书签,当调试执行过关键行后,可以回到书签位置
本质:gdb 会把时钟回拨到检查点所记录的时间,所有程序变量,寄存器,栈帧等等都恢复到检查点上保存的状态
不会撤销已写入文件的数据,但是会把文件指针指向以前的位置
不会将外设的数据收回
注意
checkpoint
保存当前执行快照
restart 【id】
恢复快照
info checkpoints
列出所有检查点
delete checkpoint 【id】
删除快照点
书签
break 【】
程序在控制返回到帧的时候立即中断,但不留下断点
finish
修改断点条件
condition [bnum] [exp]
cond为真中断
break … if cond
命中一次后删除
tbreak 【】
硬件断点,需要硬件的支持(没有用过)
hbreak 【】
正则断点,所有匹配正则表达式 regex 的函数上设置断点
rbreak 【regex】
查看断点信息
info breakpoints
忽略id断点count次
ignore 【id】 【count】
设置断点
软件观察点:所谓软件观点(software watchpoint),即用 watch 命令监控目标变量(表达式)后,GDB 调试器会以单步执行的方式运行程序,并且每行代码执行完毕后,都会检测该目标变量(表达式)的值是否发生改变,如果改变则程序执行停止。可想而知,设置软件观察点的方式,一定程度上会影响程序的执行效率。但从另一个角度看,调试程序的目的并非是为了获得运行结果,而是查找导致程序异常或 Bug 的代码,因此即便软件观察点会影响执行效率,一定程度上也是可以接受的。
Hardware watchpoint num: Could not insert watchpoint
注意:基于寄存器个数的限制,如果调试环境中设立的硬件观察点太多,则有些可能会失去作用,这种情况下,gdb 调试器会发出如下警告:
硬件观察点:所谓硬件观察点(Hardware watchpoint),和前者最大的不同是,它在实现监控机制的同时不影响程序的执行效率。简单的理解,系统会为 gdb 调试器提供少量的寄存器(例如, 32 位的 Intel x86 处理器提供有 4 个调试寄存器),每个寄存器都可以作为一个观察点协助 gdb调试器完成监控任务。
注意:在执行此命令之前建立的硬件观察点,不会受此命令的影响。awatch 命令和 rwatch 命令只能设置硬件观察点,如果系统不支持或者借助如上命令禁用,则 GDB 调试器会打印如下信息:Expression cannot be implemented with read/access watchpoint.
0:软件监视点
1:硬件监视点
set can-use-hw-watchpoints [0/1]
设置是否启动硬件监视点
show can-use-hw-watchpoints
查看监视点类型
硬件监视点
watch [expr] [thread id]
值改变
rwatch [expr] [thread id]
读
awatch [expr] [thread id]
读写
监视点
设置监视点(https://blog.csdn.net/wojiaxiaohuang2014/article/details/127571038)
设置捕获点
clear
delete
删除断点
enable
disable
禁用/激活断点
当断点命中后,执行一些列命令
commands [bnum]… command-list …end
断点1命中后,打印x = [x],然后继续执行。程序不会因此停下来
eg:commands 1printf\"x = %d\\
断点命令列表
continue [ignore-count]
fg [ignore-count]
单步执行
step
继续向下单步执行count行
step 【count】
next
next [count]
step 命令在没有调试行信息的函数的入口点中断,而不是越过这个函数
set step-mode [on/off]
和next类似,不同点在于快速运行完当前的循环体,并运行至循环体外停止。
until
执行至指定位置后停止
until [location]
advance [location]
nexti
stepi
继续和单步
中断和继续
where和info stack等同于bt
打印整个堆栈的回溯
backtrace
打印n层栈帧,n:栈顶往下数;-n:栈底往上数
bt [n/-n]
打印每个栈帧的局部变量
bt full
回溯
thread apply all backtrace
查看所有线程的调用栈
set backtrace past-main 【on/off]
show backtrace past-main
显示main函数调用堆栈
set backtrace past-entry [on/off]
show backtrace past-entry
显示用户入口点调用堆栈
0:不限制
set backtrace limit [n/0]
show backtrace limit
调用栈层数
切换栈帧
frame [id]
堆栈里上移 n 帧
up 【n】
堆栈里下移 n 帧
down [n]
选择栈帧
查看帧信息
info frame
查看id栈帧信息,但是不切换栈帧
info frame [id]
查看选定帧参数
info args
查看栈帧本地变量
info locals
帧信息
调用栈
行号为中心显示listsize行
list [行号]
函数名为中心显示listsize行
list [function]
设置list显示count行源码
set listsize [count]
打印first到last
打印到last行
从first行开始打印
只打印最近打印行后的代码
list +
只打印最近打印行前的代码
list -
指定文件显示以行号为中心显示
list filename:[行号]
指定文件显示以函数名为中心显示
list filename:[funtion]
查看
edit
编辑
查找
指定源文件
disassemble
反汇编
源文件
概念:打印内存中连续相同类型的对象
目标值:数组的一个元素,并且是一个单独的对象
长度:打印长度
用法:p [目标值]@[长度]
伪数组
p/[FMT]
x 将数值作为整型数据,并以 16 进制打印。d 打印带符号整型数据u 打印以无符号整型数据o 以 8 进制打印整形数据t 以 2 进制打印整形。’t'代表’two’a 打印地址,打印 16 进制的绝对地址和最近符号的偏移量c 将一个整型以字符常量打印。会打印一个数值和它表示的字符。超出 7 位的 ASCII 的数值(大于 127)的字符用 8 进制的数字替代打印f 将数据以浮点类型打印s 如果可能的话,以字符串形式打印
格式化输出
查看变量
n:查看多个单位大小的内容,默认值1
f:显示格式,同print格式,默认值x
b 字节h 2 节节w 4 字节。默认值。g 8 字节
u
x/[nfu] addr
查看内存
频繁需要观察一个表达式的值,将此表达式加入到列表中,当gdb中断时自动显示表达式的值
display [expr]
查看变量print
查看内存x
指定打印格式,两种指定方式
display/fmt [expr]
加入自动显示列表
info dispaly
打印列表
undisplay [id]
delete dispaly [id]
删除监视
disable/enable dispaly [id]
禁用/激活
display
打印当前列表的值
自动显示
set print address [on|off]
不/打印地址
show print address
显示是否打印地址
堆栈地址
set print array [on|off]
打印数组
set print array-indexs [on|off]
打印数组下标
0:没有长度限制
set print elements []
限制打印数组的长度
set print repeats
数组连续相同成员数量超过上限n,打印字符串\"\"
set print null-stop
char数组初次遇到NULL停止打印
数组
set print frame-arguments all
打印所有参数
set print frame-arguments scalars
只打印非向量参数,数组、结构体等用...代替
set print frame-arguments none
不打印参数
堆栈帧参数打印
set print pretty [on|off]
结构体缩进/紧凑打印
打印指针指向对象的真实类型而不是声明类型(多态)
set print object [on| off]
C++符号打印
打印设置
以print命令打印的值保存在GDB值历史里
答应对应id值
$[id]
打印最近的值
$
打印倒数第二近的值
$$
打印倒数num近的值
$$[num]
打印值历史最近的10个值
show values
打印n为中心10个记录
show values n
打印最近打印过的值前的10个值
show values +
值历史
打印所有寄存器名和值,除了浮点和向量寄存器
info registers
打印所有寄存器的名和值,包括浮点和向量寄存器
info all-registers
打印指定寄存的值
ifno register [regname...]
寄存器
在gdb中存储数据,在以后引用
定义
set $[name]=[value]
init-if-undefined $[name]=[name]
初始化,如果已经被定义过,则不使用初始化的值
$_
x命令最近查看的地址
$__
x命令最近查看地址上的值
$_exitcode
程序调试结束退出代码
惯用变量
dump [format] memory [filename] [start_addr] [end_addr]
dump [format] value [filename] expr
append [binary] memory [filename] [start_addr] [end_addr]
append [binary] value [filename] [expr]
bias:即将被载入到内存的地址号(相对调试程序)
start:加载文件数据起始位置
end:加载文件数据结束位置
将文件内容恢复到内存中
restore [filename] [binary] [bias] [start] [end]
内存和文件之间复制数据
generate-core-file [file]
gcore [file]
生成core文件
显示名为macro宏的定义,以及行号信息
info macro [macro]
将macro宏展开
macro expand [macro]
编译时需要添加编译参数
-gdwarf-2 -g3
预处理
gdb
0 条评论
回复 删除
下一页