Note: This is a public test instance of Red Hat Bugzilla. The data contained within is a snapshot of the live data so any changes you make will not be reflected in the production Bugzilla. Email is disabled so feel free to test any aspect of the site that you want. File any problems you find or give feedback at bugzilla.redhat.com.
Bug 82081
Summary: | libstdc++ SIGABRT when throwing exceptions | ||
---|---|---|---|
Product: | [Retired] Red Hat Raw Hide | Reporter: | tanner |
Component: | gcc | Assignee: | Jakub Jelinek <jakub> |
Status: | CLOSED NOTABUG | QA Contact: | David Lawrence <dkl> |
Severity: | medium | Docs Contact: | |
Priority: | medium | ||
Version: | 1.0 | ||
Target Milestone: | --- | ||
Target Release: | --- | ||
Hardware: | i386 | ||
OS: | Linux | ||
Whiteboard: | |||
Fixed In Version: | Doc Type: | Bug Fix | |
Doc Text: | Story Points: | --- | |
Clone Of: | Environment: | ||
Last Closed: | 2004-11-24 14:29:14 UTC | Type: | --- |
Regression: | --- | Mount Type: | --- |
Documentation: | --- | CRM: | |
Verified Versions: | Category: | --- | |
oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |
Cloudforms Team: | --- | Target Upstream Version: | |
Embargoed: | |||
Bug Depends On: | |||
Bug Blocks: | 79579, 100644 |
Description
tanner
2003-01-17 07:09:10 UTC
Upgraded to gcc-3.2.1 20021207 and still get the SIGABRT problem. abort () is the default __terminate() implementation. You should find out why the exception has not been caught. Just to make sure I understand you. You are saying this looks like a problem in the -application- not catching an exception? It is VERY likely a bug in the application (of course, unless you prove that there is a catch block which accepts that exception). 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. 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. 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. 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 This has nothing to do with glibc. Reassign to gcc. But they will likely close the bug unless some recent testing is done. 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 If you have a self-contained testcase, please reopen. |