我们从客户的盒子上运行我们的软件获得核心文件.不幸的是因为我们总是使用-O2进行编译而没有调试符号,这导致我们无法弄清楚它崩溃的原因,我们已经修改了构建,所以它们现在一起生成-g和-O2.然后,我们建议客户运行-g二进制文件,以便更容易调试.
我有几个问题:
>从Linux发行版生成核心文件而不是我们在Dev中运行的文件时会发生什么?堆栈跟踪是否有意义?
>在Linux或Solaris上有没有可用于调试的好书?面向示例的东西会很棒.我正在寻找现实生活中的例子来弄清楚例行程序崩溃的原因以及作者如何找到解决方案.从中级到高级的更多东西会很好,因为我已经做了一段时间了.一些装配也会很好.
这是一个崩溃的例子,要求我们告诉客户获得-g ver.二进制文件:
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
...
理想情况下,我想解决一下为什么应用程序崩溃的原因 – 我怀疑它是内存损坏,但我不是100%肯定.
严格禁止远程调试.
谢谢
What happens when a core file is generated from a Linux distro other than the one we are running in Dev? Is the stack trace even meaningful?
可执行文件是动态链接的,就像你的那样,GDB产生的堆栈(很可能)没有意义.
原因是:GDB知道您的可执行文件是通过调用地址0x00454ff1中的libc.so.6中的内容而崩溃的,但它不知道该地址的代码是什么.所以它会查看你的libc.so.6副本并发现它在select中,所以它打印出来.
但是,客户副本libc.so.6中0x00454ff1也处于选择状态的可能性非常小.很可能客户在该地址有一些其他程序,也许是中止.
您可以使用disas select,并观察0x00454ff1是在指令的中间,还是前一条指令不是CALL.如果其中任何一个成立,则堆栈跟踪无意义.
但是,您可以自助:您只需获取从客户系统共享的(gdb)信息中列出的所有库的副本.让客户通过例如
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!
We then advice the Customer to run a -g binary so it becomes easier to debug.
一个更好的方法是:
>使用-g -O2 -o myexe.dbg构建
> cp myexe.dbg myexe
> strip -g myexe
>将myexe分发给客户
>当客户获得核心时,使用myexe.dbg进行调试