how to use “sigaltstack” in signal handler program?

久未见 提交于 2019-11-30 07:10:42

Here is a minimal sample program that uses sigaltstack to catch infinite recursion. If you comment out the sigaltstack call or SA_ONSTACK flag, the signal handler will not be able to run because it has no stack left and the program will just crash.

#define _XOPEN_SOURCE 700
#include <signal.h>
#include <unistd.h>
void handler(int sig)
{
    write(2, "stack overflow\n", 15);
    _exit(1);
}
unsigned infinite_recursion(unsigned x) {
    return infinite_recursion(x)+1;
}
int main()
{
    static char stack[SIGSTKSZ];
    stack_t ss = {
        .ss_size = SIGSTKSZ,
        .ss_sp = stack,
    };
    struct sigaction sa = {
        .sa_handler = handler,
        .sa_flags = SA_ONSTACK
    };
    sigaltstack(&ss, 0);
    sigfillset(&sa.sa_mask);
    sigaction(SIGSEGV, &sa, 0);
    infinite_recursion(0);
}

A more sophisticated use might actually perform siglongjmp to jump out of the signal handler and back to a point where the infinite recursion can be avoided. This is not valid if async-signal-unsafe library calls are being used, or if your data might be left in an unsafe/unrecoverable state, but if you're performing pure arithmetic computations, it may be valid.

Perhaps a better task for the signal handler would be performing an emergency dump of any valuable/critical data that wasn't already saved to disk. This could be difficult if you can't call async-signal-unsafe functions, but it's usually possible if you put some effort into it.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!