summaryrefslogtreecommitdiff
path: root/src/exception.cc
diff options
context:
space:
mode:
authoranonymous <local@localhost>2010-06-28 17:44:35 +0000
committeranonymous <local@localhost>2010-06-28 17:44:35 +0000
commit81adee0f2476af72ce3923874f35dceff9fedf9a (patch)
treecaa361ed02d8ce227bf982a36f4219e97211dddc /src/exception.cc
parente55300bb3884cf91c0d2735649a68984703a6350 (diff)
downloadlibcxxrt-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.cc54
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();
+ }
+
}