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                                # 单步的时候只有当前线程执行