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

11

我正在尝试在ARM上使用gdbserver调试软件以获取崩溃的回溯(backtrace)。不幸的是,我只得到了问号。无论哪里,我都读到这个问题仅与缺少符号相关,但我的库中没有剥离符号。

如果我尝试使用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个回答

3
损坏的堆栈提示可能是你的问题所在。看起来像是返回地址、虚表条目或其他东西被覆盖为零,然后控制权被转移到那里。即使您有符号可用,那些地址也不指向有效的符号。因此出现了段错误。
我并不羡慕你的任务。这些都是最难追踪的错误之一,甚至在您进行代码更改以尝试捕获它们时,它们可能会移动或暂时消失。通常最好的方法是使用git bisect或类似的版本控制工具来查找引入该错误的提交。希望不太难复现。

1
很遗憾,这是对WebKit的修改。没有之前的版本可以还原。还有其他调试的方法吗?也许使用valgrind? - Luca Carlon

1
有时候当你遇到“SEGV at address 0”的问题时,你可以使用一个技巧,手动将栈顶的返回地址弹出到pc中,并尝试从那里进行堆栈跟踪。这假设你通过一个空指针进行了间接调用,这是到达地址0最常见的方式。
现在我对ARM不太熟悉,但在x86 PC上,你可以这样做:
(gdb) set $eip = *(void **)$esp
(gdb) set $esp = $esp + 4

然后进行另一个回溯以确定您真正所在的位置。

如果您可以弄清楚编译器使用的ARM调用约定,那么您应该能够做类似的事情。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接