什么是GDB调试?
GDB 全称“GNU symbolic debugger”,从名称上不难看出,它诞生于 GNU 计划(同时诞生的还有 GCC、Emacs 等),是 Linux 下常用的程序调试器。发展至今,GDB 已经迭代了诸多个版本,当下的 GDB 支持调试多种编程语言编写的程序,包括 C、C++、Go、Objective-C、OpenCL、Ada 等。实际场景中,GDB 更常用来调试 C 和 C++ 程序。
GDB调试有什么作用?
a) 启动你的程序,可以按照你的自定义的要求随心所欲的运行程序。
b) 在某个指定的地方或条件下暂停程序。
c) 当程序被停住时,可以检查此时你的程序中所发生的事。
d) 在程序执行过程中修改程序中的变量或条件,将一个bug产生的影响修正从而测试其他bug。
使用GDB调试注意事项
1.要使用GDB调试某个程序,该程序编译时必须加上编译选项 -g,否则该程序是不包含调试信息的;
2.GCC编译器支持 -O 和 -g 一起参与编译。GCC编译过程对进行优化的程度可分为5个等级,分别为 :
-O/-O0: 不做任何优化,这是默认的编译选项 ;
-O1:使用能减少目标文件大小以及执行时间并且不会使编译时间明显增加的优化。 该模式在编译大型程序的时候会花费更多的时间和内存。在 -O1下:编译会尝试减少代 码体积和代码运行时间,但是并不执行会花费大量时间的优化操作。
-O2:包含 -O1的优化并增加了不需要在目标文件大小和执行速度上进行折衷的优化。 GCC执行几乎所有支持的操作但不包括空间和速度之间权衡的优化,编译器不执行循环 展开以及函数内联。这是推荐的优化等级,除非你有特殊的需求。 -O2会比 -O1启用多 一些标记。与 -O1比较该优化 -O2将会花费更多的编译时间当然也会生成性能更好的代 码。
-O3:打开所有 -O2的优化选项并且增加 -finline-functions, -funswitch-loops,-fpredictive-commoning, -fgcse-after-reload and -ftree-vectorize优化选项。这是最高最危险 的优化等级。用这个选项会延长编译代码的时间,并且在使用 gcc4.x的系统里不应全局 启用。自从 3.x版本以来 gcc的行为已经有了极大地改变。在 3.x,,-O3生成的代码也只 是比 -O2快一点点而已,而 gcc4.x中还未必更快。用 -O3来编译所有的 软件包将产生更 大体积更耗内存的二进制文件,大大增加编译失败的机会或不可预知的程序行为(包括 错误)。这样做将得不偿失,记住过犹不及。在 gcc 4.x.中使用 -O3是不推荐的。
-Os:专门优化目标文件大小 ,执行所有的不增加目标文件大小的 -O2优化选项。同时 -Os还会执行更加优化程序空间的选项。这对于磁盘空间极其紧张或者 CPU缓存较小的 机器非常有用。但也可能产生些许问题,因此软件树中的大部分 ebuild都过滤掉这个等 级的优化。使用 -Os是不推荐的。
GDB调试指令
0.启动gdb调试
gdb filename : 启动未启动程序进行调试(需要run)
gdb attach pid:对已经启动的程序调试, detach让gdb调试器与程序分离
gdb corename: 调试core文件
ulimit -c查看core文件生成功能是否开始(ulimit -a查看ulimit其他功能参数)
在/proc/sys/kernel/core_uses_pid内控制core文件的文件名是否加入pid作为扩展,若添加,文件内容为1,否则0
1.run -> r
gdb filename只是attach到一个调试文件,run启动程序
ctrl+c中断后,run重启
2.continue -> c
ctrl +c中断后,使用continue让程序继续运行,会在断点处中断
3.break -> b
添加永久断点, 可以接行数(一般是list出的代码对应的行数) 或者 函数名
4.tbreak
临时断点,重启程序后消失
5.backtrace -> bt
查看当前线程的调用堆栈
6.frame -> f
与backtrace结合使用,切换不同堆栈
7.info break -> info b
查看设置的断点信息
disable 断点编号 : 禁用断点编号对应断点
enable 断点编号 : 重新开启对应断点
delete 断点编号 : 删除对应断点
如果上述不加断点编号 => 禁用/启用/删除 所有断点
8.list -> l
list + : 当前位置向结尾10行
list - : 当前位置向上10行
9.print -> p
查看变量的值,或者 修改内存中的变量值
可以p func() 得到函数执行结果
可指定输出格式p /format var 如十六进制显示var p /x var
ptype : 输出变量类型
10.info threads
查看当前进程的所有线程的运行情况。*号表示当前gdb作用在哪一个线程
thread 切换不同线程
11.info args
查看当前函数的参数值
12.next -> n
单步步过,遇到函数调用直接跳过,不会执行
13.step -> s
单步步入 遇到函数调用会进入函数内部
14.finish
直接执行完当前函数,返回调用处
15.return
直接结束当前函数,返回调用处(可以指定返回值)
16.until -> u
快速执行并跳到指定行
17.jump
可以跳到指定行或函数,中间的被略过,如果指定位置没有断点,继续执行
18.disassemble
输出当前函数的汇编指令
默认为AT&T格式,set disassembly-flavor intel更改为intel汇编格式
19.set args
在gdb attach之后,run之前,使用set args 指定被调试程序的命令行参数(多个参数用""括住,空格隔开), show args 查看当前设置的命令行参数
20.watch
监视一个变量活着一段内存, 当发生变化时,gdb就会中断.
21.display
监视变量或者内存的值,每次gdb中断,就自动输出这些值
info display查看当前已经监视了哪些值
delete display 编号 : 移除对指定变量的监视
22.多线程调试:
set scheduler-locking on : 锁定当前线程,其他线程暂停运行
set scheduler-locking step: 锁定next、step操作目标为当前线程
set scheduler-locking off : 取消锁定