Linux开发工具 —— 调试器gdb
五、Linux调试器 —— gdb使用
1、背景
这里我们对以下代码不理解,需要调试:
对我们编译好的可执行程序 mytest 进行 gdb:
这是因为 Linux 中默认生成的可执行程序是 release 版本的, 如果需要 debug 版本,就得加上 -g 选项:
Linux 中生成的可执行程序,它的二进制的格式是 elf 的,readelf 可以读取内部的格式:
我们可以使用选项 -S 查看可执行程序的分段情况:
gdb 调试 debug 版本:
- 在 C语言阶段我们就了解过了程序的发布方式有两种,debug 模式和 release 模式
- Linux gcc/g++ 出来的二进制程序,默认是 release 模式
- 要使用 gdb 调试,必须在源代码生成二进制程序的时候,加上 -g 选项
一个项目的开发流程 ❓
注意对于上图中的测试来说严格来说并不是测开,如果产品迭代更新,bug 修复等,严格来说就得重新测试,包括上代产品测试过的,这样成本较高,所以就诞生了很多自动化测试的开发需求,这就是测开,所以一般这里成本较低的一些脚本语言做的,如 python。
2、开始使用
ctrl + d/D 或 quit/q:退出调试
list/l 行号(, 行号):显示 binFile 源代码,显示的是当前行号周围的代码,可以利用另一个行号来指定一段区间
list/l 函数名:列出某个函数的源代码
r 或 run:运行程序
n 或 next:单条执行
s 或 step:进入函数调用
break(b) 行号:在某一行设置断点
break 函数名:在某个函数开头设置断点
info break/i b:查看断点信息
finish:执行到当前函数返回,然后停下等待命令
print(p):打印表达式的值,通过表达式可以修改变量的值或调用函数,类似于 p
p/P 变量:打印变量值
set var:修改变量的值
continue 或 c:从当前位置开始连续而非单步执行程序
delete breakpoints/d 或 d:删除所有断点
delete breakpoints n 或 d n:删除序号为 n 的断点
enable (breakpoints) 序号:启用断点,默认全启
disable 序号:禁用断点,默认全禁
display 变量名:跟踪查看一个变量,每次停下来都显示它的值
undisplay:取消对先前设置的那些变量的跟踪
until X 行号:跳至 X 行
breaktrace 或 bt:查看各级函数调用及参数
info (i) locals:查看当前栈帧局部变量的值
quit:退出 gdb
调试代码(入门) ❗
-
l + 行号(, 行号),显示的是当前行号周围的代码,按回车继续往下显示,直到全部显示完
-
b + 行号,打断点
-
i + b,查看断点
-
r,运行程序(调试)
-
n,单步执行,继续执行可按 n/Enter(gdb 可以记录历史执行的命令)
-
p + 变量,查看变量(监视),当循环往下走时,它不会变化,所以它用于查看一次
-
display + 变量,跟踪查看一个变量,每次停下来都显示它的值
- undisplay + 变量序号,取消对先前设置的那些变量的跟踪
- c,循环还没走完,想直接跳出循环到下一个断点处(因为我已经确定这个循环是对的)
- 结束调试,使用 ctrl + d 或 quit,退出调试
调试代码(进阶),主要演示剩余的指令 ❗
- 设置断点
- d n,删除序号为 n 的断点;d,删除所有断点
注意如果删除断点,下一次再加断点,它的 Num 是递增的,除非把 gdb 退出
- 设置了 17 行和 24 行的断点,并 r,接着 n 往下走执行 scanf
注意空行会直接跳过
-
这里我们想进入函数内部,先试用 n
发现它并没有进入,说明 n 是逐过程执行
-
重新调试可以再 r
-
这里想进入函数内部可以使用逐语句命令 s
-
bt,查看调用堆栈
-
a)现在在 Sum 内的循环里,想跳出循环到 return,Sum 里没断点,不能用 c
until 行号,跳转到指定行号
b)现在在 Sum 内的循环里,想跳出到 20 行等待,除了使用 until 外,更规范的的还可以使用 finish,执行到当前函数返回,然后停下等待命令,注意不能 finish main 函数
c)现在在 Sum 内的循环里,想跳到下一个断点处可以直接 c
![在这里插入图片描述](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/40509695ebe1480991d0fc6133eaba37~tplv-k3u1fbpfcp-zoom-1.image)
-
disable (序号),断点禁用,默认是全禁;
enable breakpoints (序号),断点启用,默认是全启
-
如果在循环里有 100 次循环,想将循环跑到第 80 次可以 set var
📝 小结
最后想必很多同学会觉得 gdb 相比 VS 的调试成本就高的多,其实那是 gdb 用的不熟练导致的,如果熟练了其实可以说它俩的效率是等价的
实际对于 gdb,在往后的编程中用的不多,不用则已,一用惊人,所以还是得了解的。
3、理解
相信大家对 Visual Studio 2017 已经不陌生了,这里为了方便记忆,可以对应 VS 的操作来进行理解记忆
b 行号 ↔ F9
r ↔ F5
c ↔ F5
n ↔ F10
s ↔ F11
q ↔ shift + F5
- 点赞
- 收藏
- 关注作者
评论(0)