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 | |
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')
-rw-r--r-- | src/Makefile | 47 | ||||
-rw-r--r-- | src/dwarf_eh.h | 1 | ||||
-rw-r--r-- | src/exception.cc | 54 |
3 files changed, 57 insertions, 45 deletions
diff --git a/src/Makefile b/src/Makefile index 0d0e203..d8240a7 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,7 +1,5 @@ OBJECTS = typeinfo.o exception.o dynamic_cast.o terminate.o guard.o -TEST_OBJECTS = test_typeinfo.o test.o test_exception.o new.o test_guard.o - # Needed for building the shared library CXXFLAGS = -fPIC # Needed for GCC atomic ops to work on x86. @@ -20,42 +18,7 @@ CXXFLAGS += -Wall -pedantic -g CPPFLAGS += -I/usr/local/include LDFLAGS += -L/usr/local/lib -L. -lpthread -fexceptions - - - - -all: test libcxxabi.so.1 - -PRODUCTS = test libcxxabi.so.1 system_test - -test: $(TEST_OBJECTS) libcxxabi.so.1 - @echo - @gcc $(CPPFLAGS) $(LDFLAGS) -lcxxabi -o test $(TEST_OBJECTS) - -# Fudge the dynamic library search path to include the current directory so -# that we can run the tests without having to install the .so -runtest: test - @LD_LIBRARY_PATH=.:$(LD_LIBRARY_PATH) ./test - -# Run the test program in the debugger -debug: test - @LD_LIBRARY_PATH=.:$(LD_LIBRARY_PATH) gdb ./test - -# Run the test program with valgrind. Make sure that the output from this has -# no memory leaks -valgrind: test - @LD_LIBRARY_PATH=.:$(LD_LIBRARY_PATH) valgrind --leak-check=full ./test - -# Compile another version of the test program linked against libstdc++, run it, -# and ensure that both versions pass the same number of tests. Bugs in the -# unwinding can cause some test not to be executed - this is a quick way of -# testing that the correct number pass. -compare: test - @$(CXX) $(CXXFLAGS) $(LDFLAGS) $(TEST_OBJECTS) -lstdc++ -o system_test - @./system_test 2>&1 | tail -1 > system_test.out - @echo Comparing libcxxabi and libstdc++ versions... - @LD_LIBRARY_PATH=.:$(LD_LIBRARY_PATH) ./test 2>&1 | tail -1 | diff system_test.out - - +PRODUCTS = libcxxabi.so.1 libcxxabi.so.1: $(OBJECTS) @echo Linking $@... @@ -63,9 +26,15 @@ libcxxabi.so.1: $(OBJECTS) .cc.o: @echo Compiling $<... - @echo $(CXXFLAGS) @$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $< clean: @echo Cleaning... @rm -f $(OBJECTS) $(PRODUCTS) $(TEST_OBJECTS) vgcore* *.core + + +dynamic_cast.o: dynamic_cast.cc typeinfo.h abi_namespace.h typeinfo +exception.o: exception.cc typeinfo.h abi_namespace.h typeinfo dwarf_eh.h +guard.o: guard.cc +terminate.o: terminate.cc +typeinfo.o: typeinfo.cc typeinfo.h abi_namespace.h typeinfo diff --git a/src/dwarf_eh.h b/src/dwarf_eh.h index 466f792..1ab25db 100644 --- a/src/dwarf_eh.h +++ b/src/dwarf_eh.h @@ -73,6 +73,7 @@ static inline int dwarf_size_of_fixed_size_field(unsigned char type) case DW_EH_PE_udata2: return 2; case DW_EH_PE_udata4: return 4; case DW_EH_PE_udata8: return 8; + case DW_EH_PE_absptr: return sizeof(void*); } abort(); } 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(); + } + } |