Linux调试器-gdb
背景:
程序的发布方式有两种,debug模式和release模式
debug模式:可以被调试;
release模式:不可以被调试。
为什么需要debuy和release这两个模式呢?
答:程序员在开发的时候需要去调试代码,所以需要debuy模式,而用户一般不懂这些代码的调试不需要debuy模式,只需要快速的下载和安装,所以release把调试信息的部分去掉了,体积也得到了减小,更适合给用户使用(测试环节也是使用release模式)。
Linux gcc/g++出来的二进制程序,1.默认是release模式,2.默认是动态链接。
要使用gdb调试,必须在源代码生成二进制程序的时候, 加上 -g 选项(生成debug模式)。此时:我们还需要知道调试究竟是在干什么?
1.找到问题(查找、范围查找、局部逐行查找……)
2.解决问题(根据上下文代码逻辑)
实践:
首先:如果没有安装gdb:yum install -y gdb
要使用gdb调试,必须在源代码生成二进制程序的时候, 加上 -g 选项(生成debug模式),这里我们为了方便将执行放入到makefile中(自动构建)。
此时再写一个用于调试的程序:test.c
基于上面得到kezhix程序mytest后还可以查看可执行程序的格式:
readelf -S mytest | grep -i debuy
调试的指令:
命令 | 解析 |
ctrl + d 或 quit 调试命令 | gdb binFile 退出 |
list( l ) 行号 | 显示binFile源代码,接着上次的位置往下列,每次列10行。 |
list( l ) 函数名 | 列出某个函数的源代码。 |
run( r ) | 运行程序。 |
next( n ) | 单条执行。 |
step( s ) | 进入函数体调用 |
break(b) 行号 | 在某一行设置断点 |
break(b) 函数名 | 在某个函数开头设置断点 |
info break( b ) | 查看断点信息。 |
finish | 执行到当前函数返回,然后停下来等待命令 |
print( p ) | 打印表达式的值,通过表达式可以修改变量的值或者调用函数 |
p 变量 | 打印变量值(显示一次)。 |
set var | 修改变量的值 |
continue( c ) | 从当前位置开始连续而非单步执行程序 |
delete breakpoints | 删除所有断点 |
delete breakpoints n | 删除序号为n的断点 |
disable breakpoints | 禁用断点 |
enable breakpoints | 启用断点 |
info(或i) breakpoints | 参看当前设置了哪些断点 |
display 变量名 | 跟踪查看一个变量,每次停下来都显示它的值 |
undisplay 序号 | 取消对先前序号设置的那些变量的跟踪 |
until X行号 | 运行至X行 |
breaktrace(或bt) | 查看各级函数调用及参数 |
info( i ) locals | 查看当前栈帧局部变量的值 |
quit | 退出gdb |
调试指令的使用:
有了上面的基础,我们就可以来调试程序了:
list/l 行号:显示binFile源代码,接着上次的位置往下列,每次列10行。回车键实现下翻!
r或run:运行程序。相当于VS的F5!
break(b) 行号:在某一行设置断点,相当于VS的F9!
info break :查看断点信息。这里Linux引入了断点编号的概念,即:给断点设置编号,开启/关闭断点需要使用对应的断点编号!
delete breakpoints n:删除序号为n的断点
disable breakpoints:禁用断点
enable breakpoints:启用断点
n 或 next:单条执行。相当于VS的F10!
s或step:进入函数调用。相当于V的F11!
display 变量名:跟踪查看一个变量,每次停下来都显示它的值。
undisplay:取消对先前设置的那些变量的跟踪。
需要注意的是这里也使用了,序号的概念,取消跟踪需要输入对应的序号!
continue(或c):从当前位置开始连续而非单步执行程序,直接从一个断点到下一个断点。
breaktrace(或bt):查看各级函数调用及参数,现在所属调用的堆栈。
如下:在test.c的main()主函数的第22行!
finish:执行到当前函数返回,然后停下来等待命令。
需要注意:finish在主函数中使用是无效的,必须在调用的函数中使用才有效!
如下:因为在for循环设置了断点所以有一次的停留,回车后就直接运行到函数结束,并回到主函数的下一个断点!
until X行号:跳至X行.
需要注意:until跳转无法越过断点,还是会在断点停留,可以回车跳过断点。
set var name=value:修改一个变量的内容(不需要改代码,进行多分支测试!)
当我们在gdb(调试)时输入一条指令,是会自动记录最近一条指令的,所以我们想继续上一条指令操作时就可以<回车>来继续执行。
以上就是个人学习的见解和学习过程的解析,欢迎各位大佬在评论区探讨,交流!
如果本篇对你有帮助的话,三连支持一下吧。
感谢大佬们的三连! 感谢大佬们的三连! 感谢大佬们的三连!