我们有一个服务器(用C和C ++编写),它当前捕获一个SEGV并将一些内部信息转储到一个文件中。我想生成一个核心文件,并在我们捕获SEGV时将其写入磁盘,因此我们的支持代表和客户不必为ulimit大惊小怪,然后等待崩溃再次发生以获得核心文件。我们过去曾使用过中止功能,但它受到ulimit规则的约束而无效。
我们有一些遗留代码读取/ proc / pid / map并手动生成核心文件,但它已过时,并且看起来不太便携(例如,我猜它不会起作用)我们的64位版本)。在Linux进程中生成和转储核心文件的最佳方法是什么?
答案 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处理这种情况的方法:
答案 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,如果堆损坏,它可能会失败。