首页 > 解决方案 > 发布代码的 gdb 堆栈跟踪可读性如何影响 x64?

问题描述

我正在开发一个项目,其中出现了“我们希望在发布构建堆栈跟踪中获得更多信息”的请求。

对于“堆栈跟踪”,我基本上是指of t a a btin 中的输出gdb,我认为它相当于 gstack 正在运行的进程的输出。如果这是真的,那将是我的问题之一。

我的主要问题是堆栈跟踪的可用性相当不稳定(有时你有它们,有时你没有)并且文档可能更详细(例如gdb文档声明“-fomit-frame-pointer使得在某些机器上无法调试。”,没有任何明确的信息关于x86_64)

此外,当使用 来检查正在运行的程序时gstack,我得到了非常完美的堆栈跟踪。不过,我不确定这是否正是我从核心转储中得到的gdb(这意味着在我获得较少信息的所有情况下,堆栈都已真正损坏)。

目前,代码是用-O2. 我最近看到了一个堆栈跟踪,我们自己的程序代码的堆栈帧没有任何函数参数值,但是我们的代码已经调用第三方库的第一个(内部)帧提供了这些值。在这里,我不确定这是否表明第一方库设置了更好的 gcc 调试选项,或者这些信息是否只是在迭代堆栈跟踪时丢失了。

我想我的问题是:

所有考虑都是在核心转储程序二进制文件存在且源代码不可用的假设下进行的。

对于“堆栈跟踪的质量”,我的意思是 3 个标准:

标签: c++gccgdb

解决方案


哪些编译器选项会影响 x86_64 上的堆栈跟踪质量

-fomit-frame-pointer默认设置x86_64不会导致堆栈跟踪不可用。

GDB 依赖于展开描述符,您可以使用stripor删除这些描述符-fno-unwind-tables(这是不明智的做法)。

来自这些来源的堆栈跟踪是否相同:
- 正在运行的程序的 gstack 的输出

最后我看了一下,gstack是一个简单的 shell 脚本,它调用了gdb,所以是的。

  • 将 gdb 附加到正在运行的程序,执行“taa bt”

是的。

  • 在正在运行的程序上调用 gcore,用 gdb 打开核心,然后“taa bt”

是的,只要在运行的同一系统core上使用 GDB 打开。gcore

  • 程序中止和系统编写的核心文件,用gdb打开

和上面一样。

如果您尝试core在与生成它的系统不同的系统上打开,并且二进制文件使用动态库,则需要set sysroot适当地打开。请参阅问题和答案。

请注意,堆栈在 GDB 中可能看起来已损坏或不可用有几个原因:

  • -fno-unwind-tables或者strip上面提到的
  • 从汇编编译的代码,并且缺少正确的.cfi指令
  • 使用非常旧的编译器构建的第三方库,并且具有不正确的展开描述符(gcc-4.4 之前的任何东西都非常糟糕)。
  • 最后,堆栈损坏。

推荐阅读