普通断点:break命令
- break
//示例程序 #include<stdio.h> int main() { int num = 1; //4 while (num < 20) //5 { num *= 2; //7 } printf("num: %d",num); return 0; }
- 在第4行打断点:‘b 4’
- 在上述基础上在第六行打断点:‘b +2’
- num大于10在第七行打断点:
b 7 if num>10
- tbreak
-
- 与break命令用法相同,但tbreak断点用完一次之后就消失
-
- 上述程序用
b 7 if num>10
命令run之后会在每一次num大于时中断,tbreak 7 if num>10
只中断一次,continue程序直接执行到末尾
- 上述程序用
- rebreak
-
- rbreak命令打的断点会一直存在,是用于C、C++函数的中断命令
//示例程序 #include<stdio.h> void fun_1() { printf("one\n"); } void fun_2() { printf("second"); } int main(int argc,char* argv[]) { fun_1(); fun_2(); return 0; }
- 在所有fun格式函数前打断点:
rbreak fun
- 在所有fun格式函数前打断点:
- rbreak命令打的断点会一直存在,是用于C、C++函数的中断命令
观察断点:watch命令
使用 GDB 调试程序的过程中,借助观察断点可以监控程序中某个变量或者表达式的值,只要发生改变,程序就会停止执行
- 监控变量值变化:
watch num
num为变量名或表达式形如a+b - 查看当前观察点数量:
info watchpoints
- rwatch命令:只要程序中出现读取目标变量(表达式)的值的操作,程序就会停止运行
- awatch 命令:只要程序中出现读取目标变量(表达式)的值或者改变值的操作,程序就会停止运行
- watch命令:只有当被监控变量(表达式)的值发生改变,程序才会停止运行
捕捉断点:catch命令
- tcatch命令与catch命令:catch命令监控是永久的,tcatch命令只监控一次
//示例程序 #include <iostream> using namespace std; int main() { int num = 1; while(num <= 5) { try{ throw 100; //8 }catch(int e){ //9 num++; cout << "next" << endl; } } cout << "over" << endl; return 0; }
- 捕捉异常:
catch throw int
设置捕捉断点,run,up回到源码显示异常位置8 - 捕捉主程序catch异常:
catch catch int
,run or continue,up回到源码显示异常位置9 - ldd命令查看动态库的加载和卸载:
ldd main.exe
以查看libstdc++.so.6为例:catch load libstdc.so.6
- 捕捉异常:
条件断点:condition命令
- 只有当condition条件成立时,才执行断点
- break和watch可以直接用break … if …创建条件断点,捕捉断点catch要用condition
调试步骤://示例程序 #include <iostream> using namespace std; int main() { int num = 1; while(num<20) { try{ throw num; }catch(int &e){ num++; } } cout << num << endl; return 0; }
- 添加普通断点:
b 9
- 运行:
r
- 添加观察断点:
rwatch num
- 添加捕捉断点:
catch throw int
- 查看当前已设置断点:
info b
- 为普通断点添加条件表达式:
condition 1 num==3
- 为观察断点添加条件表达式:
condition 2 num==3
- 为捕捉断点添加条件表达式:
condition 3 num==3
- 添加普通断点:
- ignore命令:ignore 命令也可以使一个断点成为条件断点,但这里的“条件”并非自定义的表达式,而仅为一个整数,它用来表示该断点失效的次数。也就会说,ignore 命令可以使目标断点暂时失去作用,当断点失效的次数超过指定次数时,断点的功能会自动恢复.
使断点1失效3次:ignore 1 3
查看断点信息
- num:断点编号
- type:断点类型
- disp:是临时断点还是永久断点
- enb:断点是否启用
- address:断点地址
- what:断点位置、中断次数
禁用断点
- 禁用所有断点:
disable
- 禁用指定编号的断点(禁用编号为2的断点):
disable 2
- 激活所有断点:
enable
- 激活指定编号的断点(激活编号为2的断点):
enable 2
- 临时激活2号断点一次:
enable once 2
- 激活断点2一次之后永久删除:
enable delete 2
删除断点
- 删除指定位置的断点(删除第二行的断点):
clear 2
- 删除所有断点:
delete
- 删除指定编号的断点(删除编号为3的断点):
delete 2
单步调试
- next命令:在16行处设置断点,运行程序,执行两步(执行到18行):
n 2
- step命令与next区别:运行到子函数所在行执行step命令将进入子函数内部,而next命令则执行到主函数的下一行,不会进入子函数内部
- until命令:不带参数的 until 命令,可以使 GDB 调试器快速运行完当前的循环体,并运行至循环体外停止
- 执行到第九行结束:
until 9
或u 9
jump命令
- 直接跳转到指定行(19):
jump 19
finish命令与return命令
- 结束当前执行函数
- ==区别:finish 命令会执行函数到正常退出;return 命令是立即结束执行当前函数并返回,即使当前函数没有执行完也立即结束;finish命令不可以结束主函数,return函数可以
print命令
//示例程序
#include <stdio.h>
typedef struct student{
char *name;
}stu;
int num = 10;
int main(){
int num = 20;
int array[10]={1,2,3,4,5,6};
stu Wing = {"wing"};
return 0; //11
}
- 打印变量:
p num
- 修改变量值(修改num值为4):
p num=4
- 打印 name 指针的同时,输出其所在的内存地址:
print -address on --Wing.name
- 打印 name 指针的同时,不输出其所在的内存地址:
print -address off --Wing.name
- 以便于阅读的方式,输出结构体的值:‘print -pretty on – Wing’
- 以压缩的格式输出结构体的值:
print LanguageC
或print -pretty off -- Wing
- 以二进制输出num的值:
print/t num
- 从 array[1] 处开始,输出 array 数组中后续的 2 个元素的值:
print array[1]@2
- 输出局部变量num的值:
print num
- 输出全局变量num的值:
print 'main.c'::num
display命令
与print区别:使用 1 次 print 命令只能查看 1 次某个变量或表达式的值,而同样使用 1 次 display 命令,每次程序暂停执行时都会自动打印出目标变量或表达式的值
- 查看num值:
display num
- 查看自动显示列表中的变量:
info display
- 删除自动显示列表的变量(删除3号):
delete display 3
或者undisplay 3
- 禁用自动显示列表中的变量(禁用2号):
disable display 2
- 启用自动显示列表禁用的变量(启用2号):
enable display 2