diff options
author | anonymous <local@localhost> | 2010-06-28 17:44:35 +0000 |
---|---|---|
committer | anonymous <local@localhost> | 2010-06-28 17:44:35 +0000 |
commit | 81adee0f2476af72ce3923874f35dceff9fedf9a (patch) | |
tree | caa361ed02d8ce227bf982a36f4219e97211dddc /src/exception.cc | |
parent | e55300bb3884cf91c0d2735649a68984703a6350 (diff) | |
download | libcxxrt-81adee0f2476af72ce3923874f35dceff9fedf9a.tar.gz libcxxrt-81adee0f2476af72ce3923874f35dceff9fedf9a.tar.bz2 libcxxrt-81adee0f2476af72ce3923874f35dceff9fedf9a.tar.xz |
Added std:: functions for setting unexpected / terminate handlers.
Diffstat (limited to 'src/exception.cc')
-rw-r--r-- | src/exception.cc | 54 |
1 files changed, 48 insertions, 6 deletions
diff --git a/src/exception.cc b/src/exception.cc index bf49bb2..5bfd921 100644 --- a/src/exception.cc +++ b/src/exception.cc @@ -815,17 +815,59 @@ extern "C" std::type_info *__cxa_current_exception_type() */ extern "C" void __cxa_call_unexpected(void*exception) { - // FIXME: This should call the unexpected handler from the exception, or - // the global per-thread one if that one doesn't exist. _Unwind_Exception *exceptionObject = (_Unwind_Exception*)exception; - fprintf(stderr, "Exception spec violated! You have no skill!\n"); if (exceptionObject->exception_class == exception_class) { __cxa_exception *ex = (__cxa_exception*) ((char*)exceptionObject - offsetof(struct __cxa_exception, unwindHeader)); + if (ex->unexpectedHandler) + { + ex->unexpectedHandler(); + // Should not be reached. + abort(); + } + } + std::unexpected(); +} - // TODO: Demangle type name - fprintf(stderr, "Thrown exception was: %s\n", ex->exceptionType->name()); +namespace std +{ + unexpected_handler set_unexpected(unexpected_handler f) throw() + { + static __cxa_thread_info *info = thread_info(); + unexpected_handler old = info->unexpectedHandler; + info->unexpectedHandler = f; + return old; + } + terminate_handler set_terminate(terminate_handler f) throw() + { + static __cxa_thread_info *info = thread_info(); + terminate_handler old = info->terminateHandler; + info->terminateHandler = f; + return old; } - exit(1); + void terminate() + { + static __cxa_thread_info *info = thread_info_fast(); + if (0 != info && 0 != info->terminateHandler) + { + info->terminateHandler(); + // Should not be reached - a terminate handler is not expected to + // return. + } + abort(); + } + void unexpected() + { + static __cxa_thread_info *info = thread_info_fast(); + if (0 != info && 0 != info->unexpectedHandler) + { + info->unexpectedHandler(); + // Should not be reached - a terminate handler is not expected to + // return. + abort(); + } + terminate(); + } + } |