如何使用gdb来剖析像Word处理器这样的应用程序

时间:2011-12-22 23:26:40

标签: debugging gdb

就开源开发而言,我是新手。我已经尝试过几个项目,但由于代码库很大,我总是感到很沮丧。

我一直面临的一个特殊问题是无法确定大型代码库的哪个部分处理特定作业。比方说,如果我想知道代码的哪一部分在字处理器中进行文本渲染和布局。

人们经常给出的建议是使用gdb逐步完成程序。

所以我尝试在我的文字处理器上打开一个文件(用调试标志编译)并得到一个回溯但奇怪的是,我得到的只是一些普通的函数调用,其中没有一个与打开文件有关。

这是我在执行gdb /usr/local/bin/abiword

时获得的
(gdb) bt
0  0xffffe424 in __kernel_vsyscall ()
1  0xb63b472b in poll () from /lib/libc.so.6
2  0xb66256eb in g_poll () from /usr/lib/libglib-2.0.so.0
3  0xb6616db6 in ?? () from /usr/lib/libglib-2.0.so.0
4  0xb66174bb in g_main_loop_run () from /usr/lib/libglib-2.0.so.0
5  0xb6d6668d in gtk_main () from /usr/lib/libgtk-3.so.0
6  0xb7c04a4d in AP_UnixApp::main (szAppName=0x8048970 "abiword", argc=1, 
    argv=0xbffff704) at ap_UnixApp.cpp:1332
7  0x080488a3 in main (argc=1, argv=0xbffff704)
    at ../src/wp/main/gtk/UnixMain.cpp:30

请建议如何将gdb用于此目的。很抱歉,如果我的问题听起来太吵了,但我真的对这样的任务感到失望,所以谷歌也没有帮助。 :|

1 个答案:

答案 0 :(得分:3)

  

人们经常给出的建议是使用gdb逐步完成程序。

这是最差可能的建议,在处理像文字处理器这样复杂的事情时(简称WP)。

您想要做的是在二进制文件上运行ldd,或者查看正在运行的WP的/proc/<pid>/maps,并查看它使用的共享库。

然后阅读这些库。其中一个可能与文本渲染有关。它很可能还带有一组例子。

构建该库,构建示例,修改它们以执行其他操作。

现在您已准备好通过在库入口点设置GDB断点,并检查WP的哪些部分正在调用它们来回答诸如“该WP如何使用该库”之类的问题,以及用哪些参数。

对其他图书馆重复,你最终会建立一个如何融合在一起的图片。

  

所以我尝试在我的文字处理器上打开一个文件(用调试标志编译)并得到一个回溯但奇怪的是,我得到的只是一些普通的函数调用,其中没有一个与打开文件有关。

在GDB中,执行以下操作:catch syscall open。现在尝试打开一个文件,你会发现WP的确切部分对此负责。

编辑:

  

“catch syscall open”捕获所有“开放”系统调用,这些调用很多

是。但WP开始后不应该有那么多open秒。在屏幕上显示WP之后,以及在执行catch菜单操作之前,File->Open也是如此。

  

有没有办法指定文件的名称以及catch syscall open?

是的,您可以使catch有条件。条件的详细信息是特定于操作系统的。看起来您正在使用带有VDSO的i686-linux。对于这种组合,以下应该可以解决这个问题:

(gdb) catch syscall open
Catchpoint 1 (syscall 'open' [5])

(gdb) cond 1 ((char*)$ebx)[0] == '/' && ((char*)$ebx)[1] == 'h' \
           && ((char*)$ebx)[2] =='o' && ((char*)$ebx)[3] == 'm'

以上条件将使catchpoint仅在打开具有"/hom"前缀的文件时停止。

您可以以明显的方式添加更多字母。

你也可以试试这个:

(gdb) cond 1 0 == strcmp($ebx, "/home/nav/Doc1.doc")

但是在你到达main之前这可能不会起作用,并且可能会导致GDB崩溃(它崩溃了,这是一个错误)。