Linux中的核心转储

我想创build一个核心转储,当我的进程崩溃。 目前我正在采用这种方法:

  1. 使用gcc / g ++的“-g”构build一个特殊的“debugging”版本的程序。
  2. 执行“ulimit -c unlimited”
  3. 现在,无论程序崩溃,我们都会得到核心转储。

但我想尽量减less步骤的数量,以便:

  • 核心转储应该总是被创build。 即使是“释放”构build。 不应要求用户手动执行“ ulimit -c unlimited ”命令。
  • 该核心转储的回溯应该能够给出文件,函数,线路号码的调用。 这是一个人类可读的forms堆栈跟踪。
  • 我不想用“-g”作为debugging版本来构build程序。 或者至less它不应包含任何其他debugging信息,这些信息不会产生可读的堆栈跟踪。 因为这将是该程序的发布版本。

所以我有两个问题:

  1. 如何在程序的“发布”版本中创build核心转储?
  2. 总是。 没有手动执行“ ulimit -c unlimited

Solutions Collecting From Web of "Linux中的核心转储"

通常的解决方案是使用-g编译并在释放文件之前剥离调试信息。 寻找“strip”命令。 您可以使用调试信息保存该文件,并使用它来调试从客户那里获得的核心转储。

如果您想要在用户机器上打印出人类可读的回溯,则需要使用(某些)调试信息分发二进制文件。 在glibc中寻找'backtrace()'函数。

请注意,即使二进制文件不包含调试信息,也会创建核心转储(如果ulimit设置正确)。

确保创建核心转储的最佳方法可能是在运行二进制文件之前,从设置ulimit的脚本执行二进制文件。

  • 关于核心限制,你可以通过调用setrlimit在C中自己完成。
  • 在GNU(glibc)或BSD系统上,可以通过调用backtrace和相关的系统调用来获得回溯。 然后,您将不得不通过运行addr2line (或复制其功能)将函数地址转换为函数名称。
  • 只要不使用-g ,你仍然可以得到一个回溯(除了内联函数不会出现)。

你可以试试google-coredumper:

一个简单的工具,用于在程序运行时从多线程应用程序创建GDB可读的内核。 coredumper库可以编译成应用程序来创建正在运行的程序的核心转储,而不会终止。

http://sourceforge.net/projects/goog-coredumper/

  1. Linux上没有“发布”版本和“调试”版本。 使用“-g”时,您只需创建一个包含调试信息的程序。 你可以去除这些信息。

更新
其实我想我应该说一下我在消息中没有提到的调试和发行版本之间的一个可能的区别。 为了摆脱程序中的所有assert() ,可以使用NDEBUG定义来构建发布版本。 调试版本应该建立在没有定义NDEBUG的情况下,因为assert()有助于查找错误。

但是,如果您不使用assert()则不会有任何区别。

  1. 用户可以在他或她的配置文件中设置ulimit -c unlimited。

  2. 用一些优化编译的程序的回溯通常不会给出有用的行号。

  3. 你可以建立一个带有调试信息的版本并存入你的档案。 然后将其剥离并将剥离的二进制文件交付给您的客户。 如果客户给你一个核心文件,那么只需使用带有调试信息的版本和来自客户的核心文件。

  4. How to create a core dump in the "release" build of a program? 这不是你的责任,这是操作系统的责任。

如果代码是发布模式/高度优化的版本,你几乎不会得到一个体面的栈式跟踪。 使用-g开关或忘记完成一个堆栈跟踪…你不能同时拥有! 这又回到了这一点 – 听起来像你正在预期的代码即使在生产环境中崩溃?

为什么不修复代码,并确保它的工作第一…代码的气味…. 嗅闻

编辑:好吧,我上面的评论可能会遇到一些严厉的,我没有打算在那里苛刻…为了读者的利益,我已经包括了一个链接到另一个问题张贴在这里,并在答案我给,使用信号来创建一个堆栈跟踪和重定向到一个文件。 这将有助于OP的问题,并帮助他解决问题…