GDB Introduction
GDB基本用法
C语言编译选项
GCC将C代码编译成可执行程序,会执行预处理、编译、汇编和链接四个步骤。预处理包含头文件,替换宏定义。编译是由C代码生成汇编程序。汇编则是将汇编程序转换为目标二进制文件。链接是把目标文件和库链接在一起,生成一个可以运行的程序。
常用选项如下所示。
- -E
- 预处理之后就停下来,不执行编译
- -S
- 编译之后就停下来,不执行汇编
- -c
- 编译之后停下来,不执行链接
- -o FILE
- 指定输出文件
- -M
- 输出依赖关系,包含系统头文件
- -MM
- 输出依赖关系,不包含系统头文件
- -MF FILE
- 指定文件,用于保存输出依赖关系
- -I
- 指定头文件搜索路径
- -L
- 指定库文件搜索路径
- -lLIBNAME
- 指定链接库
- -g
- 产生调试信息,用GDB调试时需要开启该选项
- -On
- 指定代码优化级别,数字越大优化越大
- -D NAME=VALUE
- 预定义一个宏
- -static
- 禁止链接动态库
- -shared
- 生成共享对象,一般需要开启
-fPIC
选项
基本操作
这里介绍设置断点、单步执行、查看状态、改变状态这几个功能。
在使用gdb功能之前,需要用gdb启动程序,启动方法如下所示。
gdb --args prog arg1 arg2... gdb prog core gdb prog <pid> gdb -x scripts.gdb
设置断点
b LINE|FUNC|-NLINE|+NLINE # 指定暂停函数、行号、行号偏移量 b FILE:LINE|FILE:FUNC # 有多个源文件时的定位方法 b *ADDR # 运行到指定内存地址处暂停 b ARGS if CONDITION # 指定暂停的条件 clear # 清除所有停止点 clear LINE|FUNC # 清除停止行、函数 d(delete) BPS # 删除断点 dis(disable) BPS # 关闭断点 en(enable) BPS # 开启断点 condition BP [EXPR] # 满足表达式才在断点处暂停 ignore BP N # 忽略断点N次
分步执行
r(run) ARGS # 运行程序 c(continue) # 继续执行 s(step) # 进入子函数:step into n(next) # 越过子函数:step over fin(finish) # 跳出子函数:step out u(until) LINE # 跳出循环:step over q(quit) # 退出调试
查看信息
常用设置查看的信息:
i b # 查看已设置断点信息 i f # 查看当前栈的详细信息 i display # 查看设置的display信息 i args # 当前函数的参数和值 i locals # 显示局部变量和值 i catch # 函数中的异常处理信息 i line LINE|FUNC # 查看运行时内存地址 i registers # 查看寄存器 i all-registers # 查看所有寄存器
常用状态查看的信息:
h(help) KEY # 查看帮助信息 bt(backtrace) [N] # 查看程序调用栈 l(list) [-|LINE|FUNC] # 查看代码,减号用于显示前面10行 f(frame) [N] # 查看指定栈信息,参数用于切换栈并显示 p(print)/F EXPR # 查看表达式的值,可以打印寄存器 p *arr@len # int *arr = malloc(len * sizeof(int)); x/NFU ADDR # 按照指定格式解析内存地址 display/F EXPR # 暂停后自动显示值 display/i $pc # 暂停时显示当前指令 undisplay DNUM # 清除暂停显示 dis display DNUM # 关闭暂停显示 en display DNUM # 开启暂停显示 watch VAR # 变量被改变时暂停 disassemble FUNC # 查看函数的汇编代码
更改状态
set args ARGS # 设置程序启动参数,show args查看 set env VAR=EXPR # 设置环境变量,show env查看 set var VAR=EXPR # 设置变量的值 signal SIGNAL # 向程序发送信号
多线程调试
info thread # 查看当前进程的线程 info threads # 显示所有可调试线程 thread TID # 切换调试线程 break LINE thread all # 为所有线程设置断点 thread apply TID... command # 让多个线程执行给定命令 set scheduler-locking off|on|step off # 不锁定任何线程 on # 只有当前被调试线程会执行 step # 单步的时候只有当前线程执行