SIGSEGV处理程序中的段错误 [英] Segfault in SIGSEGV handler

查看:135
本文介绍了SIGSEGV处理程序中的段错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我具有以下C代码:

Lets assume I have the following C code:

static void handler(int sig, siginfo_t *si, void *unused)
{
    printf("BOOM!\n");

    //another segfault here

    exit(-1);
}

int main(int argc, char *argv[])
{
    struct sigaction sa;

    sa.sa_flags = SA_SIGINFO;
    sigemptyset(&sa.sa_mask);
    sa.sa_sigaction = handler;
    if (sigaction(SIGSEGV, &sa, NULL) == -1)
        perror("failed to set handler");

   // call other stuff here, somewhere in the callstack a segfault happens 

}

如果执行遇到第一个分段错误,则将触发处理程序.但是,如果由于某种原因在处理程序本身中发生分段错误,会发生什么情况呢?会使用新的siginfo_t再次调用处理程序,还是会立即终止程序?

If the execution hits the first segmentation fault the handler will be triggered. But what happens when in the handler itself from some reason a segmentation fault happens? Will it call the handler again with the new siginfo_t or will the program be terminated immediately?

如果再次调用处理程序,则将执行以下操作:

If the handler is called again would something like this work:

int in_handler = 0;
static void handler(int sig, siginfo_t *si, void *unused)
{
    printf("BOOM!\n");
    if(!in_handler) 
    {
         in_handler = 1;
         //code that could possibly segfault
    } else {
         //totally safe code
    }
    exit(-1);
}

我之所以要问的原因是,我目前正在用C语言编写某种单元测试框架.如果一个测试用例由于某种非法的内存访问而失败了,我想将所有剩余的测试标记为失败.如果由于某种原因测试没有真正严重破坏堆,则此操作可能会失败,因为我必须遍历数据结构并将该信息写入xml文件.但是,如果将所有其余测试标记为失败,我仍然希望保留哪个测试是失败的信息.

The reason why I'm asking is that I'm currently writing some sort of unit test framework in C. If a testcase failed due to some illegal memory access I would like to mark all remaining tests as failed. If for some reason the test hast screwed up the heap really badly this operation could fail because I have to iterate over a data structure and write that information to a xml file. But if marking all remaining tests as failed I would still like to preserver the information which test was the failing one.

推荐答案

sigaction(2) :

#include <signal.h>

int sigaction(int signum, const struct sigaction *act, struct sigaction
    *oldact);  

....

sigaction结构定义为类似

          struct sigaction {
              void (*sa_handler)(int);
              void (*sa_sigaction)(int, siginfo_t *, void *);
              sigset_t sa_mask;
              int sa_flags;
              void (*sa_restorer)(void);
          }

....

sa_mask给出应屏蔽的信号掩码 信号处理程序的执行.另外,信号 触发处理程序将被阻止,除非SA_NODEFER标志为 使用.

sa_mask gives a mask of signals which should be blocked during execu- tion of the signal handler. In addition, the signal which triggered the handler will be blocked, unless the SA_NODEFER flag is used.

由于在设置信号处理程序时未设置SA_NODEFER标志,因此如果仍在信号处理程序中发生了另一个段错误,则不会再次调用该标志.退出后,先前被阻止的信号将被传送.

Because you didn't set the SA_NODEFER flag when setting up your signal handler, it won't get called again if another segfault occurs while still in the signal handler. Once you exit, the signal which was previously blocked will then be delivered.

这篇关于SIGSEGV处理程序中的段错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆