Bug 26397 - Program crashes when rethrowing exception
Summary: Program crashes when rethrowing exception
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 4.0.2
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-02-21 15:55 UTC by michael.klein@fazi.de
Modified: 2009-06-10 11:45 UTC (History)
4 users (show)

See Also:
Host: powerpc-ibm-aix5.2.0.0
Target: powerpc-ibm-aix5.2.0.0
Build: powerpc-ibm-aix5.2.0.0
Known to work:
Known to fail:
Last reconfirmed:


Attachments
Preprocessed source (45.96 KB, application/gzip)
2006-02-21 15:57 UTC, michael.klein@fazi.de
Details
Sample code that exhibits segmentation fault (94 bytes, text/plain)
2006-07-07 18:25 UTC, Stuart Downing
Details

Note You need to log in before you can comment on or make changes to this bug.
Description michael.klein@fazi.de 2006-02-21 15:55:30 UTC
The program below crashes with illegal instruction when rethrowing the previously caught exception.

GCC version:

$ powerpc-ibm-aix5.2.0.0-gcc-4.0.2 -v
Using built-in specs.
Target: powerpc-ibm-aix5.2.0.0
Configured with: ../gcc-4.0.2/configure --disable-nls --enable-threads=posix --enable-languages=c,c++ --disable-shared --enable-version-specific-runtime-libs 
Thread model: aix
gcc version 4.0.2

$ powerpc-ibm-aix5.2.0.0-gcc-4.0.2 exctest.cpp -lstdc++ -o exctest


#include <string>

struct FzException
{
  const char *what()
  {
    mWhat = std::string("a") + std::string("b");
    return mWhat.c_str();
  }

  std::string mWhat;
};


int main(int, char **argv)
{
  try
  {
    try
    {
      throw FzException();
    }
    catch(FzException & e)
    {
      e.what();
      throw;
    }
  }
  catch(...)
  {
    exit(1);
  }
}
Comment 1 michael.klein@fazi.de 2006-02-21 15:57:39 UTC
Created attachment 10887 [details]
Preprocessed source
Comment 2 Andrew Pinski 2006-02-21 16:05:26 UTC
$ powerpc-ibm-aix5.2.0.0-gcc-4.0.2 exctest.cpp -lstdc++ -o exctest

Can you try linking with:
$ powerpc-ibm-aix5.2.0.0-g++-4.0.2 exctest.cpp  -o exctest

instead and see if that helps?
Comment 3 michael.klein@fazi.de 2006-02-21 16:21:05 UTC
Didn't help, same result with powerpc-ibm-aix5.2.0.0-g++ (there is no powerpc-ibm-aix5.2.0.0-g++-4.0.2 here).
Comment 4 David Edelsohn 2006-04-14 17:52:10 UTC
The testcase works for me.  I am a little confused about what you actually have installed if you have "gcc" and "g++" installed with different names (with and without -4.0.2).  Do you have a consistent G++ installation or are you mixing and matching different G++?  Somehow using different versions of the compiler and libraries?
Comment 5 michael.klein@fazi.de 2006-04-24 09:26:39 UTC
Actually, gcc is installed both with *and* without "-X.Y.Z" on all machines here except the Debian Linuxes (AIX, HP-UX, Solaris), but none of them carries a g++ ending with "-X.Y.Z".

According to truss, libstdc++.a and libgcc.a are definitely pulled from /usr/local/lib/gcc/powerpc-ibm-aix5.2.0.0/4.0.2

Anyway, I just noticed something odd, the program works when:
- compiled and linked with 3.3.6
- compiled with 3.3.6, linked with 4.0.2
- compiled with 4.0.2, linked with 3.3.6

And the program only crashes if it is compiled *and* linked with 4.0.2. Any reasonable explanation for this?
Comment 6 Mark Woollard 2006-06-07 23:13:14 UTC
I have come across this issue too. It seems that if the exception being thrown is passed back across a function call then the rethrow will cause a segfault. If the catch and rethrow are in the same function as the original throw then the issue does not reveal itself. Example code that causes the problem is below and I have tested with this against compilers from 3.4.3 through to 4.1.1. The same code behaves correctly on all other platforms we work with.

#include <iostream>
#include <string>
#include <exception>

class derived : public std::exception
{
public:
	derived( const std::string &m ) : msg(m) { }
	virtual ~derived() throw() {}
	
	const char *what() const throw()
	{
		return msg.c_str( );
	}	
	
private:
	std::string msg;
};

void test( )
{
	derived e("Screwed");
	throw e;
}

int main ( int argc, char * argv[] )
{
	try
	{
		try
		{
			test( ); 
                        // Switching to the following in place of calling test() works correctly
                        // derived e("Screwed"); throw e; 
		}
		catch( const std::exception &e )
		{		
			std::cout << "Inner catch: " << e.what() << std::endl;
			throw; // Segfaults
		}
	}
	catch( const std::exception & e )
	{
		std::cout << "Outer catch: " << e.what() << std::endl;
	}
	
	return 0;
}
Comment 7 Stuart Downing 2006-07-07 18:25:59 UTC
Created attachment 11852 [details]
Sample code that exhibits segmentation fault

This is a simplified code sample that produces the symptom
Comment 8 Stuart Downing 2006-07-07 18:28:24 UTC
We are also observing this symptom, but only when gcc is configured with --disable-shared.

This configuration...

/devp/src/bld/gcc4.1.1.s/usr/local/bin/g++ -v
Target: powerpc-ibm-aix5.1.0.0
Configured with: /devp/src/gcc-4.1.1/configure --enable-languages=c,c++ --disable-nls --disable-threads --disable-shared
Thread model: aix
gcc version 4.1.1

exhibits a segmentation fault

but this one

/devp/src/bld/gcc4.1.1/usr/local/bin/g++ -
Using built-in specs.
Target: powerpc-ibm-aix5.1.0.0
Configured with: /devp/src/gcc-4.1.1/configure --enable-languages=c,c++ --disable-nls --disable-threads --enable-shared
Thread model: aix
gcc version 4.1.1

does not.
Comment 9 David Edelsohn 2008-10-15 12:29:31 UTC
Proper G++ exception handling requires shared libraries.
Comment 10 Stuart Downing 2008-10-15 13:43:40 UTC
(In reply to comment #9)
> Proper G++ exception handling requires shared libraries.
> 

Why?  This is not the case on other target platforms. 
Comment 11 David Edelsohn 2008-10-15 15:34:38 UTC
You can try manually linking the program with libsupc++.a as well:

http://codesynthesis.com/~boris/blog/2006/12/10/statically-linking-on-aix/
Comment 12 David Edelsohn 2008-11-06 15:34:06 UTC
Subject: Bug 26397

Author: dje
Date: Thu Nov  6 15:32:40 2008
New Revision: 141646

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=141646
Log:
        PR target/26397
        * config/rs6000/aix.h (LIBSTDCXX_STATIC): Define.

	cp/
        * g++spec.c (LIBSTDCXX_STATIC): New.
        (lang_spec_driver): Use LIBSTDCXX_STATIC when not shared_libgcc.

Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/config/rs6000/aix.h
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/g++spec.c

Comment 13 Jonathan Wakely 2009-06-10 11:45:59 UTC
(In reply to comment #12)
> Subject: Bug 26397
> 
> Author: dje
> Date: Thu Nov  6 15:32:40 2008
> New Revision: 141646
> 
> URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=141646
> Log:
>         PR target/26397
>         * config/rs6000/aix.h (LIBSTDCXX_STATIC): Define.
> 
>         cp/
>         * g++spec.c (LIBSTDCXX_STATIC): New.
>         (lang_spec_driver): Use LIBSTDCXX_STATIC when not shared_libgcc.
> 
> Modified:
>     trunk/gcc/ChangeLog
>     trunk/gcc/config/rs6000/aix.h
>     trunk/gcc/cp/ChangeLog
>     trunk/gcc/cp/g++spec.c
> 

http://gcc.gnu.org/ml/gcc/2009-06/msg00231.html shows that the string "-lstdc++ -lsupc++" is passed to collect2 as a single argument via execvp, resulting in an attempt to link to "libstdc++ -lsupc++" which is not valid.