GNU 调试器是一个发现程序缺陷的强大工具。
如果你是一个程序员,想在你的软件增加某些功能,你首先考虑实现它的方法:例如写一个方法、定义一个类,或者创建新的数据类型。然后你用编译器或解释器可以理解的编程语言来实现这个功能。但是,如果你觉得你所有代码都正确,但是编译器或解释器依然无法理解你的指令怎么办?如果软件大多数情况下都运行良好,但是在某些环境下出现缺陷怎么办?这种情况下,你得知道如何正确使用调试器找到问题的根源。
GNU 调试器GNU Project Debugger(GDB)是一个发现项目缺陷的强大工具。它通过追踪程序运行过程中发生了什么来帮助你发现程序错误或崩溃的原因。(LCTT 校注:GDB 全程是“GNU Project Debugger”,即 “GNU 项目调试器”,但是通常我们简称为“GNU 调试器”)
本文是 GDB 基本用法的实践教程。请跟随示例,打开命令行并克隆此仓库:
git clone https://GitHub.com/hANSIc99/core_dump_example.git
快捷方式
GDB 的每条命令都可以缩短。例如:显示设定的断点的 info break
命令可以被缩短为i break
。你可能在其他地方看到过这种缩写,但在本文中,为了清晰展现使用的函数,我将所写出整个命令。
命令行参数
你可以将 GDB 附加到每个可执行文件。进入你克隆的仓库(core_dump_example
),运行make
进行编译。你现在能看到一个名为coredump
的可执行文件。(更多信息,请参考我的文章《创建和调试 Linux 的转储文件》。)
要将 GDB 附加到这个可执行文件,请输入: gdb coredump
。
你的输出应如下所示:
返回结果显示没有找到调试符号。
调试信息是目标文件object file(可执行文件)的组成部分,调试信息包括数据类型、函数签名、源代码和操作码之间的关系。此时,你有两种选择:
- 继续调试汇编代码(参见下文“无符号调试”)
- 使用调试信息进行编译,参见下一节内容
使用调试信息进行编译
为了在二进制文件中包含调试信息,你必须重新编译。打开 Makefile
,删除第 9 行的注释标签(#
)后重新编译:
CFLAGS =-Wall -Werror -std=c 11 -g
-g
告诉编译器包含调试信息。运行make clean
,接着运行make
,然后再次调用 GDB。你得到如下输出后就可以调试代码了:
新增的调试信息会增加可执行文件的大小。在这种情况下,执行文件增加了 2.5 倍(从 26,088 字节 增加到 65,480 字节)。
输入 run -c1
,使用-c1
开关启动程序。当程序运行到达State_4
时将崩溃: