LINUX——调试器gdb/cgdb的使用
目录
引入
常见使用
watch(监视)
set var确定问题原因
条件断点
添加条件断点
给已经存在的断点新增条件
引入
样例代码
#include<stdio.h>int total(int s,int e){int result=0;int i=0; for(i=s;i<e;i++){result+=i;}return result;}int main(){int start=1;int end=100;int n=total(start,end);printf("result is %d\n",n);return 0;}
- 我们知道,程序的发布形式有两种,即:debug模式和release模式,linux下gcc/g++出来的二进制程序,默认是release模式。
- 要使用gdb调试,必须在源代码生成二进制程序的时候,加上-g选项,如果没有添加,程序就无法被编译。
常见使用
开始:gdb 文件名
退出:ctrl+d 或者 quit调试命令
命令(简写) | 作用 | 样例 |
---|---|---|
l | 显示源代码,从上次位置开始,每次列出10行 | ![]() |
l 函数名 | 列出指定函数的源代码 | ![]() |
l 行号 | 把这个行号以及周围的代码显示出来,一共10行,此行号在中间 | ![]() |
r/run | 从程序开始连续执行 | ![]() |
n/next | 单步执行,不进入函数内部,相当于vs2022的F10 | ![]() |
s/step | 单步执行,进入函数的内部,相当于vs2022的F11 | ![]() |
b/break 行号 | 在指定行号设置断点 | ![]() |
info b/break | 查看当前所有断点的信息 | ![]() |
finish | 执行到当前函数返回,然后停止 | ![]() |
p/print 表达式 | 打印表达式的值 | |
p/print 变量 | 打印变量的值 | |
set var 变量=值 | 修改变量的值 | |
c/continue | 从当前位置开始来连续执行程序 | |
d/delete breakpoints | 删除所有的断点 | ![]() |
d/delete breakpoints n | 删除序号为n的断点 | |
disable breakpoints | 禁⽤所有断点 | |
enable breakpoints | 启⽤所有断点 | |
info/i breakpoints | 查看当前设置的断点列表 | ![]() |
display 变量名 | 跟踪显⽰指定变量的值 | ![]() |
undisplay 编号 | 取消对指定编号的变量的跟踪显⽰ | ![]() |
until X ⾏号 | 执⾏到指定⾏号 | |
q/quit | 退出GDB调试器 | |
watch(监视)
执行时监视一个表达式的值。如果监视的表达式在程序运行期间的值发生变化,gdb会暂停程序的执行,并通知使用者。
- 如果有一些变量不应该修改,但是你怀疑它修改导致了问题,你可以watch它!
- 使用watch可以监视一个表达式在程序运行期间值的变化。
set var确定问题原因
#include<stdio.h>int total(int s,int e){int flag=0;//这里故意写错,模拟一下错误的场景int result=0;int i=0; for(i=s;i<e;i++){result+=i;}return result*flag;}int main(){int start=1;int end=100;int n=total(start,end);printf("result is %d\n",n);return 0;}
经过一系列的排查我们发现可能是return result*flag 这里出错了!
这是我们就可以使用set var更改flag的值,确认是不是它的问题!!
发现真的是它的问题,但是注意,我们的源代码并没有被改变!!这样更加方便,不用改变源代码,就可以改变flag的值进行试错。
条件断点
添加条件断点
b 行号 if x==xx
给已经存在的断点新增条件
condition 断点号 x==xx