This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c++/14113] New: -O2 corrupts stack for small example
- From: "gcc at cohi dot at" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 11 Feb 2004 17:13:48 -0000
- Subject: [Bug c++/14113] New: -O2 corrupts stack for small example
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
SYMPTOM
The following code example crashes in the sense that it acts as if it couldn't
find the (obviously present) try block.
SNIPPET
The following function seems to be the critical one, the full code of the
program is included below. As shown, the problem occurs when compiled with -W
-Wall -O2 and goes away if either -O2 is omitted, or one of the two marked
places is changed:
void A::t2( const std::string & s1, const std::string & s2 )
{
int i;
if ( ! get( i ) )
{
do { std::ostringstream oss; oss << __FILE__ << __LINE__ << " " <<
"kasimir"; throw oss.str(); } while ( 1 ); // normally a THROW() macro
// Change to "throw std::string( "kasimir" );" lets the problem
disappear, althouth this is _not_ the throw that will be executed.
}
switch ( i )
{
case 1:
f1( s1, s2 );
break;
case 2:
f2( s1, s2, false );
break;
case 3:
f2( s1, s2, true );
break;
// Change case 2 and case 3 to
// case 2:
// case 3:
// f2( s1, s2, i == 3 );
// break;
// makes the problem disappear.
case 7:
case 8:
f3( s1, s2 );
break;
}
}
COMPILER
gcc-3.3-20040209/bin/g++ -v
Reading specs from
/opt/global/gcc-3.3-20040209/lib/gcc-lib/sparc-sun-solaris2.8/3.3.3/specs
Configured with: ./configure --prefix=/opt/global/gcc-3.3-20040209
--enable-shared --enable-threads --with-cpu=v9 --with-gnu-as
--with-as=/opt/global/gcc-3.3-32-solaris8-108528-20/bin/as
--enable-languages=c,c++ --with-gnu-ld
--with-ld=/opt/global/gcc-3.3-32-solaris8-108528-20/bin/ld --disable-multilib
Thread model: posix
gcc version 3.3.3 20040209 (prerelease)
gcc-3.3-32-solaris8-108528-20/bin/g++ -v
Reading specs from
gcc-3.3-32-solaris8-108528-20/bin/../lib/gcc-lib/sparc-sun-solaris2.8/3.3/specs
Configured with: ../gcc-3.3/configure
--prefix=/opt/global/gcc-3.3-32-solaris8-108528-20 --enable-shared
--enable-threads --with-cpu=v9 --with-gnu-as
--with-as=/opt/global/gcc-3.3-32-solaris8-108528-20/bin/as --with-gnu-ld
--with-ld=/opt/global/gcc-3.3-32-solaris8-108528-20/bin/ld --disable-multilib
Thread model: posix
gcc version 3.3
gcc-3.3.1-DEPRECATED/bin/g++ -v
Reading specs from
gcc-3.3.1-DEPRECATED/bin/../lib/gcc-lib/sparc-sun-solaris2.8/3.3.1/specs
Configured with: ./configure
--prefix=/opt/global/gcc-3.3.1-32-solaris8-108528-20 --enable-shared
--enable-threads --with-cpu=v9 --with-gnu-as
--with-as=/opt/global/gcc-3.3-32-solaris8-108528-20/bin/as
--enable-languages=c,c++ --with-gnu-ld
--with-ld=/opt/global/gcc-3.3-32-solaris8-108528-20/bin/ld --disable-multilib
Thread model: posix
gcc version 3.3.1
(The 3.3.1 is modified - it contains the patch for bug 12301.)
SOURCE
The source is put into two files to prevent inlining...
bug02.hh:
#include <string>
#include <sstream>
bool get( int & );
struct A
{
void t2( const std::string &, const std::string & );
void f1( const std::string &, const std::string & );
void f2( const std::string & s1, const std::string & s2, bool );
void f3( const std::string &, const std::string & );
};
#define THROW( MeSSaGe ) \
do { std::ostringstream oss; oss << __FILE__ << __LINE__ << ' ' << MeSSaGe;
throw oss.str(); } while( 1 )
bug02-broken.cc:
#include <string>
#include <iostream>
#include "bug02.hh"
void A::t2( const std::string & s1, const std::string & s2 )
{
int i;
if ( ! get( i ) )
{
THROW( "kasimir" );
}
switch ( i )
{
case 1:
f1( s1, s2 );
break;
case 2:
f2( s1, s2, false );
break;
case 3:
f2( s1, s2, true );
break;
case 7:
case 8:
f3( s1, s2 );
break;
}
}
int main( int, char ** )
{
A * a = new A;
try
{
a->t2( std::string( "foo" ), std::string( "bar" ) );
}
catch ( std::string & s )
{
std::cerr << s << '\n';
}
return 0;
}
bug02-lib.cc:
#include "bug02.hh"
bool get( int & i )
{
i = 3;
return true;
}
void A::f1( const std::string &, const std::string & )
{
}
void A::f2( const std::string & s1, const std::string & s2, bool )
{
// At this point it doesn't seem to matter how the exception is thrown.
// This is the exception that is thrown, and that is not caught by the
// catch in main() - unless one of the three changes outlined above is
// made.
throw std::string( "nasenbaer" );
// THROW( s1 << s2 );
}
void A::f3( const std::string &, const std::string & )
{
}
STACK
An excerpt from the stacktrace obtained from our full software that has a
crash/signal/assert/uncaught-exception handler that executes pstack to get a
stacktrace of the crash - seems that something is broken so that it doesn't find
the catch block for the exception.
fe1f0d4c _thrp_kill (0, 1, 6, fe20c000, 1, fe21321c) + f8
fe34ba74 raise (6, 6, ffbedc88, 42c2, 6, 2c0e5c) + 40
fe33591c abort (fe3bc000, 0, ffbedd28, 189d1c, 0, 0) + c0
00189d2c _ZN4Base14terminate_funcEv (1edf90, ffbeddd4, 23f768, 2c0e50, 0, 1) + 8c
feee59f4 _ZN10__cxxabiv111__terminateEPFvvE (189ca0, 1be1dc, ffbee2a8, 0, 1, 0) + 4
feee58d4 __gxx_personality_v0 (3, 1cfab4, 474e5543, 432b2b00, a98bb8, ffbee2a8)
+ 4ac
fe3e5460 _Unwind_RaiseException_Phase2 (2, ffbee2a8, 0, ffbee5f8, 4, 0) + 7c
fe3e578c _Unwind_Resume (a98be8, ffffffff, 1ed400, 68, 5fba, 1bc008) + 50
--
Summary: -O2 corrupts stack for small example
Product: gcc
Version: 3.3
Status: UNCONFIRMED
Severity: critical
Priority: P2
Component: c++
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: gcc at cohi dot at
CC: gcc-bugs at gcc dot gnu dot org
GCC build triplet: sparc-sun-solaris2.8
GCC host triplet: sparc-sun-solaris2.8
GCC target triplet: sparc-sun-solaris2.8
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=14113