从进程内部转储Linux核心文件的好方法是什么?

时间:2008-11-25 19:54:20

标签: linux gdb

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

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

8 个答案:

答案 0 :(得分:9)

Google有一个库,用于在名为google-coredumper的正在运行的进程中生成coredump。这应该忽略ulimit和其他机制。

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

答案 1 :(得分:5)

我看到pmbrett's post并认为“嘿,那很酷”,但在我的系统(Gentoo)的任何地方找不到该实用程序。

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

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

似乎对我很好。

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

答案 2 :(得分:4)

尝试使用Linux命令gcore

用法:gcore [-o filename] pid

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

答案 3 :(得分:3)

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

  1. 修复ulimit !!!
  2. 接受您没有获得核心文件并在gdb中运行,脚本化以在SIGSEGV上执行“thread all apply bt”
  3. 接受您没有获得核心文件并从应用程序中获取堆栈跟踪。 Stack Backtracing Inside Your Program文章已经很老了,但这些日子也应该有可能。

答案 4 :(得分:1)

您还可以使用setrlimit(2)从程序中更改ulimit()。与ulimit shell命令一样,这可以降低限制,或者像硬限制允许的那样提高它们。在启动时setrlimit()允许核心转储,你没事。

答案 5 :(得分:1)

我假设您有一个捕获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);
}

答案 6 :(得分:0)

system(“kill -6”)

如果你还在找东西,我试试看。

答案 7 :(得分:0)

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