【问题标题】:How to generate core dump file without crash/segfault for c/c++ program如何为 c/c++ 程序生成没有崩溃/段错误的核心转储文件
【发布时间】:2020-06-06 15:35:58
【问题描述】:

当 c/c++ 程序崩溃/segfault 时,系统会生成一个核心转储文件,然后我们可以使用 gdb 来检查每个核心转储文件的回溯。 但在某些情况下,程序可能不会崩溃,但我们还想检查回溯,即我们想为程序生成一个核心转储文件。有什么方法可以实现吗?

【问题讨论】:

  • 您可以使用:github.com/JochenKalmbach/StackWalker 效果很好。
  • 为什么不设置断点并查看回溯?为什么要为此生成核心转储?
  • raise(SIGTRAP)
  • 或者更好,如果你想在一个特定的地方回溯而不杀死进程if (fork() == 0) raise (SIGTRAP);
  • @Oliv: SIGTRAP 可以被抓到。 SIGKILL不能,见signal(7)(假设是Linux系统)

标签: c++ gdb


【解决方案1】:

在某些情况下,程序可能不会崩溃,但我们也想检查回溯,即我们想为程序生成一个核心转储文件,

你的“即”不遵循:您可以轻松地生成回溯而不生成核心转储。

由于您的问题有 gdb 标签,我假设您想从程序本身的 outside 执行此操作(有一些方法可以从程序的 inside 执行此操作好)。

许多系统都有backtrace GDB 包装器,但您可以像这样使用“vanilla”GDB 做到这一点:

gdb --batch -q -p $PID -ex 'where' -ex 'quit'
gdb --batch -q -p $PID -ex 'thread apply all where' -ex 'quit'

$PID 替换为您想要获取堆栈跟踪的实际进程ID。 如果您想要所有线程的堆栈跟踪,请对多线程程序使用第二种形式。

如果你真的想在不杀死程序的情况下保存内核,GDB 可以使用gcore 命令来实现。

【讨论】:

    【解决方案2】:

    但在某些情况下,程序可能不会崩溃,但我们也想检查回溯

    对于这种情况,我建议使用好的回溯库。使用 Ian Taylor 的 libbacktrace(用于在 Linux 上使用 DWARF 调试信息编译的 C++ 代码,例如使用 g++ -O1 -g2 -Wall 编译),你会得到一个很好的。

    我很乐意在运行时使用它,在我的RefPerSys 项目中(例如,参见它的issue#25)。当然GCC 也使用它(巧妙地报告致命错误)。

    当然,GNU libc 也有 backtrace 功能。在 Linux 上,您可以将它们与 dladdr(3) 结合使用。

    我们要生成一个核心转储文件

    在 Linux 上,我建议为此使用 gcore(1)

    当然,在 Linux 上可以在运行时禁用核心转储。请参阅 core(5)setrlimit(2)。并且一些内存可能不会被转储,请参阅mmap(2)elf(5)

    PS。在非 Linux 系统上(例如FreeBSDSolaris 等...),gdb 行为和core 转储可能完全不同...。

    【讨论】:

    • 在 linux 上,可以使用 /proc/pid/coredump_filter 自定义转储的内容
    • 是的,如上述答案中提到的core(5) 中所述
    猜你喜欢
    • 1970-01-01
    • 2012-05-27
    • 2019-01-14
    • 2012-12-30
    • 1970-01-01
    • 2015-01-21
    • 1970-01-01
    • 1970-01-01
    • 2017-11-10
    相关资源
    最近更新 更多