Beej 的 GDB 快速入门指南

原文地址https://beej.us/guide/bggdb/

更多网址http://csapp.cs.cmu.edu/3e/students.html

这是一篇旨在帮助初学者快速上手 GNU 的调试器 gdb 的简陋说明。通常 gdb 由 IDE 运行执行,然而也有很多人基于各种原因并不喜欢 IDE,这篇指南正是为这批人准备。

有必要强调,这篇指南仅仅是入门教程,学习 gdb 远不止读读这里几行字。如果想要深入学习 gdb,不妨敲敲自己命令行的 man gdb,或者去参考下文提及的网络资源。

除了 “其它” 章节,这篇教程要求按序阅读。

编译

在编译时必须告诉编译器你要用 gdb,编译器才会在编译器运行调试。以下是 gcc 使用 gdb 的命令,加上 -g 选项:

Shell

1
2
$ gcc -g hello.c -o hello
$ g++ -g hello.cpp -o hello

之后,你就能在调试器中查看符号表等一系列信息了。

更多信息

请查看 官方 GDB 文档

此外推荐使用 DDD(Data Display Debugger)作为 gdb 前端。

启动调试器

首先记住:只要你的命令行有 (gdb) 提示,输入 help 就可以获取帮助,此外输入 quit 可以退出调试,回车 则重复上一次执行的命令。

gdb 有多种启动方式,这里只提及两种方法:

  1. 原生命令行启动

    使用 gdb 启动一个叫 hello 的程序:

    Stata

    1
    2
    3
    4
    5
    6
    7
    $ gdb hello
    (gdb) run
    Starting program: /home/beej/hello
    Hello, world!

    Program exited normally.
    (gdb)

    输入 rrun 来运行程序。

  2. 使用 TUI 模式

    使用 gdb -tui。这种模式下可以使用上下左右和翻页键操作源代码窗口。通过 list 命令可以指定文件路径或行号,例如:list hello.c:5

命令行参数

要向程序的 argv 传递参数,在 run 的时候作为参数传入:

Shell

1
2
(gdb) run arg1 arg2
Starting program: /home/beej/hello arg1 arg2

断点

在运行 run 前,你需要在想中断的地方设置断点。使用 breakb 命令:

命令 说明
break main 在 main() 函数的开始处中断
break 5 在当前文件的第 5 行中断
break hello.c:5 在 hello.c 的第 5 行中断

管理断点:

  • 查看断点info breakpoints (或 i b)
  • 清空断点clear [位置]
  • 删除断点delete [断点编号]
  • 禁用/启用disable [编号]enable [编号]

步进

  • next (n):步过 (Step Over)。执行下一条语句,如果是函数调用,会直接执行完该函数。
  • step (s):步进 (Step Into)。进入函数内部一行行执行。
  • continue (c):继续运行直到下一个断点。
  • CTRL-C:程序运行中按此键可强制暂停并返回 gdb 提示符。
  • 回车键:重复执行上一条命令。

检查变量

  • display [变量名]:每次步进都会显示该变量的值。
    • info display:查看显示列表。
    • undisplay [编号]:取消显示。
  • print (p):一次性打印变量值。
  • printf:格式化输出,例如 printf "%08X\n", i

其它

堆栈操作

  • backtrace (bt):显示当前函数调用堆栈。

其它步进方式

  • finish:退出当前函数并返回调用者。
  • stepi:步进单条汇编指令。
  • advance [位置]:继续运行直到到达指定位置。

修改变量

  • set variable [赋值表达式]:运行时修改变量值。例如 set (i = 20)

硬件监测点 (Watchpoints)

  • watch [变量]:当变量被写入时触发。
  • rwatch:变量被读取时触发。
  • awatch:变量被读取或写入时触发。

关联运行进程

  1. 获取进程 PID。
  2. 启动 gdb 后输入 attach [PID]
  3. 调试结束后输入 quit 提示 detach 时选 y

Coredump 事后分析

如果程序崩溃产生了 core 文件:

Shell

1
$ gdb -tui -c core foo

这能直接定位到崩溃时的代码行。

TUI 窗口功能

  • layout src/asm/split/reg:切换布局(源码、汇编、拆分、寄存器)。
  • focus (fs) [窗口名]:切换焦点。
  • set disassembly-flavor intel/att:设置汇编风格。

快速参考表

命令 描述
help [command] 获取命令帮助
run [args] 运行程序
quit 退出 gdb
break [loc] 设置断点
next / step 步过 / 步进
continue 继续运行
backtrace 查看调用栈
print [expr] 打印表达式/变量
info break 查看断点列表
layout split 源码与汇编拆分显示