c++ - 发布代码的 gdb 堆栈跟踪可读性如何影响 x64?
问题描述
我正在开发一个项目,其中出现了“我们希望在发布构建堆栈跟踪中获得更多信息”的请求。
对于“堆栈跟踪”,我基本上是指of t a a bt
in 中的输出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 个标准:
- 调用的函数名称可用,而不仅仅是“??”
- 源代码文件名和行号可用
- 函数调用参数可用。
解决方案
哪些编译器选项会影响 x86_64 上的堆栈跟踪质量
是-fomit-frame-pointer
默认设置x86_64
,不会导致堆栈跟踪不可用。
GDB 依赖于展开描述符,您可以使用strip
or删除这些描述符-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 之前的任何东西都非常糟糕)。
- 最后,堆栈损坏。
推荐阅读
- c# - 计算数组中的元素 - 性能 -
- python - 当每个脚本在 python 中有多个线程时,从主脚本同时运行两个脚本
- javascript - 无法使用谷歌地图标记,并出现 javascript 全局变量问题
- c# - 等待同步的异步方法是否可以接受?
- oracle - Oracle 高级队列与小型 Oracle 数据库表
- c# - 当轴是修复部分图表的范围时,整个图表的光标不可见并且轴标签重叠
- magento2 - 在类别页面上加载更多不适用于波尔图主题 magento 2 的产品
- node.js - Jest Express 使用参数测试中间件
- node.js - 每当我的页面在 DialogFlow 中刷新时,如何设置我的标志变量 0?
- cookies - Pm.cookies.jar 找不到 secure=true 的 cookie