Throwing an exception from within a signal handler

后端 未结 7 1987
半阙折子戏
半阙折子戏 2020-11-30 03:56

We have a library that deals with many aspects of error reporting. I have been tasked to port this library to Linux. When running though my little test suite, one of the

7条回答
  •  刺人心
    刺人心 (楼主)
    2020-11-30 04:45

    At least in Ubuntu 16.04 x86-64, throwing out of a signal handler seems to work fine. Whether this is by design (i.e. guaranteed to work, rather than working accidentally somehow), I have not researched. I compiled the program below using g++ -o sig-throw sig-throw.cpp:

    #include 
    #include 
    #include 
    #include 
    
    extern "C" void handler(int sig, siginfo_t *info, void *xxx)
    {
        throw "Foo";
    }
    
    int main(int argc, char **argv)
    {
        struct sigaction sa = {0};
    
        sa.sa_sigaction = handler;
    #if 0
        // To ensure SIGALRM doesn't remain blocked once the signal handler raises
        // an exception, either enable the following, or add enable the sigprocmask
        // logic in the exception handler below.
        sa.sa_flags = SA_NODEFER;
    #endif
        sigaction(SIGALRM, &sa, NULL);
    
        alarm(3);
    
        try {
            printf("Sleeping...\n");
            sleep(10);
            printf("Awoke\n"); // syscall interrupted
        }
        catch (...) {
            printf("Exception!\n");
    #if 1
            // To ensure SIGALRM doesn't remain blocked once the signal handler
            // raises an exception, either enable the following, or add enable
            // SA_NODEFER when registering the signal handler.
            sigset_t sigs_alarm;
            sigemptyset(&sigs_alarm);
            sigaddset(&sigs_alarm, SIGALRM);
            sigprocmask(SIG_UNBLOCK, &sigs_alarm, NULL);
    #endif
        }
    
        alarm(3);
    
        try {
            printf("Sleeping...\n");
            sleep(10);
            printf("Awoke\n"); // syscall interrupted
        }
        catch (...) {
            printf("Exception!\n");
        }
    
        return 0;
    }
    

    Here's it running:

    [swarren@swarren-lx1 sig-throw]$ ./sig-throw 
    Sleeping...
    Exception!
    

    For reference:

    [swarren@swarren-lx1 sig-throw]$ lsb_release -a
    ...
    Description:    Ubuntu 16.04.6 LTS
    ...
    
    [swarren@swarren-lx1 sig-throw]$ dpkg -l libc6
    ...
    ii  libc6:amd64  2.23-0ubuntu11  amd64  GNU C Library: Shared libraries
    
    [swarren@swarren-lx1 sig-throw]$ g++ --version
    g++ (Ubuntu 5.4.0-6ubuntu1~16.04.11) 5.4.0 20160609
    

提交回复
热议问题