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

C++ gdb在ARM上报告的回溯中只有问号,c++,debugging,gdb,gdbserver,C++,Debugging,Gdb,Gdbserver,我正在尝试用ARM上的gdbserver调试一个软件,以获得崩溃的回溯。不幸的是,我只得到了问号。在任何地方,我都读到这个问题仅仅与缺乏符号有关,但符号并没有从我的图书馆中剥离出来 如果我尝试使用file命令在客户端中加载符号,我会得到: reading symbols from <path>/libQtWebKit.so.4.7.2...(no debugging symbols found)...done. 我的库是在发行版中编译的,但符号实际上就在那里。有了nm,我可以找到那

我正在尝试用ARM上的gdbserver调试一个软件,以获得崩溃的回溯。不幸的是,我只得到了问号。在任何地方,我都读到这个问题仅仅与缺乏符号有关,但符号并没有从我的图书馆中剥离出来

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

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

我的库是在发行版中编译的,但符号实际上就在那里。有了nm,我可以找到那些。为什么我只得到问号?这仅仅是因为库是通过优化编译的吗?是否可以在发布模式下调试库?

损坏的堆栈可能是您的问题。它看起来像是一个返回地址或虚拟表条目,或者某个内容被零覆盖,然后控制权被转移到了那里。即使您有可用的符号,这些地址也不会指向有效的符号。因此出现了断层


我不羡慕你的任务。这些是一些最难追踪的bug,当您更改代码试图捕获它们时,它们甚至可以移动或暂时消失。您的最佳选择通常是类似于
git bisect
或您的VCS等价物,以找到引入它的提交。希望复制不会太困难。

当您遇到“地址0处的SEGV”问题时,有时可以使用的一个技巧是手动将返回地址从堆栈顶部弹出到pc中,并尝试从那里进行堆栈跟踪。这假设您通过空指针执行间接调用来访问地址0,这是访问地址0的最常见方式

现在我对ARM不太熟悉,但在x86 PC上,您可以:

(gdb) set $eip = *(void **)$esp
(gdb) set $esp = $esp + 4
然后再做一次回溯,找出你真正的位置


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

不幸的是,这是对WebKit的修改。没有可恢复到的早期版本。还有其他的调试方法吗?也许是瓦尔格林?
(gdb) set $eip = *(void **)$esp
(gdb) set $esp = $esp + 4