【发布时间】:2018-09-17 15:08:03
【问题描述】:
我正在处理一个项目,其中出现了“我们希望在发布构建堆栈跟踪中获得更多信息”的请求。
对于“堆栈跟踪”,我的意思基本上是gdb 中的输出of t a a bt,我认为它相当于正在运行的进程的gstack 输出。如果这是真的,那将是我的问题之一。
我的主要问题是堆栈跟踪的可用性相当不稳定(有时你有它们,有时你没有)并且文档可能更详细(例如gdb 文档指出“-fomit-frame-pointer 使得在某些情况下无法调试机器。”,没有关于 x86_64 的任何明确信息)
另外,当使用gstack 检查一个正在运行的程序时,我得到了一个非常完美的堆栈跟踪。不过,我不确定这是否正是我从带有gdb 的核心转储中得到的结果(这意味着在我获得较少信息的所有情况下,堆栈都已真正损坏)。
目前,代码使用-O2 编译。我最近看到了一个堆栈跟踪,我们自己的程序代码的堆栈帧没有任何函数参数值,但是我们的代码已经调用第三方库的第一个(内部)帧提供了这些值。在这里,我不确定这是否表明第一方库设置了更好的 gcc 调试选项,或者这些信息是否只是在迭代堆栈跟踪时丢失了。
我想我的问题是:
- 哪些编译器选项会影响 x86_64 上的堆栈跟踪质量
- 来自这些来源的堆栈跟踪是否相同:
- 正在运行的程序的
gstack的输出 - 将gdb附加到正在运行的程序,执行
t a a bt - 在一个正在运行的程序上调用
gcore,用gdb打开核心,然后t a a bt - 程序中止,系统写入核心文件,以
gdb打开
- 正在运行的程序的
- 是否有一些深入的文档,哪些参数会影响 x86_64 上的堆栈跟踪质量?
所有考虑因素都假设存在核心转储的程序二进制文件,并且源代码不可用。
“堆栈跟踪的质量”是指 3 个标准:
- 调用的函数名可用,而不仅仅是“??”
- 源代码文件名和行号可用
- 函数调用参数可用。
【问题讨论】:
-
是什么产生了堆栈跟踪?堆栈跟踪是如何产生的?是你的代码还是系统?您如何衡量堆栈跟踪质量?在 gstack 中,堆栈跟踪是由 gstack 产生的,你每次都可以在 gstack 下运行你的代码,你为什么不这样做呢? gdb 中的核心转储只是具有寄存器状态的程序的内存映像。调试信息是嵌入在可执行文件中的 DWARF 或其他格式信息。如果“进程转储核心”通常意味着调用
abort(),那么它的打印内容和方式取决于系统。 -
另外,我不建议生成带有调试信息的发布可执行文件,因为这可能会为逆向工程提供大量信息,从而很容易窃取您的工作。
-
@Kamil Cuk:我试图回答您在原始问题中的注释。