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