一尘不染

调试客户包装盒上生成的核心文件

linux

通过在客户的机器上运行我们的软件,我们可以获得核心文件。不幸的是,由于我们一直使用-O2 进行 编译, 而没有
调试符号,这导致了无法弄清崩溃原因的情况,我们修改了构建,现在它们一起生成-g和-O2。然后,我们建议客户运行-g二进制文件,以便于调试。

我有几个问题:

  1. 当从Linux发行版生成核心文件而不是我们在Dev中运行的核心文件时,会发生什么情况?堆栈跟踪是否有意义?
  2. 在Linux或Solaris上有调试的好书吗?面向示例的东西很棒。我正在寻找现实生活中的例子,以弄清例程为什么崩溃以及作者如何得出解决方案。中级到高级的东西会更好,因为我已经做了一段时间了。进行一些组装也是很好的。

这是一个崩溃的示例,它要求我们告诉客户获得-g版本。的二进制:

Program terminated with signal 11, Segmentation fault.
#0  0xffffe410 in __kernel_vsyscall ()
(gdb) where
#0  0xffffe410 in __kernel_vsyscall ()
#1  0x00454ff1 in select () from /lib/libc.so.6
...
<omitted frames>

理想情况下,我想解决以找出导致应用程序崩溃的原因-我怀疑这是内存损坏,但我不是100%肯定。

严格禁止远程调试。

谢谢


阅读 268

收藏
2020-06-02

共1个答案

一尘不染

当从Linux发行版生成核心文件而不是我们在Dev中运行的核心文件时,会发生什么情况?堆栈跟踪是否有意义?

如果可执行文件是动态链接的,就象您的动态链接一样,GDB生成的堆栈(很可能) 没有 意义。

原因:GDB知道您的可执行文件通过libc.so.6在address处调用某个东西而崩溃了0x00454ff1,但它不知道该地址上的代码是什么。因此,它将查看
您的 副本,libc.so.6并发现该副本位于中select,因此将其打印出来。

但是0x00454ff1在您的 客户 副本中选择的机会也libc.so.6很小。顾客很可能在那个地址有其他程序abort

您可以使用disas select,然后观察它0x00454ff1是否在指令中间,或者上一条指令不是CALL。如果这些条件之一成立,那么您的堆栈跟踪将毫无意义。

但是,您 可以 自助:您只需(gdb) info shared要从客户系统中获取列出的所有库的副本。让客户将它们焦油起来

cd /
tar cvzf to-you.tar.gz lib/libc.so.6 lib/ld-linux.so.2 ...

然后,在您的系统上:

mkdir /tmp/from-customer
tar xzf to-you.tar.gz -C /tmp/from-customer
gdb /path/to/binary
(gdb) set solib-absolute-prefix /tmp/from-customer
(gdb) core core  # Note: very important to set solib-... before loading core
(gdb) where      # Get meaningful stack trace!

然后,我们建议客户运行-g二进制文件,以便于调试。

一个 更好的方法是:

  • 与建立 -g -O2 -o myexe.dbg
  • strip -g myexe.dbg -o myexe
  • myexe发给客户
  • 当客户得到时core,用于对其myexe.dbg进行调试

您将拥有完整的符号信息(文件/行,局部变量),而不必向客户发送特殊的二进制文件,也无需透露太多有关源的详细信息。

2020-06-02