我正在开发一个项目,其中出现了“我们希望在发布构建堆栈跟踪中获得更多信息”的请求。
使用“堆栈跟踪”我的意思是of t a a bt
中的输出gdb
,我认为这相当于运行进程的gstack输出。如果这是真的,那将是我的一个问题。
我的主要问题是堆栈跟踪的可用性是相当不稳定的(有时你有它们,有时你没有),文档可能更详细(例如gdb
文档声明“-fomit-frame-pointer
在某些机器上无法进行调试。”,没有任何明确的有关x86_64的信息)
此外,在使用gstack
检查正在运行的程序时,我得到了非常完美的堆栈跟踪。但是,我不确定,如果这正是我从gdb
的核心转储中得到的(这意味着我得到的信息越来越少,堆栈真的被破坏了)。
目前,代码是使用-O2
编译的。我最近看到了一个堆栈跟踪,其中我们自己的程序代码的堆栈帧没有任何函数参数值,但是我们的代码已经称为第三方库的第一个(内部)框架提供了这些值。在这里,我不确定这是否表明第一方库具有更好的gcc调试选项集,或者这些信息是否在迭代堆栈跟踪的某个时刻丢失了。
我想我的问题是:
gstack
的输出
将gdb附加到正在运行的程序,执行t a a bt
在一个正在运行的程序中称为gcore
,用gdb
打开核心,然后t a a bt
程序中止和系统编写的核心文件,用gdb
打开在假设核心转储存在程序二进制文件且源代码不可用的情况下进行的所有考虑。
“堆栈跟踪质量”是指3个标准:
哪些编译器选项会影响x86_64上的堆栈跟踪质量
-fomit-frame-pointer
是x86_64
的默认值,不会导致堆栈跟踪无法使用。
GDB依赖于展开描述符,你可以用strip
或-fno-unwind-tables
剥离它们(这是不明智的)。
这些来源的堆栈痕迹是相同的: - 正在运行的程序的gstack输出
最后我看,gstack
是一个简单的shell脚本,调用gdb
,所以是的。
- 将gdb附加到正在运行的程序中,执行“t a a bt”
是。
- 在正在运行的程序上调用gcore,用gdb打开核心,然后“t a a bt”
是的,前提是core
在运行gcore
的同一系统上使用GDB打开。
- 程序中止和系统编写的核心文件,用gdb打开
与上述相同。
如果您尝试在与生成它的系统不同的系统上打开core
,并且二进制文件使用动态库,则需要适当地使用set sysroot
。请参阅this的问题和答案。
请注意,GDB中堆栈可能看起来已损坏或不可用的原因有几个:
-fno-unwind-tables
或strip
ing.cfi
指令