在x64上发布代码的gdb堆栈跟踪可读性如何受到影响?

时间:2018-09-17 15:08:03

标签: c++ gcc gdb

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

对于“堆栈跟踪”,我基本上是指of t a a bt中的输出gdb,我想它相当于正在运行的进程的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个标准:

  • 可以使用被叫函数名,而不仅仅是“ ??”
  • 源代码文件名和行号可用
  • 功能调用参数可用。

1 个答案:

答案 0 :(得分:1)

  

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

-fomit-frame-pointerx86_64的默认设置,不会会导致堆栈跟踪不可用。

GDB依赖于展开描述符,您可以 strip-fno-unwind-tables删除它们(这是 ill 的建议)。 / p>

  

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

上次我发现,gstack是一个琐碎的Shell脚本,调用了gdb,所以是。

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

是的

  
      
  • 在运行的程序上称为gcore,先用gdb打开core,然后“ t a bt”
  •   

是的,提供了 core是在运行gcore相同系统上通过GDB打开的。

  
      
  • 程序中止,系统写入了核心文件,并使用gdb打开了
  •   

与上述相同。

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

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

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