【Linux】Linux调试器----gdb/cgdb
目录
- 前言
- 一、debug和release
- 二、gdb/cgdb的使用
- 1. 启动bdg/cgdb
- 2. 退出
- 3. 代码查看(list/l)
- 4. 运行程序(r)
- 5. 设置断点
- 6. 查看断点
- 7. 删除断点
- 8. 禁用/启动断点
- 9. 逐语句/逐过程
- 10. 查看变量
- 11. 运行到指定行
- 12. 执行到函数返回
- 13. 从断点处运行到下一个断点
- 三、gdb/cgdb调试技巧
- 1. watch
- 2. set var
- 3. 条件断点
前言
【Linux】自动化构建–make/Makefile详情请点击,今天继续介绍【Linux】Linux调试器----gdb/cgdb
一、debug和release
在Linux中编译器(gcc/g++)默认生成的可执行文件是release版本的(无调试信息),无法调试
如果想要使用gdb/cgdb来调试代码,必须要使用debug(包含调试信息)版本,gcc/g++默认是生成release版本,我们使用
gcc -o test-debug test.c -g
指令来指定生成debug版本的可执行程序由于debug版本在可执行性程序内部添加了调试信息,因此debug版本比release版本所占空间大
可执行程序不仅仅是二进制文件,它的内部是有固定格式的,指令:
readelf -S 可执行文件名
,查看可执行文件的格式(ELF格式),我们还可以借助管道和grep对二进制格式信息进行搜索,-i :表示忽略大小写查找
由于默认是生成release版本,所以test中无调试信息,没有debug信息,test-debug是debug版本,所以查找到了debug相关信息
二、gdb/cgdb的使用
cgbd 类似于是gdb 的“现代化”终端界面,拥有了图形化界面,因此建议新手先使用cgbd调试,熟练掌握相关指令和操作后再使用gdb,这里使用cgdb做演示
1. 启动bdg/cgdb
bdg/cgdb 可执行文件名
:启动bdg/cgdb
- 使用cgdb会直接进入两个窗口的页面,上面窗口是代码,下面窗口是cbdg指令区,这样调试的时候能看到代码以及调试进度
2. 退出
- quit/q退出gdb/cgdb
3. 代码查看(list/l)
l n
:会打印上下共n行代码,gdb会记录最近一次的命令,如果超查看完整代码,可以输入命令:l 0
再不停的按回车键即可将全部代码内容显示
l 函数名
:查看函数代码
4. 运行程序(r)
- r:从程序开始连续执行,如果有断点执行到第一个断点处,如果没有断点,执行到程序结束
5. 设置断点
- b n:表示再第n行设置断点
- b 文件名:行号,表示在文件行号为n的位置打断点
- b 函数名:在函数开头设置断点
使用gdb并不能很直观的看到断点的设置,我们使用cgdb来查看断点设置后的效果
- 我们可以看到,20行设置断点后,20行行标数字20变成红色
- 在20行打下断点,使用r指令运行程序
6. 查看断点
info b:查看断点信息,根据断点设置的先后顺序编号
7. 删除断点
d n:n表示断点序号(不是行号)
8. 禁用/启动断点
- disable n:n代表断点序号,禁用断点
- enable n:n代表断点序号,启动断点
9. 逐语句/逐过程
逐语句:进入函数
逐过程:把函数当成一个整体语句(不进入函数里面)
- vs中,逐过程F10,逐语句F11
- cdgb中,
逐过程 n(next)
,逐语句 s(step)
逐过程 n(next)
逐语句 s(step)
10. 查看变量
- p 变量:调试过程中,查看变量的值并将其打印出来
- 用p命令每次调试的时候都必须要
p 变量
才会打印变量值,有什么办法能在调试的时候直接显示查看变量的值吗? - 使用display 变量跟踪显示变量,类似于vs中的监视窗口
- 取消对变量的跟踪显示使用指令:undisplay 编号(不能使用变量名)
11. 运行到指定行
在函数中如果有一个循环语句,我们想直接一步运行完这个循环语句(这个区域的代码),使用指令:until 行号:直接运行到该行号位置
12. 执行到函数返回
finish指令:直接执行完该函数
13. 从断点处运行到下一个断点
指令:c,从当前位置运行到下一个断点处
注意:调试步骤
- 首先使用
until && finish && c
来大致缩小错误程序的范围- 再使用
逐语句(s)、逐过程(n)
来确定具体错误代码
三、gdb/cgdb调试技巧
1. watch
- 执行时监视⼀个表达式(如变量)的值。如果监视的表达式在程序运行期间的值发生变化,gdb会暂停程序的执行
- 其本质也是一个断点,只不过该断点生效的条件是watch的变量的值发生变化才会触发
- 如果你有⼀些变量不应该修改,但是你怀疑它修改导致了问题,你可以watch它,如果变化了,就会通知你(监视变量的变化)
2. set var
- set var 变量名:在debug过程中,修改变量的值(在我们知道问题代码是某个变量影响导致的,直接在gdb/cgdb中修改,如果修改后代码没问题,那么就能直接确定问题)
3. 条件断点
- 条件断点命令:b 行号 if 断点触发条件
- 条件断点其本质也是断点,只不过要触发条件之后才生效
- 将已存在的断点(普通)改为条件断点
使用指令:condition 普通断点的序号 条件