GDB Notebook
利用 GDB 可以做四种主要的事情来帮助调试:
- 启动程序,指定参数
- 使程序在指定条件下停止
- 检查程序停止时发生了什么
- 更改程序中的内容
截至目前,GDB 15.1 支持的语言包括 Ada, Assembly, C, C++, D, Fortran, Go, Objective-C, OpenCL, Modula-2, Pascal ,Rust.
下面将介绍 GDB 调试的主要用法。
启动程序
编译文件时需要带上调试信息,对于 C++ 需要编译时带上 -g
参数,对于 Rust 需要编译
对于已经编译好的二进制文件,可以通过 readelf -S <program> | grep debug
检查是否带有调试段
调试未运行程序
通过 gdb <program>
来加载编译好的二进制文件,在 gdb
中 可以通过 run
或者 run <args>
进行运行,并选择是否携带参数。
此外还可以通过先 set args <args>
的方式,先设定参数,然后再 run
来运行
调试运行中程序
使用 ps -ef | grep <proc_name>
获得 pid,然后进入 gdb 后通过 attach <pid>
的方式进行调试
如果运行的程序没有调试信息,可以通过 file <program>
的形式加载symbols
断点
增加断点
在 gdb 中断点命令为 break
,可以通过以下方式增加断点:
- 根据行号:
b <filename>:<lineno>
注意这里文件名可以不需要写完整路径,gdb 可以自己推断 - 根据函数名:
b <funcname>
- 根据条件:
b <filename>:<lineno> if x==0
此外还有特殊断点:
- 正则断点:
rbreak <filename>:<regex>
可以通过正则的方式设置断点,例如rbreak <filename>:^print
设置以 print 开头的函数 - 临时断点:
tbreak
,只使用一次
操作断点
禁用或启用:
disable #禁用所有断点
disable bnum #禁用标号为bnum的断点
enable #启用所有断点
enable bnum #启用标号为bnum的断点
清除断点:
clear #删除当前行所有breakpoints
clear function #删除函数名为function处的断点
clear filename:function #删除文件filename中函数function处的断点
clear lineNum #删除行号为lineNum处的断点
clear f:lename:lineNum #删除文件filename中行号为lineNum处的断点
delete #删除所有breakpoints,watchpoints和catchpoints
delete bnum #删除断点号为bnum的断点
跳过断点:
通过 info breakpoints
拿到所有设置的断点,然后ignore <breakpointNum> <times>
可以多次跳过断点
变量查看
在 gdb 中通过 print
的方式来打印变量内容
打印格式1
print [_Expression_] print $[_Previous value number_] print {[_Type_]}[_Address_] print [_First element_]@[_Element count_] print /[_Format_] [_Expression_]
此处需要注意,Format 可以包含:
Format
- o - octal
- x - hexadecimal
- u - unsigned decimal
- t - binary
- f - floating point
- a - address
- c - char
- s - string
内存查看
x [_Address expression_] x /[_Format_] [_Address expression_] x /[_Length_][_Format_] [_Address expression_] x
Last modified on 2024-09-17