gdb 常用命令

#gdb 基本使用

#1. 启动 gdb

  • 调试可执行文件:

    1
    gdb <可执行文件>
  • 调试正在运行的进程:

    1
    gdb -p <进程ID>
  • 调试 core 文件:

    1
    gdb <可执行文件> <core 文件>

#2. 设置调试环境

  • 查看动态库信息:

    1
    2
    info sharedlibrary
    info share
  • 设置动态库搜索路径:

    1
    2
    set sysroot <库文件根目录>  # 常用于交叉编译环境
    set solib-search-path <库文件目录>

    实际找动态库时会在 sysroot 下的 solib-search-path 中查找。

  • 设置断点时忽略动态库:

    1
    set breakpoint pending on
  • 设置分页显示:

    1
    set pagination on

#3. 基本控制流

  • runr:启动程序的执行。
  • start:从程序的入口点开始执行, 在 main 函数处暂停。
  • continuec:继续执行程序直到下一个断点。
  • finishfin:执行当前函数直到返回。
  • until <位置>:继续执行直到指定位置。
  • quitq:退出 gdb。

单步执行:

  • nextn:单步执行,不进入函数调用。
  • nextini:单步执行汇编指令,不进入函数调用。
  • steps:单步执行,进入函数调用。
  • stepisi:单步执行汇编指令,进入函数调用。

查看控制流状态:

  • backtracebt:显示当前调用栈。
  • frame <帧编号>f <帧编号>:切换到指定的栈帧。

多线程调试:

  • info threadsi t:列出所有线程。
  • thread <线程编号>t <线程编号>:切换到指定线程。
  • thread apply all <命令>:对所有线程执行指定命令。

#4. 断点和观察点

  • break <位置>b <位置>:设置断点。
  • break <位置> if <条件>b <位置> if <条件>:设置条件断点。
  • info breakpointsi b:列出所有断点。
  • delete <断点编号>d <断点编号>:删除指定断点。
  • enable <断点编号>en <断点编号>:启用指定断点。
  • disable <断点编号>dis <断点编号>:禁用指定断点。
  • clear <位置>:清除指定位置的断点。

观察点:

  • watch <变量名>w <变量名>:设置观察点,当变量的值发生变化时暂停程序。
  • rwatch <变量名>rw <变量名>:设置读观察点,当变量被读取时暂停程序。
  • awatch <变量名>aw <变量名>:设置读写观察点,当变量被读取或修改时暂停程序。
  • info watchpointsi w:列出所有观察点。
  • delete <观察点编号>d <观察点编号>:删除指定观察点。
  • disable <观察点编号>dis <观察点编号>:禁用指定观察点。
  • enable <观察点编号>en <观察点编号>:启用指定观察点。

#5. 变量和内存

  • print <变量名>p <变量名>:打印变量的值。
  • print <类型> <变量名>p <类型> <变量名>:以指定类型打印变量的值。
  • set <变量名> = <值>:修改变量的值。
  • examinex/<格式> <地址>:以指定格式查看内存内容。

查看变量信息:

  • info localsi l:显示当前栈帧的局部变量。
  • info argsi a:显示当前栈帧的函数参数。

命中断点时显示变量:

  • display <变量名>disp <变量名>:每次暂停时自动显示变量的值。
  • undisplay <显示编号>undisp <显示编号>:取消自动显示变量。

调整print命令的输出格式:

  • set print pretty <on|off>:启用漂亮打印。
  • set print elements <数量>:设置打印数组时的元素数量限制。

Examine命令的格式选项:

  • x/<数量><格式><大小> <地址>:查看内存内容。
    • <数量>:要查看的单元数。
    • <格式>:显示格式,如 x(十六进制)、d(十进制)、o(八进制)、t(二进制)、c(字符)、f(浮点数)。
    • <大小>:单元大小,如 b(字节)、h(双字节)、w(四字节)、g(八字节)。

#6. 源码导航

  • 设置源代码路径:

    1
    2
    3
    4
    5
    set directories <源代码目录>
    show directories

    # 对源码路径进行一个 replace(a, b) 操作
    set substitute-path <a> <b>
  • listl:显示当前执行位置的代码。

  • list <行号>l <行号>:显示指定行号附近的代码。

  • list <函数名>l <函数名>:显示指定函数的代码。

  • list <起始行号>,<结束行号>l <起始行号>,<结束行号>:显示指定范围的代码。

#7. 信号处理

  • info signalsi s:显示当前信号处理设置。
  • handle <信号> <stop|nostop> <print|noprint> <pass|nopass>:设置对指定信号的处理方式。
  • signal <信号>:向被调试程序发送指定信号。

#8. core dump

  • set core-file <文件名>:指定 core dump 文件用于调试。
  • generate-core-file <文件名>:生成 core dump 文件。

通过 kill -SIGSEGV <进程ID> 也可以让程序产生 core dump 文件

通过 gcore <进程ID> 也可以生成 core dump 文件

#9. 脚本和自动化

  • 启动 gdb 时执行初始命令:

    1
    2
    gdb -x <脚本文件> ...
    gdb -ex "<命令1>" -ex "<命令2>" ...
  • 执行初始命令后自动退出 gdb:

    1
    gdb --batch ...