通过在客户的机器上运行我们的软件,我们可以获得核心文件。不幸的是,由于我们一直使用-O2 进行 编译, 而没有 调试符号,这导致了无法弄清崩溃原因的情况,我们修改了构建,现在它们一起生成-g和-O2。然后,我们建议客户运行-g二进制文件,以便于调试。
我有几个问题:
这是一个崩溃的示例,它要求我们告诉客户获得-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%肯定。
严格禁止远程调试。
谢谢
当从Linux发行版生成核心文件而不是我们在Dev中运行的核心文件时,会发生什么情况?堆栈跟踪是否有意义?
如果可执行文件是动态链接的,就象您的动态链接一样,GDB生成的堆栈(很可能) 没有 意义。
原因:GDB知道您的可执行文件通过libc.so.6在address处调用某个东西而崩溃了0x00454ff1,但它不知道该地址上的代码是什么。因此,它将查看 您的 副本,libc.so.6并发现该副本位于中select,因此将其打印出来。
libc.so.6
0x00454ff1
select
但是0x00454ff1在您的 客户 副本中选择的机会也libc.so.6很小。顾客很可能在那个地址有其他程序abort。
abort
您可以使用disas select,然后观察它0x00454ff1是否在指令中间,或者上一条指令不是CALL。如果这些条件之一成立,那么您的堆栈跟踪将毫无意义。
disas select
CALL
但是,您 可以 自助:您只需(gdb) info shared要从客户系统中获取列出的所有库的副本。让客户将它们焦油起来
(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
您将拥有完整的符号信息(文件/行,局部变量),而不必向客户发送特殊的二进制文件,也无需透露太多有关源的详细信息。