使用 gdb 进行调试

通过 GNU 调试器 (gdb),您可以在程序执行或回顾程序在崩溃那一刻的行为时检查其他程序的内部情况。

gdb 允许您检查和控制代码执行情况,它对于评估崩溃或一般不正确行为的原因非常有用。 gdb 不处理 Java™ 进程,因此它在纯 Java 程序上的使用有限。 它对于调试本机库和 JVM 自身非常有用。

运行 gdb

您可以通过三种方式运行 gdb

启动程序
通常,gdb <application> 命令用于在 gdb 控制下启动程序。 但是,由于 Java 的启动方式,您必须通过设置环境变量然后调用 Java 来启动 gdb :
export IBM_JVM_DEBUG_PROG=gdb
java
然后,您将接收到 gdb 提示符,并提供 run 命令和 Java 自变量:
r <java_arguments>
连接到正在运行的程序
如果 Java 程序已在运行,那么可以在 gdb下对其进行控制。 需要正在运行的程序的进程标识,然后使用 Java 应用程序作为第一个自变量并使用进程标识作为第二个自变量来启动 gdb :
gdb <Java Executable> <PID>

在将 gdb 连接到正在运行的程序后,该程序将停止,并对查看器显示其在代码中的位置。 之后,该程序将处于 gdb 的控制下,您可以开始发出命令以设置和查看变量,并以一般方式控制代码执行情况。

在系统转储(核心文件)上运行
在程序崩溃时,通常会生成系统转储。 gdb 可在此系统转储上运行。 系统转储包含发生崩溃时程序的状态。 使用 gdb 来检查导致发生崩溃的所有变量和寄存器的值。 此信息可帮助您发现导致崩溃发生的原因。 要调试系统转储,请以 Java 应用程序文件作为第一个自变量并以系统转储名称作为第二个自变量来启动 gdb :
gdb <Java Executable> <system dump>

当针对系统转储运行 gdb 时,开始时它会显示一些信息,如程序接收到的终止信号、此时正在执行的函数以及产生该故障的代码行。

当程序受 gdb控制时,将显示欢迎消息,后跟提示 (gdb)。 程序现在正在等待您输入指示信息。 对于每条指令,程序会以您选择的任何方式继续执行。

设置断点和观察点

可使用以下命令,为特定的行或函数设置断点:

break linenumber

break functionName

设置断点后,请使用 continue 命令来使程序一直执行,直至到达断点。

使用条件语句设置断点,使程序仅在满足指定条件时才停止。 例如,使用 breakpoint 39 if var == value 可使程序在到达第 39 行(且只有变量等于指定值)时停止。

如果想要了解变量在何时以及何地变为特定值,可使用观察点。 请在所讨论的变量处于作用域内时设置观察点。 设置完毕后,当该变量达到指定值时,系统便会发出警报来提醒您。 该命令的语法是:watch var == value

要查看已设置的断点和观察点,请使用 info 命令:

info break
info watch
gdb 达到断点或观察点时,它会打印出接下来设置要执行的代码行。 在第 8 行设置断点将导致程序在完成执行第 7 行后但是在执行第 8 行之前停止。 和断点和观察点一样,程序也会在收到特定系统信号时停止。 您可以使用以下命令,在每次收到此类系统信号时阻止调试工具停止运行:
handle sig32 pass nostop noprint 
handle sigusr2 pass nostop noprint 

检查代码

当到达代码的正确位置时,有多种方式可用来检查代码。 最有用的是 backtrace(缩写为 bt),其显示调用堆栈。 调用堆栈是函数架构集合,其中每个函数架构都包含诸如函数参数和局部变量等信息。 这些函数架构以其执行顺序分布在调用堆栈中。 这意味着最近调用的函数显示在调用堆栈的最上方。 您可以通过检查调用堆栈来跟踪程序的执行轨迹。 显示调用堆栈时,将在行开头显示架构号,之后依次是调用函数的地址、函数名以及函数的源文件。 例如:
#6 0x804c4d8 in myFunction () at myApplication.c

要查看有关函数架构的更详细信息,请使用 frame 命令以及指定架构编号的参数。 选择架构后,您可以使用命令 print var 来显示其变量。

使用 print 命令来更改变量的值;例如,print var = newValue

info locals 命令显示选中函数中所有本地变量的值。

要遵循程序执行的确切顺序,请使用 stepnext 命令。 两个命令都采用了可指定所执行行数的可选参数。 但是,next 将函数调用视为单行执行,而 step 遍历所调用函数的每一行,一次一步。

有用的命令

完成代码调试后,run 命令使程序运行到其结束或崩溃点。 quit 命令用于退出 gdb

其他有用的命令包括:

ptype
打印变量的数据类型。
info share
打印当前装入的共享库的名称。
info functions
打印所有函数原型。
list
显示当前行周围的 10 行源代码。
help
显示主题列表,每个主题均调用 help 命令以显示有关该主题的详细帮助信息。