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 */

Reply via email to