Debugging 如何使用gdb剖析像文字处理器这样的应用程序

Debugging 如何使用gdb剖析像文字处理器这样的应用程序,debugging,gdb,Debugging,Gdb,就开源开发而言,我是个新手。我曾尝试过几个项目,但总是因为代码库太大而感到沮丧 我一直面临的一个特殊问题是无法确定大型代码库的哪一部分处理特定任务。比方说,如果我想知道文字处理器中的文本呈现和布局是代码的哪一部分 人们经常给出的建议是使用gdb逐步完成程序 所以我试着在我的字处理器上打开一个文件(它是用调试标志编译的)并得到一个回溯,但奇怪的是,我得到的只是一些普通的函数调用,这些调用都与打开一个文件无关 这就是我在执行gdb/usr/local/bin/abiword (gdb) bt 0

就开源开发而言,我是个新手。我曾尝试过几个项目,但总是因为代码库太大而感到沮丧

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

人们经常给出的建议是使用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用于此目的。很抱歉,如果我的问题听起来太离谱,但我真的无法用语言来完成这样的任务,所以谷歌也帮不上忙|

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

当处理像文字处理器(简称WP)这样复杂的事情时,这是最糟糕的建议

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

然后阅读这些库。其中之一可能与文本呈现有关。它很可能还附带了一组示例

构建那个库,构建示例,修改它们来做其他事情

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

对其他库重复上述步骤,最终将构建一幅事物如何组合在一起的图片

所以我试着在我的字处理器上打开一个文件(它是用调试标志编译的)并得到一个回溯,但奇怪的是,我得到的只是一些普通的函数调用,这些调用都与打开一个文件无关

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

编辑:

“catch syscall open”捕获所有“open”系统调用,这些调用非常多

对。但是在WP启动后,不应该有那么多的
打开的
s。因此,在屏幕上显示WP之后,在执行
文件->打开
菜单操作之前,请执行
捕获操作

有没有办法指定文件名和catch syscall open

是的,您可以将
捕获设置为有条件的。该条件的详细信息是特定于操作系统的。看起来您正在将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)。

您不能只是随机选择一个程序并对其运行调试器,期望找到人类可读的代码,上面写着“此部分处理文本的图形输出”或其他内容。除非您在汇编代码和堆栈跟踪方面非常先进,否则您至少需要调试符号,并且带有调试信息和源代码的对象文件会使事情变得更简单。谢谢,但我确保使用调试信息编译程序。您可以编辑问题并添加这些信息。:)读取一个大的代码库可能很困难,但是单步执行一个大的、完整的程序要困难得多。“catch syscall open”捕获所有“open”系统调用,这些调用非常多。有没有办法指定文件名和catch syscall open?我在程序上运行了strace并打开了一个示例文件。这是其中一个调用:open(“/home/nav/Doc1.doc”,O|RDONLY | O|u LARGEFILE)我想知道我是否可以在这个调用中打开gdb。这很奇怪,但当我在GDB7.2P1上尝试cond10==strcmp($ebx,/home/nav/Doc1.doc”)时,我也收到了一个分段错误。奇怪的是,当我用--enable debug编译gdb 7.3.1时,我收到了:测试断点条件时出错:当前上下文中没有符号“strcmp”。捕获点1(调用系统调用“打开”),0xb7ff85b4英寸??()来自/lib/ld-linux.so。2@navgeet“无符号strcmp”。。。这是“在进入“主要”部分之前不会起作用的。我认为我没有获得有意义的回溯的原因是回溯只打印一个调用堆栈,而我希望获得调用历史记录。对吗?