From a283c64f6b95ec2db1b4b6004f27b1e448961e73 Mon Sep 17 00:00:00 2001 From: anonymous Date: Wed, 29 Sep 2010 23:20:49 +0000 Subject: Add __cxa_demangle support --- CMakeLists.txt | 2 ++ src/CMakeLists.txt | 2 ++ src/exception.cc | 7 +++---- src/typeinfo.cc | 38 ++++++++++++++++++++++++++++++++++++++ test/test.cc | 30 ++++++++++++++++++++++++++++++ test/test_exception.cc | 2 ++ test/test_guard.cc | 5 ++++- test/test_typeinfo.cc | 11 ----------- 8 files changed, 81 insertions(+), 16 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 403d43f..7da13f7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,5 +7,7 @@ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/lib") set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/lib") add_subdirectory(src) +IF(BUILD_TESTS) add_subdirectory(test) +ENDIF() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d30da28..7633f03 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -8,6 +8,8 @@ set(CXXRT_SOURCES stdexcept.cc memory.cc aux.cc + libelftc_dem_gnu3.c + libelftc_vstr.c ) diff --git a/src/exception.cc b/src/exception.cc index 749f743..0ecc679 100644 --- a/src/exception.cc +++ b/src/exception.cc @@ -443,18 +443,17 @@ static void report_failure(_Unwind_Reason_Code err, void *thrown_exception) fprintf(stderr, "Fatal error during phase 2 unwinding\n"); break; case _URC_END_OF_STACK: - fprintf(stderr, "Terminating due to uncaught exception %p:\n", + fprintf(stderr, "Terminating due to uncaught exception %p", thrown_exception); -/* TODO: Uncomment this when __cxa_demangle() is implemented. size_t bufferSize = 128; char *demangled = (char*)malloc(bufferSize); const char *mangled = __cxa_current_exception_type()->name(); int status; __cxa_demangle(mangled, demangled, &bufferSize, &status); - fprintf(stderr, "Terminating due to uncaught of type %s:\n", + fprintf(stderr, " of type %s\n", status == 0 ? (const char*)demangled : mangled); -*/ + if (status == 0) { free(demangled); } // Print a back trace if no handler is found. // TODO: Make this optional _Unwind_Backtrace(trace, 0); diff --git a/src/typeinfo.cc b/src/typeinfo.cc index cc2b3c7..6d16668 100644 --- a/src/typeinfo.cc +++ b/src/typeinfo.cc @@ -1,4 +1,7 @@ #include "typeinfo.h" +#include +#include +#include using std::type_info; @@ -39,3 +42,38 @@ ABI_NAMESPACE::__vmi_class_type_info::~__vmi_class_type_info() {} ABI_NAMESPACE::__pbase_type_info::~__pbase_type_info() {} ABI_NAMESPACE::__pointer_type_info::~__pointer_type_info() {} ABI_NAMESPACE::__pointer_to_member_type_info::~__pointer_to_member_type_info() {} + +// From libelftc +extern "C" char *cpp_demangle_gnu3(const char *); +extern "C" bool is_cpp_mangled_gnu3(const char *); + +extern "C" char* __cxa_demangle(const char* mangled_name, + char* buf, + size_t* n, + int* status) +{ + char *demangled = cpp_demangle_gnu3(mangled_name); + if (NULL != demangled) + { + size_t len = strlen(demangled); + buf = (char*)realloc(buf, len+1); + if (0 != buf) + { + memcpy(buf, demangled, len); + buf[len] = 0; + *n = len; + *status = 0; + } + else + { + *status = -1; + } + free(demangled); + } + else + { + *status = -2; + return NULL; + } + return buf; +} diff --git a/test/test.cc b/test/test.cc index 13bad95..520286c 100644 --- a/test/test.cc +++ b/test/test.cc @@ -1,13 +1,20 @@ #include #include +#include + static int succeeded; static int failed; +static bool verbose; void log_test(bool predicate, const char *file, int line, const char *message) { if (predicate) { + if (verbose) + { + printf("Test passed: %s:%d: %s\n", file, line, message); + } succeeded++; return; } @@ -24,3 +31,26 @@ static void __attribute__((constructor)) init(void) { atexit(log_totals); } + +void test_type_info(void); +void test_exceptions(); +void test_guards(void); +int main(int argc, char **argv) +{ + int ch; + + while ((ch = getopt(argc, argv, "v")) != -1) + { + switch (ch) + { + case 'v': + verbose = true; + default: break; + } + } + + test_type_info(); + test_guards(); + test_exceptions(); + return 0; +} diff --git a/test/test_exception.cc b/test/test_exception.cc index 5042b64..8149fbf 100644 --- a/test/test_exception.cc +++ b/test/test_exception.cc @@ -5,6 +5,8 @@ #include +#define fprintf(...) + void log(void* ignored) { printf("Cleanup called on %s\n", *(char**)ignored); diff --git a/test/test_guard.cc b/test/test_guard.cc index 5f8521d..1ad5a2f 100644 --- a/test/test_guard.cc +++ b/test/test_guard.cc @@ -1,4 +1,5 @@ #include +#include "test.h" static int static_count; struct static_struct @@ -6,7 +7,6 @@ struct static_struct int i; static_struct() { - fprintf(stderr, "Initialized static\n"); static_count++; i = 12; }; @@ -23,4 +23,7 @@ int init_static(void) void test_guards(void) { init_static(); + int i = init_static(); + TEST(i == 12, "Static initialized"); + TEST(static_count == 2, "Each static only initialized once"); } diff --git a/test/test_typeinfo.cc b/test/test_typeinfo.cc index 7e9e308..6d2fbdd 100644 --- a/test/test_typeinfo.cc +++ b/test/test_typeinfo.cc @@ -2,9 +2,6 @@ #include "test.h" #include -// FIXME: Move this and main() to a different file. -void test_exceptions(); - struct Virt1; struct Virt2; struct Diamond; @@ -110,11 +107,3 @@ void test_type_info(void) TEST(0 == dynamic_cast(b2), "Casting Root to Sub1 (0 expected)"); } -void test_guards(void); -int main(void) -{ - test_type_info(); - test_guards(); - test_exceptions(); - return 0; -} -- cgit v1.2.3