只有gdb在ARM上报告的回溯中的问号

时间:2011-12-08 20:49:45

标签: c++ debugging gdb gdbserver

我正在尝试使用ARM上的gdbserver调试软件以获得崩溃的回溯。不幸的是我只得到问号。无处不在,我读到这个问题只是缺少符号,但符号并没有从我的库中删除。

如果我尝试使用file命令在客户端加载符号,我会得到:

reading symbols from <path>/libQtWebKit.so.4.7.2...(no debugging symbols found)...done.

然后,当崩溃发生时:

Program received signal SIGSEGV, Segmentation fault.
0x00000000 in ?? ()
(gdb) bt
#0  0x00000000 in ?? ()
#1  0x4bf38b88 in ?? ()
Backtrace stopped: previous frame identical to this frame (corrupt stack?)

我的库是在发布时编译的,但符号实际上是存在的。有了nm,我可以找到它们。为什么我只收到问号?这只是因为库是用优化编译的吗?是否可以在发布模式下使用库进行调试?

2 个答案:

答案 0 :(得分:2)

corrupt stack注释可能是你的问题。它看起来像一个返回地址或虚拟表条目或用零覆盖的东西,然后控制权转移到那里。即使您有符号可用,这些地址也不指向有效符号。因此,段错误。

我不羡慕你的任务。这些是一些最难追踪的错误,当您进行代码更改以尝试捕获它们时甚至可以移动或暂时消失。你最好的选择通常是git bisect或你的VCS等同于找到引入它的提交。希望重现并不太难。

答案 1 :(得分:1)

当你得到“SEGV at address 0”问题时,有时可以使用的一个技巧是手动将堆栈顶部的返回地址弹出到pc并尝试从那里进行堆栈跟踪。这假设您必须通过NULL指针进行间接调用来寻址0,这是获取地址0的最常用方法。

现在我对ARM不太熟悉,但在x86 PC上,你会这样做:

(gdb) set $eip = *(void **)$esp
(gdb) set $esp = $esp + 4

然后再做一次回溯以确定你到底在哪里。

如果您可以通过编译器找出用于ARM的调用约定,那么您应该可以执行类似的操作。

相关问题