In our application we want to translate synchronous signals (such as SIGSEGV) to C++ exceptions.
The method is to use throw directly from either: 1 - From the signal handler itself. 2 - From a function called by the signal handler. I'm having trouble getting this to work reliably. Test program attached below. Building and running: $ g++ sigthrow.cpp -fnon-call-exceptions -fexceptions $ a.out terminate called after throwing an instance of 'char const*' Aborted (core dumped) $ Removing option -fnon-call-exceptions gives: $ g++ sigthrow.cpp -fexceptions $ a.out ~StructWithDtor: Count 0 Caught exception So it works, except the frame that generated the exception is not cleaned up (it should call a destructor for another instance of StructWithDtor). The pattern seems to be: 1 - If the function generating the signal has objects to unwind, this is always missed. 2 - Also, when compiled with -fnon-call-exceptions the program often (not always) aborts. 3 - If the function generating the signal does not have objects to unwind it goes well (with or without -fnon-call-exceptions) Are there some other compiler option to make this work? Something to be done in the signal handler? So far I haven't found any working examples of this functionality on the web. But others have found similar difficulties. What is the status of this? It's an important feature when using plugins, script interpreters and linking with code from other languages. Regards // ATS. ----------------- source ------------------------------- #include <stdio.h> #include <csignal> #include <unistd.h> #include <sys/syscall.h> typedef void(*stSignalHandlerFn)(int); struct old_i386_kernel_sigaction { stSignalHandlerFn k_sa_handler; unsigned long k_sa_mask; unsigned long k_sa_flags; void (*sa_restorer) (void); }; void stSigSegvHandler( int dummy ){ void **_p = (void **)&dummy; struct sigcontext_struct *_regs = (struct sigcontext_struct *)++_p; throw "SIGSEGV signaled"; } int g_cnt; struct StructWithDtor { StructWithDtor() : m_cnt(g_cnt++) { } ~StructWithDtor(){ printf("~StructWithDtor: Count %d\n", m_cnt); } int m_cnt; }; int FuncNested1( int *pi ){ StructWithDtor swd; return *pi; } int FuncTop( int *pi ){ StructWithDtor swd; return FuncNested1( pi ); } int main( int argc, const char* argv[] ) { // Install a SIGSEGV handler using syscall struct old_i386_kernel_sigaction kact; kact.k_sa_handler = stSigSegvHandler; kact.k_sa_mask = 0; kact.k_sa_flags = 0; syscall( SYS_sigaction, SIGSEGV, &kact, NULL ); // Trigger SIGSEGV try { FuncTop( NULL ); }catch( ... ){ puts( "Caught exception\n" ); } } -- Summary: Erratic behaviour: Exception translation (throw from signal handlers) Product: gcc Version: 4.1.3 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: asteinarson at gmail dot com GCC build triplet: Linux Ubuntu 7.10, X86-32, gcc 4.1.3 (Ubuntu default) GCC host triplet: Linux Ubuntu 7.10, X86-32, gcc 4.1.3 (Ubuntu default) GCC target triplet: Linux Ubuntu 7.10, X86-32, gcc 4.1.3 (Ubuntu default) http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34152