diff options
author | anonymous <local@localhost> | 2010-10-01 23:11:25 +0000 |
---|---|---|
committer | anonymous <local@localhost> | 2010-10-01 23:11:25 +0000 |
commit | e34781fc2d3165dff329a48fba4ac8e21e36c748 (patch) | |
tree | 5a7a30e7628612eb07ac920e9478ca71d1c75797 | |
parent | 18482f17915bd417aa7a99a2050adbc355a4429c (diff) | |
download | libcxxrt-e34781fc2d3165dff329a48fba4ac8e21e36c748.tar.gz libcxxrt-e34781fc2d3165dff329a48fba4ac8e21e36c748.tar.bz2 libcxxrt-e34781fc2d3165dff329a48fba4ac8e21e36c748.tar.xz |
Fixed crash when rethrowing.
-rw-r--r-- | src/exception.cc | 12 |
1 files changed, 9 insertions, 3 deletions
diff --git a/src/exception.cc b/src/exception.cc index d31ebdd..272bf30 100644 --- a/src/exception.cc +++ b/src/exception.cc @@ -519,6 +519,11 @@ static void clear_rethrow_flag(__cxa_exception *ex) extern "C" void __cxa_rethrow() { __cxa_eh_globals *globals = __cxa_get_globals_fast(); + // Note: We don't remove this from the caught list here, because + // __cxa_end_catch will be called when we unwind out of the try block. We + // could probably make this faster by providing an alternative rethrow + // function and ensuring that all cleanup code is run before calling it, so + // we can skip the top stack frame when unwinding. __cxa_exception *ex = globals->caughtExceptions; if (0 == ex) @@ -526,18 +531,19 @@ extern "C" void __cxa_rethrow() fprintf(stderr, "Attempting to rethrow an exception that doesn't exist!\n"); std::terminate(); } - globals->caughtExceptions = ex->nextException; + + assert(ex->handlerCount > 0 && "Rethrowing uncaught exception!"); ex->handlerCount--; // Set the most significant bit in the exception's handler count as a flag // indicating that the exception is being rethrown. This flag is not // explicitly tested - we just set a high bit to ensure that the value of - // the caughtExceptions field does not drop to 0. This bit is then cleared + // the handlerCount field does not drop to 0. This bit is then cleared // when the exception is caught again. As long as we don't have more than // 2^30 exception handlers on the stack, and the compiler correctly // balances calls to begin / end catch, this should work correctly. - set_rethrow_flag(globals->caughtExceptions); + set_rethrow_flag(ex); // Continue unwinding the stack with this exception. This should unwind to // the place in the caller where __cxa_end_catch() is called. The caller |