强制内核在SIGSEGV挂钩时转储进程
问题描述:
我为具有非常有限的RAM值的系统编写应用程序。由于应用程序崩溃总是可能的,它使用动态内存分配,我创建的回调,所有可能的方式应用可以停止和清理所有的缓冲区那里,就像这样:强制内核在SIGSEGV挂钩时转储进程
sigaddset (&sigact.sa_mask, SIGSEGV);
sigaction (SIGSEGV, &sigact, (struct sigaction*) NULL);
它触发了一些通知的行动,并试图重新启动本身几次。 但我仍然想知道是什么导致了崩溃,所以我需要crashdump。 GDB不适合这么小的系统,只有内核级别的核心转储是可能的。但由于应用程序截获了这样一个信号,毕竟它自己退出,所以内核没有收到信号 - 没有核心创建。
我不能发出
kill(getpid(), kernel_signal);
,因为它导致递归 - 这个信号也被截断。在这种情况下可以吗?
答
也许不是核心转储,你可以打印出一个回溯。这应该使用更少的内存并且是一个可捕获的信号。请看这个信号处理程序。
#include <execinfo.h>
/* This signal handler ensures clean exits while not running in daemon mode */
void signal_handler(int type)
{
fprintf(stderr, "\nSIGNAL CAUGHT: %d: ", type);
switch (type)
{
case SIGSEGV:
{
#ifdef GLIBC
{
void *array[10];
size_t size;
// get void*'s for all entries on the stack
size = backtrace(array, 10);
// print out all the frames to stderr
fprintf(stderr, "Error: signal %d:\n", type);
backtrace_symbols_fd(array, size, STDERR_FILENO);
// DO CLEANUP HERE
}
#else // Cause ulibc is terrible
fprintf(stderr, "SEGMENTATION FAULT");
// DO CLEANUP HERE
break;
}
#endif
case SIGINT:
case SIGTERM:
case SIGHUP:
default:
{
// DO CLEANUP HERE
}
}
}
的['abort'(http://man7.org/linux/man-pages/man3/abort.3.html)功能可以帮助,除非你赶上'SIGABRT'太(你不该“T)。 – 2014-11-22 12:31:03
你尝试过'SIGQUIT'吗? [这个答案](http://*.com/a/5648539/464709)提到它是强制核心转储的正确方法。或者,[unix.se]上的[这个回答](http://unix.stackexchange.com/a/11191)表明分叉进程并让孩子立即中止。它也可能适用于你的情况。 – 2014-11-22 12:31:16
由于某种原因,SIGQUIT不会触发核心创建,但SIGABRT会这样做。 Joachim,请将您的评论作为答案 - 这是正确的。我测试了它,并且它做了我想要的所有 – pugnator 2014-11-22 12:58:57