我有一个非常复杂的跨平台应用程序。最近,我和我的团队一直在运行压力测试,遇到了几次崩溃(以及随之而来的核心转储)。其中一些核心转储非常精确,并向我展示了大约 10 个或更多堆栈帧发生崩溃的确切位置。其他人有时只有一个堆栈框架,带有 ??成为唯一的象征!
我想知道的是:
- 有没有办法增加核心转储指向正确方向的可能性?
- 为什么报告的堆栈帧数量不一致?
- 关于管理核心转储的任何最佳实践建议。
以下是我编译二进制文件的方式(在 Release模式下):
- 编译器和平台:g++ with glibc-2.3.2-95.50 on CentOS 3.6 x86_64 -- 这有助于我保持与旧版 Linux 的兼容性。
- 所有文件都使用 -g 标志编译。
- 调试符号从最终二进制文件中剥离并保存在单独的文件中。
- 当我有核心转储时,我将 GDB 与创建核心的可执行文件和符号文件一起使用。 GDB 从不提示核心/二进制/符号之间存在不匹配。
但有时我会得到根本没有符号的核心转储!可以理解我正在链接非调试版本的 libstdc++ 和 libgcc,但如果至少堆栈跟踪显示我的代码中错误指令调用的起源位置(尽管它最终可能以 ?? 结尾),那就太好了.
最佳答案
Others sometimes have just one stack frame with "??" being the only symbol!
这可能有很多原因,其中包括:
- 栈帧被破坏(覆盖)
- EBP/RBP(在 x86/x64 上)目前没有任何有意义的值(value)——这可能会发生,例如在使用
-fomit-frame-pointer
编译的单元或这样做的 asm 单元中
请注意,第二点可能只是通过以这种方式编译 glibc 等方式发生。安装此类系统库的调试信息可以缓解这种情况(类似于 openSUSE 上的 glibc-debug{info,source} 包)。
gdb 比 glibc 对程序有更多的控制,所以 glibc 的 backtrace
调用自然无法打印回溯,如果 gdb 也不能这样做的话。
但运送源代码会容易得多:-)
关于linux - 如何增加 Linux 核心转储匹配符号的概率?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4613876/