强制内核在挂钩SIGSEGV时转储进程

时间:2014-11-22 12:23:50

标签: c linux linux-kernel segmentation-fault sigsegv

我为RAM值非常有限的系统编写应用程序。由于应用程序崩溃始终是可能的并且它使用动态内存分配,因此我为所有可能的方法创建了回调,可以停止应用程序并清理那里的所有缓冲区,如下所示:

sigaddset ( &sigact.sa_mask, SIGSEGV );
sigaction ( SIGSEGV, &sigact, ( struct sigaction* ) NULL );

它触发一些通知操作并尝试多次重启。 但我仍然想知道导致崩溃的原因,所以我需要crashdump。 GDB不适合这么小的系统,只能进行内核级核心转储。 但是当应用程序截获这样的信号并且在它自己退出之后,内核没有接收到信号 - 没有核心被创建。
我无法发出

 kill(getpid(), kernel_signal);

因为它导致递归 - 这个信号也被截获了。在这种情况下是否有可能?

1 个答案:

答案 0 :(得分:2)

也许您可以打印出回溯,而不是核心转储。这应该使用更少的内存,是一个可捕获的信号。请看这个信号处理程序。

#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
        }

    }
}