Throwing an exception from within a signal handler

后端 未结 7 1964
半阙折子戏
半阙折子戏 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:48

    This code demonstrates a technique which moves the throwing of the exception out of the signal handler into the code. My thanks to Charles for the idea.

    #include 
    #include 
    #include 
    
    using namespace std;
    
    jmp_buf gBuffer;        // A buffer to hold info on where to jump to
    
    void catch_signal(int signalNumber)
    {
        //signal(SIGINT, SIG_DFL);          // Switch to default handling
        signal(SIGINT, catch_signal);       // Reactivate this handler.
    
        longjmp             // Jump back into the normal flow of the program
        (
            gBuffer,        // using this context to say where to jump to
            signalNumber    // and passing back the value of the signal.
        );
    }
    
    
    int test_signal()
    {
        signal(SIGINT, catch_signal);
    
        try
        {
            int sig;
            if ((sig = setjmp(gBuffer)) == 0) 
            {
                cout << "before raise\n";
                raise(SIGINT);
                cout << "after raise\n";
    
            }
            else
            {
                // This path implies that a signal was thrown, and
                // that the setjmp function returned the signal
                // which puts use at this point.
    
                // Now that we are out of the signal handler it is
                // normally safe to throw what ever sort of exception we want.
                throw(sig);
            }
        }
        catch (int &z)
        {
            cerr << "Caught exception: " << z << endl;
        }
    
        return 0;
    }
    
    int main()
    {
        try
        {
            test_signal();
        }
        catch (int &z)
        {
            cerr << "Caught unexpected exception: " << z << endl;
        }
        return 0;
    }
    

提交回复
热议问题