13

我们有一个服务器(用 C 和 C++ 编写),它当前捕获一个 SEGV 并将一些内部信息转储到一个文件中。我想在我们捕获 SEGV 时生成一个核心文件并将其写入磁盘,因此我们的支持代表和客户不必对 ulimit 大惊小怪,然后等待崩溃再次发生以获得核心文件。我们过去曾使用过 abort 函数,但它受制于 ulimit 规则并且没有帮助。

我们有一些读取 /proc/pid/map 并手动生成核心文件的遗留代码,但它已经过时,并且看起来不太便携(例如,我猜它在我们的 64 位中不起作用构建)。在 Linux 进程中生成和转储核心文件的最佳方法是什么?

4

8 回答 8

9

谷歌有一个库,用于从名为google-coredumper的运行进程内部生成核心转储。这应该忽略 ulimit 和其他机制。

生成核心文件的调用文档在此处。根据文档,在信号处理程序中生成核心文件似乎是可行的,但不能保证始终有效。

于 2008-12-03T18:47:22.850 回答
5

我看到pmbrett 的帖子并认为“嘿,这很酷”,但在我的系统(Gentoo)上的任何地方都找不到该实用程序。

所以我做了一些刺激,发现 GDB 有这个选项。

gdb --pid=4049 --batch -ex gcore

似乎对我来说工作得很好。

但是它不是很有用,因为它捕获了当时正在使用的最低功能,但除此之外它仍然做得很好(没有内存限制,用它转储了 350M 的 firefox 进程快照)

于 2008-11-29T17:37:26.550 回答
4

尝试使用 Linux 命令 gcore

用法:gcore [-o 文件名] pid

您需要使用 system(或 exec)和 getpid() 来构建正确的命令行以从您的进程中调用它

于 2008-11-29T01:38:46.063 回答
3

一些可能的解决方案^W处理这种情况的方法:

  1. 修复ulimit!!!
  2. 接受你没有得到核心文件并在 gdb 中运行,脚本在 SIGSEGV 上执行“线程全部应用 bt”
  3. 接受您没有获得核心文件并从应用程序中获取堆栈跟踪的事实。The Stack Backtracing Inside Your Program文章已经很老了,但现在应该也可以了。
于 2008-11-25T21:05:33.353 回答
2

您还可以使用 setrlimit(2) 从程序中更改 ulimit()。与 ulimit shell 命令一样,这可以降低限制,或者在硬限制允许的范围内尽可能提高限制。在启动时 setrlimit() 允许核心转储,你很好。

于 2008-12-30T11:51:23.967 回答
2

例如,我假设您有一个信号处理程序可以捕获 SEGV,并执行诸如打印消息和调用 _exit() 之类的操作。(否则,您首先会有一个核心文件!)您可以执行以下操作。

void my_handler(int sig)
{
   ...
   if (wantCore_ && !fork()) {
      setrlimit(...);  // ulimit -Sc unlimited
      sigset(sig, SIG_DFL);  // reset default handler
      raise(sig);  // doesn't return, generates a core file
   }
   _exit(1);
}
于 2011-09-07T19:33:49.167 回答
1

使用 backtrace 和 backtrace_symbols glibc 调用来获取跟踪,请记住 backtrace_symbols 在内部使用 malloc,如果堆损坏,它可能会失败。

于 2010-11-11T17:10:28.827 回答
0

系统(“杀死 -6”)

如果您仍在寻找某些东西,我会尝试一下

于 2009-03-27T04:16:43.830 回答