ZMonster's Blog 巧者劳而智者忧,无能者无所求,饱食而遨游,泛若不系之舟

GDB调试技巧(续)

以下是这段时间阅读 Tesseract 源代码时所学习并实践过的一些 GDB 调试技巧,和 前一篇 一样,我也认为这些是比较实用的(虽然对别人来说未必)。

另外,我觉得阅读源代码的话,最好的办法莫过于进行调试,深入其内部的处理流程 —— 当然如果作者有提供完善的文档的话可以省下很多的精力。

设置环境变量

这个其实倒和 GDB 本身没多大关系,一般来说在 shell 里启动 GDB 的话,是能够正常使用用户的环境变量的,不过作为一个 Emacser ,我更喜欢在 Emacs 里用 gud-gdb 来进行调试,Emacs 会为 GDB 提供一个更易用的用户界面,但问题是这种情况下自己设置的一些环境变量都没有被读取。

在调试 Tesseract 的时候,程序要使用一个外部的环境变量 TESSDATA_PREFIX ,于是就出现问题了。

解决这个问题的方法是用 set 命令在 GDB 里设置环境变量:

set environment TESSDATA_PREFIX=/home/linusp/data/tessdata

当然了 set 命令还可以用来设置、修改变量的值,是非常有用的。

修改、设置程序中的变量

有两种办法,一种是使用 set 命令,另外一种是使用 print 命令。

set 命令:

set variable i=0

或者先得到待设置的变量的地址(用 print 命令),然后根据地址来修改值:

set *((int *) 0xbfbb0000) = 20

print 命令:

print i=0

查看变量的类型

使用 whatis 命令可以得到变量的类型,如果变量的类型是一个复合类型而非 C/C++ 的基础类型,则可以通过 ptype 命令来查看该类型的定义。

gdb_show_type.png

调用函数

在调试的时候可以通过 call 命令来调用一些函数。在调试 Tesseract 时,它使用的图像库 Leptonica 提供了一个显示图像的函数 pixDisplay ,让我能够用 call 命令来调用它查看每一步处理结束后图像变成了什么样子,实在是帮了大忙了。

除了辅助调试外,不妨将思维发散一下,用 call 命令可以调用函数,而 print 命令则能执行一些非函数调用的普通语句(不过控制语句无法被执行),结合这两者我们就有了一个几乎是交互式的 C/C++ 运行环境了。