是否可以调试由没有 gdb 标志编译的可执行文件生成的核心文件?

Posted

技术标签:

【中文标题】是否可以调试由没有 gdb 标志编译的可执行文件生成的核心文件?【英文标题】:Is it possible to debug core file generated by a executable compiled without gdb flag? 【发布时间】:2011-08-02 08:13:48 【问题描述】:

是否可以调试没有gdb标志编译的可执行文件生成的核心文件?

如果是的话,有没有关于它的指针或教程?

【问题讨论】:

你说的gdb标志是什么??你的意思是-g标志(调试标志) 正如您的一个好答案所暗示的那样,汇编级调试就是您将获得的全部。可以做到,但并不容易,而且不会有“教程”。您将不得不学习运行程序的处理器的汇编语言。 了解操作系统、CPU 架构和目标文件格式可能有助于解决这个问题。你能提供这些信息吗? 如果您没有选择答案,我们会为您选择一个。 :-) 【参考方案1】:

是的,你可以。但这并不容易。我给你举个例子。

假设我有一个名为 foo.c 的程序:

main()

    *((char *) 0) = '\0';

我会编译它并确保没有符号:

$ cc foo.c
$ strip a.out
$ file a.out
a.out: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.15, stripped

好的,该运行它了:

$ ./a.out
Segmentation fault (core dumped)

哎呀。似乎有一个错误。让我们启动一个调试器:

$ gdb ./a.out core
[..]
Reading symbols from /tmp/a.out...(no debugging symbols found)...done.
[..]
Core was generated by `./a.out'.
Program terminated with signal 11, Segmentation fault.
#0  0x0804839c in ?? ()
(gdb) bt
#0  0x0804839c in ?? ()
#1  0xb7724e37 in __libc_start_main () from /lib/i386-linux-gnu/libc.so.6
#2  0x08048301 in ?? ()

嗯,看起来很糟糕。没有符号。我们能弄清楚发生了什么吗?

(gdb) x/i $eip
=> 0x804839c:   movb   $0x0,(%eax)

看起来它试图将一个值为 0 的字节存储到 EAX 寄存器指向的内存位置。为什么失败了?

(gdb) p $eax
$1 = 0
(gdb)

它失败了,因为 EAX 寄存器指向一个内存地址零并且它试图在该地址存储一个字节。糟糕!

不幸的是,我没有任何好的教程的指针。搜索“gdb reverse engineering”会给出一些可能有用的链接。

更新:

我注意到这是关于在客户处调试核心转储的评论。当您将剥离的二进制文件发送给客户时,您应该始终保留该二进制文件的调试版本。

我建议不要剥离甚至提供源代码。我编写的所有代码都与源代码一起发送给客户。我在客户方面遇到过太多次了,面对一个不称职的供应商,该供应商已经发布了一个损坏的软件,但不知道如何修复它。太烂了。

这似乎实际上是这个问题的重复:

Debug core file with no symbols

那里有一些额外的信息。

【讨论】:

【参考方案2】:

是的,你可以, 这就是写裂缝的人正在做的事情, 不幸的是,我不再拥有我在大学学习的课程的幻灯片和文档,但在谷歌上搜索reverse engineeringdisassembly tutorials 会给你一些起点。了解汇编代码的方式也很重要。

我们的课程是基于一本书,主要是第 1 章和第 3 章,但现在有一个新版本

Computer Systems: A programmer's perspective by R.E. Bryant and D.R. O'Hallaron

它解释了计算机系统背后的基础知识,并让您很好地了解系统中程序的工作原理。

另外,在学习这一点时,请注意 64 位 cpu 的汇编代码与 32 位 cpu 的汇编代码不同,以防万一。

【讨论】:

【参考方案3】:

如果程序编译时不带-g标志,则无法调试核心文件。

否则,您可以这样做: gdb 可执行核心文件

您可以在以下位置找到更多信息: http://wwwpub.zih.tu-dresden.de/~mlieber/practical_debugging/04_gdb.pdf

【讨论】:

所以在大多数客户场景中,他们的可执行文件会在没有 gdbflag -g 的情况下编译,对吗?那么我们如何调试在客户场景下生成的核心转储呢? 通过客户场景,我认为您在谈论已发布的构建或 exe。因此,根据我的经验,在这种情况下,核心转储无法调试。您可能会等待一些更好的答案,以便我也可以从中受益:) 根据我的经验,发布版本仍然是使用 -g 构建的(即使有优化,例如 -O3)。这确保了一些的可调试性。可执行文件被复制到档案中。然后,从可执行文件(包括库)中删除符号,然后将其归档。最后,无符号版本正式发布。然后,您可以告诉 gdb 将可执​​行文件设置为可调试的可执行文件,同时使用带有剥离符号的可执行文件中的核心文件。然后 GDB 很高兴,一切都“正常”(好吧,就像调试优化的可执行文件“正常”一样)。

以上是关于是否可以调试由没有 gdb 标志编译的可执行文件生成的核心文件?的主要内容,如果未能解决你的问题,请参考以下文章

gdb 7.5.1 调试通过 g 4.7.2 构建的可执行文件的问题

即使使用 -g 标志编译,gdb 中也没有调试符号

使用 minidumps 和 GDB 分析 mingw 编译的可执行文件的崩溃?

GDB:断点没有被命中

从可执行文件中找出编译优化标志

linux 下面怎么用gdb调试多个.c文件?