在日常的c++代码编译或者运行过程中,使用gdb进行程序运行过程查看、程序突然终止问题定位是很有用的。此处总结到gdb一般就三种场景:
- 调用未启动程序:调试程序,查看程序变量值、调用过程等;
- 调用core文件,问题定位;
- 调用已经运行的程序;
1 查看可否调试
- 希望可调式的程序在编译时加上-g参数,但是可能程序不是自己开发的,那么就执行下面命令,如果打印了“no debugging symbols found”,就表示不可以被调试。
~$ gdb 程序文件名
- readelf命令查看程序的段信息
-$ readelf -S 程序文件名 | grep debug
# 输出一些带有debug字段的信息,有就是可调式
2 启动程序
先列举一些常用的命令,以后肯定要经常用:
2.1 调试未启动程序
- 指定程序
~$ gdb 程序文件名
- 如果启动带参数,则输入参数,注意是args
# 设置可执行程序的传参
(gdb) set args ...参数...
(gdb) run
2.2 调试core文件
程序core dump时,可能会产生core文件,不过系统可能会限制core文件的产生。
~$ ulimit -c # 输出core文件大小
block_num # block_num 最大大小,单位为块,一块默认为512字节,如果block_num = 0 表示系统不允许生成core文件
修改core文件大小
~$ ulimit -c unlimited 不限制core文件大小
~$ ulimit -c 10 设置最大大小
调式core文件
~$ gdb 程序文件名 core文件名
2.3 调试已经运行程序
- 找到正在运行的程序进程
ps -ef | grep 程序文件名
- 调试进程
~$ gdb
(gdb) attach 进程号
3 断点
1 设置断点
(gdb) b location
location | 含义 |
---|---|
filename:linenum | filename 表示源程序文件名;linenum 为整数,表示具体行数。整体的意思是在指令文件 filename 中的第 linenum 行打断点。 |
+ offset 或者 - offset | offset 为整数(假设值为 2),+offset 表示以当前程序暂停位置(例如第 4 行)为准,向后数 offset 行处(第 6 行)打断点;-offset 表示以当前程序暂停位置为准,向前数 offset 行处(第 2 行)打断点。 |
filename:function | filename 表示远程文件名;function 表示程序中函数的函数名。整体的意思是在指定文件 filename 中 function 函数的开头位置打断点。 |
2 查看断点
(gdb) info breakpoints
Num Type Disp Enb Address What
1 breakpoint keep y 0x00000000004004fa in main at buging.c:8
1.Num 列代表断点编号,该编号可以作为 delete/enalbe/disable 等控制断点命令的参数
2.Type 列代表断点类型,一般为 breakpoint
3.Disp 列代表断点被命中后,该断点保留(keep)、删除(del)还是关闭(dis)
4.Enb 列代表该断点是 enable(y) 还是 disable(n)
5.Address 列代表该断点处虚拟内存的地址
6.What 列代表该断点在源文件中的信息
3 删除断点
(gdb) d 1
4 暂时不使用断点
(gdb) disable 1