打开具有不同可执行文件但源相同的核心转储文件

Posted

技术标签:

【中文标题】打开具有不同可执行文件但源相同的核心转储文件【英文标题】:Opening core dump file with different executable but the same sources 【发布时间】:2016-09-24 14:35:01 【问题描述】:

我有一个同事机器上的 coredump 文件。

我们都有相同的程序来源和相同的第三方*.so 文件(如libmysqlclient18 和几个内部文件)。

问题是我们都独立编译软件(来自相同的来源),我想使用他的核心转储文件在我的机器上使用 GDB 进行检查。

当我尝试将核心文件和我的可执行文件加载到 gdb 中时,我得到:

user@ubuntu:/mnt/hgfs/share/dir$ gdb prog core
GNU gdb (Ubuntu/Linaro 7.4-2012.04-0ubuntu2.1) 7.4-2012.04
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-linux-gnu".
For bug reporting instructions, please see:
<http://bugs.launchpad.net/gdb-linaro/>...
Reading symbols from /mnt/hgfs/share/dir/prog...done.

warning: exec file is newer than core file.
[New LWP 4465]
[New LWP 4462]
[New LWP 4464]

warning: Can't read pathname for load map: Input/output error.
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/i386-linux-gnu/libthread_db.so.1".
Core was generated by `./prog'.
Program terminated with signal 11, Segmentation fault.
#0  0x002d3706 in ?? () from /lib/i386-linux-gnu/libc.so.6
(gdb) bt full
#0  0x002d3706 in ?? () from /lib/i386-linux-gnu/libc.so.6
No symbol table info available.
#1  0x00000000 in ?? ()
No symbol table info available.
(gdb) 

这种情况是否可行? (当然,我在启用调试符号的情况下编译软件) 如果没有,我缺少哪些技术细节?

我确信如果他或我对源进行修改是不可能的,因为那样可执行文件会有所不同,但情况并非如此,第三方*.so 文件和源,它们都匹配。

更新: 在以 cmets 中建议的用户 mkfs 的身份安装 libc6-dbg 后,我在 gdb 中得到了这个:

user@ubuntu:/mnt/hgfs/share/dir$ gdb prog core
GNU gdb (Ubuntu/Linaro 7.4-2012.04-0ubuntu2.1) 7.4-2012.04
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-linux-gnu".
For bug reporting instructions, please see:
<http://bugs.launchpad.net/gdb-linaro/>...
Reading symbols from /mnt/hgfs/share/dir/prog...done.

warning: exec file is newer than core file.
[New LWP 4465]
[New LWP 4462]
[New LWP 4464]

warning: Can't read pathname for load map: Input/output error.
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/i386-linux-gnu/libthread_db.so.1".
Core was generated by `./prog'.
Program terminated with signal 11, Segmentation fault.
#0  0x002d3706 in _IO_helper_overflow (s=0x0, c=0) at vfprintf.c:2188
2188    vfprintf.c: No such file or directory.
(gdb) bt
#0  0x002d3706 in _IO_helper_overflow (s=0x0, c=0) at vfprintf.c:2188
#1  0x00000000 in ?? ()
(gdb) bt full
#0  0x002d3706 in _IO_helper_overflow (s=0x0, c=0) at vfprintf.c:2188
        written = 47
        target = <optimized out>
        used = -1226838776
#1  0x00000000 in ?? ()
No symbol table info available.
(gdb)

【问题讨论】:

您确定安装了 libc 的调试符号(例如 libc6-dbg 包)吗?此外,由于它正在查找 .对于可执行文件,您可以将同事的可执行文件和核心转储放在临时目录中,然后从那里运行 gdb。 如果构建完全相同,包括编译器标志,这将起作用。如果构建环境存在差异,那么共享可执行文件会容易得多。 @MatthewFisher flags 是一样的,我们使用同一个 Makefile。 @mkfs 我在安装libc6-dbg 后更新了我的问题,它似乎有所帮助,但并不完全。 这可能是两个系统上的系统库不同,这意味着您必须将 libc 等从同事的计算机复制到您的计算机。请参阅 en.wikibooks.org/wiki/Linux_Applications_Debugging_Techniques/… 和 ***.com/questions/7557283/…。您还应该验证此 2 级堆栈跟踪它不是您的同事在 gdb 中打开核心文件时看到的内容:堆栈可能完全被冲洗掉了,而您系统上的 gdb 是正确解释核心文件。 【参考方案1】:

这种情况是否可行?

是的,但您需要确保您在两台机器上构建的二进制文件的符号布局相同(或至少足够接近)。这不一定是微不足道的:本地用户名、源或安装目录的路径名和主机名有时会泄漏到构建的目标文件中,并可能导致符号不匹配。

要检查二进制文件是否接近,运行diff &lt;(nm a.out) &lt;(nm b.out)——应该只有很少的差异。如果您发现很多差异,则说明您的二进制文件不够接近。

当然,我编译软件时启用了调试符号

这可能是您的第一个错误:如果您的同事使用-O2 构建,而您使用-g(以及隐含的-O0)构建,则二进制文件保证不匹配。

您需要完全使用您的同事构建时使用的标志(但您可能添加调试符号;例如,如果您的同事使用-O2 构建,您应该构建与-O2 -g一起)。

附:请注意,您需要两台机器上的identical versions of system libraries。

【讨论】:

编译器标志相同,我们使用相同的Makefile。

以上是关于打开具有不同可执行文件但源相同的核心转储文件的主要内容,如果未能解决你的问题,请参考以下文章

如何调试从执行发布文件生成的核心转储文件?

(Mac) 将核心文件留在可执行文件所在的位置,而不是 /cores?

C++学习(三九五)ELF类型文件

如何获取可执行文件的字符串转储?

相同的源代码,不同的可执行文件大小?

在 Windows cmd 中,如何在当前目录中运行可执行文件(而不是在 %PATH% 中具有相同名称的可执行文件)而不参考完整路径? [关闭]