2011-12-22 61 views
1

就开源开发而言,我是一个新手。我已经在几个项目上尝试过我的手,但由于代码基数庞大,最终总是感到沮丧。如何使用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

你不能随便选择一个程序,并运行一个调试器,期望找到一个说明“这部分处理文本的图形输出”或其他内容的可读代码。除非您在汇编代码和堆栈跟踪方面非常先进,否则至少需要调试符号,而使用调试信息和源代码的目标文件使事情变得更加容易。 – 2011-12-22 23:48:35

+0

谢谢,但我确保使用调试信息编译程序。 – navgeet 2011-12-22 23:52:25

+0

您可以编辑您的问题并添加该信息。 :) – 2011-12-23 00:12:41

回答

3

人们经常给出的建议是使用gdb来浏览程序。

这是最糟糕的可能咨询,东西打交道时可以复杂到一个字处理器(WP的简称)。

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

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

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

现在你准备好回答的问题,如通过设置GDB在库入口点断点,并检查其WP的部分被调用到他们,并与参数“是如何做到这一点WP使用​​该库”。

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

所以,我想在我的字处理器(这是用调试标志编译)打开文件,并得到一个回溯,但奇怪的是,我已经获得了所有有一些普通的函数调用其中没有涉及到打开文件。

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

编辑:

“抓系统调用打开” 捕捉所有的 “开放式” 的系统调用,这是很多

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

有没有一种方法可以指定文件的名称以及catch syscall open?

是的,你可以使catch有条件。条件的细节是特定于操作系统的。看起来你使用的i686-linux与VDSO。对于组合,下面应该做的伎俩:

(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' 

以上情况会使捕获点只开有"/hom"前缀的文件时停止。

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

你也可以试试这个:

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

,但你到main在此之前将有可能无法正常工作,从而可能导致崩溃GDB(坠毁我的,这是一个bug)。

+0

“捕获系统调用打开”捕获所有“打开”系统调用,这是很多。有没有一种方法来指定文件的名称以及catch syscall open? 我在程序上运行strace并打开一个示例文件。这是其中一个呼叫: open(“/ home/nav/Doc1.doc”,O_RDONLY | O_LARGEFILE) 我想知道在这个调用中我是否可以在gdb中断开。 – navgeet 2011-12-23 21:42:44

+0

奇怪的是,当我在gdb 7.2 p1上试过cond 1 0 == strcmp($ ebx,“/home/nav/Doc1.doc”)时,我也收到了一个分段错误。 奇怪的是当我用--enable-debug诠释gdb 7.3.1时我收到: 测试断点条件时出错: 当前上下文中没有符号“strcmp”。 Catchpoint 1(调用syscall'open'),0xb7ff85b4在?? () from /lib/ld-linux.so.2 – navgeet 2011-12-24 03:04:38

+0

@navgeet“没有符号strcmp”...这就是“在你到达”主“部分之前不会工作 – 2011-12-24 03:11:35

相关问题