# On g++-sjlj.exe (GCC) 4.2.1-sjlj (mingw32 sjlj-unwind) Using built-in specs. Target: mingw32 Configured with: ../gcc-4.2.1/configure --with-gcc --enable-libgomp --host=mingw32 --build=mingw32 --target=mingw32 --program-suffix=-sjlj --with-arch=i486 --with-tune=generic --disable-werror --prefix=/mingw --with-local-prefix=/mingw --enable-threads --disable-nls --enable-languages=c,c++,fortran,objc,obj-c++,ada --disable-win32-registry --enable-sjlj-exceptions --enable-libstdcxx-debug --enable-cxx-flags=-fno-function-sections -fno-data-sections --enable-version-specific-runtime-libs --disable-bootstrap Thread model: win32 gcc version 4.2.1-sjlj (mingw32 sjlj-unwind) # Also # On gcc version 3.4.4 (cygming special, gdc 0.12, using dmd 0.125)
<testcase1.cc>-------------------------------- #include <stdio.h> #include <signal.h> void signal_handler(int signo) { fprintf(stderr,"signaled\n"); throw 1; } int main() { signal(SIGSEGV,signal_handler); try { printf((char*)9); //<---(A) } catch(...) { fprintf(stderr,"exception caught"); } } <testcase2.cc>----------------------------------- #include <stdio.h> #include <signal.h> void signal_handler(int signo) { fprintf(stderr,"signaled\n"); throw 1; } int main() { signal(SIGSEGV,signal_handler); try { *(int*)0 = 0; //<---(B) } catch(...) { fprintf(stderr,"exception caught"); } } <disassembled main()-testcase2.cc>------------ //compiled as: g++sjlj testcase2.cc -g //gcc 4.2.1 int main() 4013f0: 8d 4c 24 04 lea 0x4(%esp),%ecx 4013f4: 83 e4 f0 and $0xfffffff0,%esp 4013f7: ff 71 fc pushl 0xfffffffc(%ecx) 4013fa: 55 push %ebp 4013fb: 89 e5 mov %esp,%ebp 4013fd: 51 push %ecx 4013fe: 83 ec 14 sub $0x14,%esp 401401: e8 6a ff ff ff call 401370 <__main> { signal(SIGSEGV,signal_handler); 401406: c7 44 24 04 34 14 40 movl $0x401434,0x4(%esp) 40140d: 00 40140e: c7 04 24 0b 00 00 00 movl $0xb,(%esp) 401415: e8 46 7b 00 00 call 408f60 <signal> try { *(int*)0 = 0; //<---(B) 40141a: b8 00 00 00 00 mov $0x0,%eax 40141f: c7 00 00 00 00 00 movl $0x0,(%eax) 401425: b8 00 00 00 00 mov $0x0,%eax } catch(...) { fprintf(stderr,"exception caught"); } } 40142a: 83 c4 14 add $0x14,%esp 40142d: 59 pop %ecx 40142e: 5d pop %ebp 40142f: 8d 61 fc lea 0xfffffffc(%ecx),%esp 401432: c3 ret -------------------------------------------------------- <testcase1.cc> and <testcase2.cc> are identical except for (A),(B). For <testcase1.cc>, <testcase2.cc> common: Both (A) and (B) are supposed to throw no exception in C++ semantics. So no need to generate the codes(<C1> hereafter) for adjusting the call site value for (A),(B). And the hole try block is supposed to throw no exception in C++ semantics. So no need to generate the codes(<C2>) for the catch block at all. But Gcc generates codes differently: (Regardless of optimization) For <testcase1.cc>, Gcc generates the codes of both <C1>,<C2> while for <testcase2.cc>, none as shown in <disassembled main()-testcase2.cc>, which crashs testcase2. Are C++ exceptions considered to be thrown from extern "C" functions (under some conditions) but not from signal handlers? If so, it matters as in the tese cases above where C++ exceptions can be thrown from signal handlers. Adding an option would be nice. Microsoft VisualC++ has similar problem when optimizing with -EHs option. But option -EHa forces the compiler to generate proper codes (regardless of optimization), which makes the traslation from Windows exception to C++ exception safe. -- Summary: (exception handling) bad/inconsistent code generation Product: gcc Version: 4.2.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: darkxun at paran dot com http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33900