gdb调试:一个简单的入门
本文最后更新于:2023年3月20日 下午
问题情景:运行下面程序,得到了错误输出,如何找出错误?
1 |
|
用以下命令得到可执行文件main,运行后发现输出了55、5105,这显然是错误的,因此需要调试
编译的时候需要加上-g选项以调试
1 |
|
-g选项的作用是在目标文件中加入源代码的信息,比如目标文件中第几条机器指令对应源代码的第几行
命令行输入gdb main进入调试,通过调试发现了下面的错误:
- 通过step步入add_range函数,发现前后两次调用函数中sum的值并没有都初始化为0(第二次调用add_range的时候sum的值为55)
gdb常用的命令
- list
- 输出源代码
- 默认从第一行开始列出十行
- 可简写为l
- list n 输出第n行前后的代码
- list function_name输出函数function_name前后的代码
- 提示符下直接敲回车表示重复上一条命令
- quit退出gdb
- run运行程序,当遇到断点后,程序会在断点处停止运行
- next往后执行一句代码
- backtrace查看函数调用的栈帧
- finish命令让程序一直运行到从当前函数返回为止
- p命令可以打印出某个变量的值,包括地址
- set var可以改变变量的值
- backtrace(或bt)查看各级函数调用及参数
- frame + 帧编号选择栈帧
- info(或i) locals查看当前栈帧局部变量的值
- display + 变量名 可以每次停下来的时候自动打印变量的值
- 用undisplay可以取消对先前设置的那些变量的跟踪
- info program: 来查看程序的是否在运行,进程号,被暂停的原因
断点调试
- break + 函数 可以在某个函数入口处设置断点
- break + 行号 可以在某一行停止
- info breakpoints列出所有断点,缩写:info b
- delete breakpoints删除断点
- disable/enable breakpoints禁用/启用断点
- 条件断点
- break 9 if sum != 0
- 如果sum!=0就在第九行打断点
- display + 变量名:跟踪查看一个变量,每次停下来都显示它的值
- undisplay取消对先前设置的那些变量的跟踪
- continue(或c)从当前位置开始连续而非单步执行程序,继续执行,到下一个断点处(或运行结束)
- run(或r)从头开始连续而非单步执行程序
观察点
- 断点是当程序执行到某一代码行时中断,而观察点是当程序访问某一存储单元时中断,如果我们不知道某一存储单元是在哪里被改动的,这时候观察点尤其有用
- 用watch命令设置观察点,
- i watchpoints 查看当前设置了哪些观察点
- x 从某个位置开始打印存储器的一段内容,全部当成字节来看,而不区分哪些字节属于哪些变量
- x/7b input
- x命令打印存储器中的内容
- 7b是打印格式
- b表示每个字节一组
- 7表示打印7组
分割窗口
- layout:用于分割窗口,可以一边查看代码,一边测试:
- layout src:显示源代码窗口
- layout asm:显示反汇编窗口
- layout regs:显示源代码/反汇编和CPU寄存器窗口
- layout split:显示源代码和反汇编窗口
- Ctrl + L:刷新窗口
带参数调试
gdb <prog>
之后,进入gdb界面,输入set args 123 abc xxx,则相当于给程序prog传入了三个参数123、abc、xxxgdb –args prog 123 abc xxx,相当于给程序prog传入了三个参数123、abc、xxx
在gdb界面下,show args命令可以查看传入的参数
gdb调试:一个简单的入门
http://gls.show/p/66ee2080/