提问人:bigmuscle 提问时间:6/5/2023 更新时间:6/8/2023 访问量:90
如何在ARM上生成可用的调用堆栈?
How to produce usable callstack on ARM?
问:
我在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 构建代码,但这没有区别。
答:
1赞
ams
6/8/2023
#1
在许多体系结构中,通常必须具有完整的调试信息或帧指针才能进行反向跟踪。有时 ABI 强制要求使用帧指针(除了堆栈指针之外),有时则不然。在寄存器相对较少的架构上,优化帧指针是很有用的,这样寄存器就可以用于其他事情。您通常可以使用 阻止它在您自己的二进制文件中执行此操作,但这对预构建的二进制文件没有帮助。(在某些体系结构上,您必须有帧指针;仅靠调试信息是不够的。-fno-omit-frame-pointer
许多 Linux 发行版都提供了额外的调试包,以便与其库包一起安装。默认情况下,通常不会安装这些软件,以节省磁盘空间并减小下载大小。GDB 将查找调试信息文件,如果能找到它们,就会使用它们,但如果找不到,则不会抱怨。
以下是我找到的有关 Raspbian 调试包的一些信息。我不知道这是否是你特别需要的,但它表明它们存在。
评论