如何在ARM上生成可用的调用堆栈?

How to produce usable callstack on ARM?

提问人:bigmuscle 提问时间:6/5/2023 更新时间:6/8/2023 访问量:90

问:

我在ARM上开发C++应用程序(树莓派,g++(树莓派8.3.0-6+rpi1)8.3.0 ).当我尝试调试代码或应用程序在代码中崩溃时,我会得到正确的调用堆栈,没有任何问题。但是,当应用程序在外部库中崩溃或我单步执行 GDB 中的外部库时,调用堆栈将丢失,并且除了函数调用之外,它不包含任何有用的东西。

例如,当我在 memcpy 函数的开头中断时,我得到以下内容:

(gdb) bt
#0  0x76fa4b5c in memcpy () at /usr/lib/arm-linux-gnueabihf/libarmmem-v7l.so
#1  0x000e6118 in CWatchDog::ComputeBatteryPercentage(float) (this=0x2643140, voltage=3.96600008) at WatchDog.cpp:197
#2  0x000e5c24 in CWatchDog::BatteryControl(CWatchDog::RxPacketData const&) (this=0x2643140, data=...) at WatchDog.cpp:149
... etc ...

但是当我单步走几行时,在指令“vpush”之后,我只得到以下内容:

(gdb) bt    
#0  0x76fa4b60 in memcpy () at /usr/lib/arm-linux-gnueabihf/libarmmem-v7l.so
#1  0x00000000 in  ()

是否有可能在外部函数中启用完整的调用堆栈? 我尝试使用 -funwind-tables -fasynchronous-unwind-tables -mapcs-frame 构建代码,但这没有区别。

C++ ARM GDB 堆栈展开

评论

3赞 463035818_is_not_an_ai 6/5/2023
您是否正在使用其他库的调试版本?
0赞 bigmuscle 6/6/2023
为什么需要使用库的调试版本,尤其是在谈论系统库时?在调试为 Win32/x64 构建的相同应用程序时,即使在第三方库的高度优化版本中,我也可以单步执行并查看整个调用堆栈。
0赞 artless noise 6/8/2023
这些二进制文件需要包含一个符号表,该表显示调用方/被调用方值的位置。它们可以位于寄存器中,也可以位于堆栈上的某个位置。信息相当大。因此,您需要在设计上进行权衡。不想要堆栈跟踪的用户将不得不为更大的磁盘空间付出代价。对于嵌入式情况,这可能是闪存甚至RAM来启用跟踪。对于 gdb(暗示 gcc/clang),此信息通常是分离的。它可以从“sym”(或符号文件)加载。这取决于您的 gcc 版本。此外,由于它是开源的,您可以重建和修改。
0赞 artless noise 6/8/2023
在这种情况下,一些与 Windows 的罐头比较似乎显示出一点无知。Windows 就是这样,因为它们永远不会给你源代码,它是一个鼓励人们隐藏软件的操作系统/软件框架。因此,在这种情况下,在“高度优化的版本”构建中提供跟踪是唯一的可能性。开源是不同的,因为它不需要做出妥协。
0赞 bigmuscle 6/9/2023
我不太明白为什么这应该与开源有关。即使在 Linux 上,我也可以拥有没有源代码和调试符号的第三方专有库。在调试我的应用程序中的某些问题时,我对知道这个库中的源位置不感兴趣。我只想在调试器中单步执行程序集,并在我的应用程序崩溃时获取回溯。现在我只看到它在外部库中崩溃了,但我无法发现它是由于将无效值从我的代码传递给该库引起的。

答:

1赞 ams 6/8/2023 #1

在许多体系结构中,通常必须具有完整的调试信息或帧指针才能进行反向跟踪。有时 ABI 强制要求使用帧指针(除了堆栈指针之外),有时则不然。在寄存器相对较少的架构上,优化帧指针是很有用的,这样寄存器就可以用于其他事情。您通常可以使用 阻止它在您自己的二进制文件中执行此操作,但这对预构建的二进制文件没有帮助。(在某些体系结构上,您必须有帧指针;仅靠调试信息是不够的。-fno-omit-frame-pointer

许多 Linux 发行版都提供了额外的调试包,以便与其库包一起安装。默认情况下,通常不会安装这些软件,以节省磁盘空间并减小下载大小。GDB 将查找调试信息文件,如果能找到它们,就会使用它们,但如果找不到,则不会抱怨。

以下是我找到的有关 Raspbian 调试包的一些信息。我不知道这是否是你特别需要的,但它表明它们存在。