http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49146
Summary: segv from libgcc_s when raising an exception, or unwinding stack with backtrace Product: gcc Version: 4.4.6 Status: UNCONFIRMED Severity: critical Priority: P3 Component: target AssignedTo: unassig...@gcc.gnu.org ReportedBy: ariel.bur...@roguewave.com Created attachment 24346 --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=24346 preprocessed file for t_exception.cpp Unwinding the stack through a frame for a function annotated with __attribute__((ms_abi)) causes a segv from libgcc_s. System type: linux x8664, gcc 4.4.6, 4.5.3, and 4.6.0. This error can be reproduced in two ways. The first is to throw an exception and there is a function annotated with __attribute__((ms_abi)) between where it's thrown and where it's caught. The other is to call the (libc) function backtrace. On most contemporary linux x8664 distributions, backtrace calls code in libgcc_s.so. Note also that in this case the backtrace shown for f looks wrong (it has too few frames). The segv occurs in the unwind code in libgcc_s.so. This is output of gcc -v: Using built-in specs. Target: x86_64-unknown-linux-gnu Configured with: /packages/gcc-4.4.6/src/gcc-4.4.6/configure --prefix=/packages/gcc-4.4.6/linux-x8664/installation --with-gmp=/packages/gcc-4.4.6/linux-x8664/installation --with-mpfr=/packages/gcc-4.4.6/linux-x8664/installation --with-mpc=/packages/gcc-4.4.6/linux-x8664/installation --enable-languages=c,c++,fortran Thread model: posix gcc version 4.4.6 (GCC) This is how I built the sample programs: /packages/gcc-4.4.6/linux-x8664/installation/bin/g++ -save-temps -g ../ms_abi-reproducer/t_exception.cpp -o t_exception -Wl,-rpath,/packages/gcc-4.4.6/linux-x8664/installation/lib64 /packages/gcc-4.4.6/linux-x8664/installation/bin/gcc -save-temps -g ../ms_abi-reproducer/t_repro.c -o t_repro -Wl,-rpath,/packages/gcc-4.4.6/linux-x8664/installation/lib64 I submit the preprocessed files as attachments. This is the source for the two programs: t_exception.cpp #include <stdio.h> struct E { }; void f ( int arg ) { if ( arg > 0 ) { f ( arg - 1 ); } else { throw E (); } } /* f */ int __attribute__((ms_abi)) f_ms_abi ( int arg ) { if ( arg > 0 ) { f_ms_abi ( arg - 1 ); } else { throw E (); } } /* f_ms_abi */ int main ( int argc, char *argv [] ) { printf ( "calling f\n" ); try { f ( 6 ); } catch ( ... ) { printf ( "caught exception thrown by f\n" ); } printf ( "calling f_ms_abi\n" ); try { f_ms_abi ( 6 ); } catch ( ... ) { printf ( "caught exception thrown by f_ms_abi\n" ); } return 0; } /* main */ t_repro.c: #include <stdio.h> #include <execinfo.h> void do_backtrace (void) { void *pcs [ 64 ]; int max_pcs = sizeof ( pcs ) / sizeof ( pcs [ 0 ] ); int num_pcs = backtrace ( pcs, max_pcs ); int i; for ( i = 0; i < num_pcs; i ++ ) printf ( " %2d: %p\n", i, pcs [ i ] ); } /* do_backtrace */ void f ( int arg ) { if ( arg > 0 ) { f ( arg - 1 ); } else { do_backtrace (); } } /* f */ int __attribute__((ms_abi)) f_ms_abi ( int arg ) { if ( arg > 0 ) { f_ms_abi ( arg - 1 ); } else { do_backtrace (); } } /* f_ms_abi */ int main ( int argc, char *argv [] ) { printf ( "calling f\n" ); f ( 6 ); printf ( "calling f_ms_abi\n" ); f_ms_abi ( 6 ); return 0; } /* main */