Bug 82081 - libstdc++ SIGABRT when throwing exceptions
libstdc++ SIGABRT when throwing exceptions
Status: CLOSED NOTABUG
Product: Red Hat Raw Hide
Classification: Retired
Component: gcc (Show other bugs)
1.0
i386 Linux
medium Severity medium
: ---
: ---
Assigned To: Jakub Jelinek
David Lawrence
:
Depends On:
Blocks: 79579 CambridgeTarget
  Show dependency treegraph
 
Reported: 2003-01-17 02:09 EST by tanner
Modified: 2007-04-18 12:50 EDT (History)
0 users

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2004-11-24 09:29:14 EST
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)

  None (edit)
Description tanner 2003-01-17 02:09:10 EST
Program received signal SIGABRT, Aborted.
[Switching to Thread 8192 (LWP 2294)]
0x408e7921 in kill () from /lib/libc.so.6
(gdb) bt
#0  0x408e7921 in kill () from /lib/libc.so.6
#1  0x406dc2aa in pthread_kill () from /lib/libpthread.so.0
#2  0x406dc591 in raise () from /lib/libpthread.so.0
#3  0x408e8808 in abort () from /lib/libc.so.6
#4  0x4086ffb7 in __cxxabiv1::__terminate(void (*)()) (
    handler=0x408e868c <abort>)
    at ../../../../libstdc++-v3/libsupc++/eh_terminate.cc:47
#5  0x40870004 in std::terminate() ()
    at ../../../../libstdc++-v3/libsupc++/eh_terminate.cc:57
#6  0x40870176 in __cxa_throw ()
    at ../../../../libstdc++-v3/libsupc++/eh_throw.cc:77
#7  0x4003aba8 in com_uwyn_qtunit::TestCase::assertImpl(QString const&, bool,
QString const&, long) (this=0x806a9dc, rConditionExpr=@0xbfffe980,
    condition=false, rFileName=@0xbfffea00, lineNumber=89)
    at framework/TestCase.cpp:106
#8  0x4003ace7 in com_uwyn_qtunit::TestCase::assertTrue(QString const&, bool,
char const*, QString const&, long) (this=0x806a9dc, rConditionExpr=@0xbfffea10,
    condition=false, pMessage=0x0, rFileName=@0xbfffea00, lineNumber=89)
    at framework/TestCase.cpp:118
#9  0x4009d376 in com_uwyn_qtunit::ExampleTestCase::testSetUp() (
    this=0x806a9dc) at ExampleTestCase.cpp:89
#10 0x4009d666 in com_uwyn_qtunit::Test<com_uwyn_qtunit::ExampleTestCase>::run()
const (this=0x804e9c8) at ../../src/framework/Test.h:63
#11 0x40043aca in
com_uwyn_qtunit::TestRunner::runTest(com_uwyn_qtunit::TestBase const&)
(this=0xbfffec70, rTest=@0x804e9c8) at framework/TestRunner.cpp:78
#12 0x400468ec in com_uwyn_qtunit::TextTestRunner::run() (this=0xbfffec70)
    at textrunner/TextTestRunner.cpp:110
#13 0x08048741 in main (argc=2, argv=0xbfffed74) at SampleTextRunner.cpp:39
#14 0x408d653d in __libc_start_main () from /lib/libc.so.6
Comment 1 tanner 2003-01-17 17:56:49 EST
Upgraded to gcc-3.2.1 20021207 and still get the SIGABRT problem.
Comment 2 Jakub Jelinek 2003-01-17 18:05:26 EST
abort () is the default __terminate() implementation.
You should find out why the exception has not been caught.
Comment 3 tanner 2003-01-17 18:11:51 EST
Just to make sure I understand you. You are saying this looks like a problem in
the -application- not catching an exception?

Comment 4 Jakub Jelinek 2003-01-17 18:14:59 EST
It is VERY likely a bug in the application (of course, unless you prove that
there is a catch block which accepts that exception).
Comment 5 tanner 2003-01-17 18:19:19 EST
I'll double check the code tonight to verify. I seem to remember seeing

catch (...) block, but I'll confirm tonight after my "real" job.
Comment 6 tanner 2003-01-19 22:34:54 EST
Breaking down gdb backtrace, I'm still of the opinion that there is a problem
with exception handling in libstdc++, all this code is open source and can be
gotten from http://www.uwyn.com/projects/qtunit/


#13 0x08048741 in main (argc=2, argv=0xbfffed74) at SampleTextRunner.cpp:39
int main(int argc, char **argv)
{
        cout << "Debugging" << flush;
        TextTestRunner runner(argc, argv);

        runner.run();   // Line 39

        return 0;
}


#12 0x400468ec in com_uwyn_qtunit::TextTestRunner::run() (this=0xbfffec70)
    at textrunner/TextTestRunner.cpp:110
void TextTestRunner::run()
{
<snip>
                        runTest(*it.current());
}

#11 0x40043aca in
com_uwyn_qtunit::TestRunner::runTest(com_uwyn_qtunit::TestBase const&)
(this=0xbfffec70, rTest=@0x804e9c8) at framework/TestRunner.cpp:78

Here is where the catch block starts:

        try {
                rTest.run();
                mpResult->addSuccess(new
TestDescription(rTest.testCase().lastFileName(),
rTest.testCase().lastLineNumber(), rTest.testFullName()));
        } catch (QtUnitException& rException) {
                // handle the exception
        }

Note that a QtUnitException is caught in this block.

#10 0x4009d666 in com_uwyn_qtunit::Test<com_uwyn_qtunit::ExampleTestCase>::run()
const (this=0x804e9c8) at ../../src/framework/Test.h:63
	template <class Fixture> void Test<Fixture>::run() const
	{
		(static_cast<Fixture*>(mpTestCase)->*mpTestMethod)();
	}

#9  0x4009d376 in com_uwyn_qtunit::ExampleTestCase::testSetUp() (
    this=0x806a9dc) at ExampleTestCase.cpp:89

void ExampleTestCase::testSetUp()
{
	double result = mValue1 + mValue2;
	qassertTrue(result == 5.0);
	qassertTrue(result == 6.0); // Line 89
}

#8  0x4003ace7 in com_uwyn_qtunit::TestCase::assertTrue(QString const&, bool,
char const*, QString const&, long) (this=0x806a9dc, rConditionExpr=@0xbfffea10,
    condition=false, pMessage=0x0, rFileName=@0xbfffea00, lineNumber=89)
    at framework/TestCase.cpp:118
void TestCase::assertTrue(const QString& rConditionExpr, bool condition, const
char* pMessage, const QString& rFileName, long lineNumber)
{ 
	QString message;

	if (NULL != pMessage)
	{
		message = QString(pMessage)+" : ";
	}
	assertImpl(message+notTrueMessage(rConditionExpr), condition, rFileName,
lineNumber);
}

#7  0x4003aba8 in com_uwyn_qtunit::TestCase::assertImpl(QString const&, bool,
QString const&, long) (this=0x806a9dc, rConditionExpr=@0xbfffe980,
condition=false, rFileName=@0xbfffea00, lineNumber=89) at framework/TestCase.cpp:106

Here is where the throw happens.

void TestCase::assertImpl(const QString& rConditionExpr, bool condition, const
QString& rFileName, long lineNumber)
{
        lastFileName(rFileName);
        mLastLineNumber = lineNumber;

        if (false == condition)
        {
                throw QtUnitException(rConditionExpr); // throw!
        }
}

I believe the catch in frame 11 in the method runTest should catch the
QtUnitException thrown above.

Download qtunit, make, then run it's own testsuite to simulate this error.
Comment 7 tanner 2003-01-20 00:37:24 EST
From the author of qtunit:

TestCase.cpp:106 says :

throw QtUnitException(rConditionExpr);

This is the default assertion implementation which can be used by each
TestCase test method. This method is called by the Test fixture which
is instantiated when using the addTest macros (TestCase.h:41). When
run() is called below for each TestCase method and an assertion is
evaluated, a QtUnitException exception is thrown. This one should
bubble through until the try ... catch below. Any std exception class
is also catched to provide error-reporting on top of failure reporting
(catch (std::exception& rException)), and finally *ANY* other exception
type is caught (catch (...)), also for error reporting.

TestRunner.cpp:71-87 says :
try
{
        rTest.run();
        mpResult->addSuccess(new
TestDescription(rTest.testCase().lastFileName(),
                rTest.testCase().lastLineNumber(), rTest.testFullName()));
}
catch (QtUnitException& rException)
{
        mpResult->addFailure(new
TestDescription(rTest.testCase().lastFileName(),
                rTest.testCase().lastLineNumber(), rTest.testFullName(),
rException.what(), rTest.sourcePath()));
}
catch (std::exception& rException)
{
        mpResult->addError(new
TestDescription(rTest.testCase().lastFileName(), 0,
rTest.testFullName(),
                rException.what(), rTest.sourcePath()));
}
catch (...)
{
        mpResult->addError(new
TestDescription(rTest.testCase().lastFileName(), 0,
rTest.testFullName(),
                trUtf8("<unknown>"), rTest.sourcePath()));
}

This should catch *ALL* exceptions, categorised according to the amount
of feedback that can be given and the type of exceptional behaviour.

I have noticed (as said before) that gcc is however very picky about
its exception implementation and the correct header files should be
included in all related files before exceptions start bubbling up
correctly. If this is not done properly, abort() is called when 'scope
boundaries' are reached (for example the boundaries of a TestModule
share library). It's possible that in untested version numbers that has
changed and that the bubbling doesn't work correctly anymore. 
Comment 8 tanner 2003-01-20 00:38:45 EST
I added std::set_terminate (__gnu_cxx::__verbose_terminate_handler);	
as recommended by 

http://gcc.gnu.org/onlinedocs/libstdc++/19_diagnostics/howto.html#1

terminate called after throwing a `com_uwyn_qtunit::QtUnitException'
  what(): result == 6.0 was not true
Comment 9 Ulrich Drepper 2004-09-28 02:24:26 EDT
This has nothing to do with glibc.  Reassign to gcc.  But they will
likely close the bug unless some recent testing is done.
Comment 10 Benjamin Kosnik 2004-10-01 13:15:01 EDT
Can't really tell what's going on without a self-contained test case,
sorry. 

Off hand, this may be caused by two live exceptions at once, at which
point unexpected is called. You can check this by creating an
unexpected handler, similar to the set_terminate call in comment 8. If
you create this, say something that prints out "unexpected" and then
calls the __verbose_terminate_handler, you'll be able to check if this
is the case.

That will at least tell you if the problem is within this app or gcc.

best,
benjamin
Comment 11 Jakub Jelinek 2004-11-24 09:29:14 EST
If you have a self-contained testcase, please reopen.

Note You need to log in before you can comment on or make changes to this bug.