From fa85cd845f6d69e511eb5bfa11243c4cf1b798f7 Mon Sep 17 00:00:00 2001 From: redfish Date: Sun, 10 Jul 2016 18:57:53 -0400 Subject: [PATCH] common: stack trace: make clang happy with func ptrs Tested that it builds with: gcc 6.1.1, STATIC=OFF,i686 gcc 6.1.1, STATIC=OFF,armv7h clang 3.8, STATIC=OFF,i686 clang 3.8, STATIC=OFF,armv7h gcc 6.1.1, STATIC=ON,i686 clang 3.8, STATIC=ON,i686 Also tested that stack trace is generated fine on exception on: i686, gcc 6.1.1, STATIC=OFF (didn't bother testing all the other platforms/configs) This should fix the build problem on OSX (#871, #901), but I don't have OSX, so I could only test Clang on Linux. --- src/common/stack_trace.cpp | 38 +++++++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/src/common/stack_trace.cpp b/src/common/stack_trace.cpp index 0d2ccb39..44002e2d 100644 --- a/src/common/stack_trace.cpp +++ b/src/common/stack_trace.cpp @@ -38,14 +38,33 @@ #endif // from http://stackoverflow.com/questions/11665829/how-can-i-print-stack-trace-for-caught-exceptions-in-c-code-injection-in-c + +// The decl of __cxa_throw in /usr/include/.../cxxabi.h uses +// 'std::type_info *', but GCC's built-in protype uses 'void *'. +#ifdef __clang__ +#define CXA_THROW_INFO_T std::type_info +#else // !__clang__ +#define CXA_THROW_INFO_T void +#endif // !__clang__ + #ifdef STATICLIB #define CXA_THROW __wrap___cxa_throw -extern "C" void __real___cxa_throw(void *ex, void *info, void (*dest)(void*)); -#else +extern "C" +__attribute__((noreturn)) +void __real___cxa_throw(void *ex, CXA_THROW_INFO_T *info, void (*dest)(void*)); +#else // !STATICLIB #define CXA_THROW __cxa_throw -#endif +extern "C" +typedef +#ifdef __clang__ // only clang, not GCC, lets apply the attr in typedef +__attribute__((noreturn)) +#endif // __clang__ +void (cxa_throw_t)(void *ex, CXA_THROW_INFO_T *info, void (*dest)(void*)); +#endif // !STATICLIB -extern "C" void CXA_THROW(void *ex, void *info, void (*dest)(void*)) +extern "C" +__attribute__((noreturn)) +void CXA_THROW(void *ex, CXA_THROW_INFO_T *info, void (*dest)(void*)) { int status; @@ -53,12 +72,13 @@ extern "C" void CXA_THROW(void *ex, void *info, void (*dest)(void*)) tools::log_stack_trace((std::string("Exception: ")+((!status && dsym) ? dsym : (const char*)info)).c_str()); free(dsym); -#ifdef STATICLIB +#ifndef STATICLIB +#ifndef __clang__ // for GCC the attr can't be applied in typedef like for clang + __attribute__((noreturn)) +#endif // !__clang__ + cxa_throw_t *__real___cxa_throw = (cxa_throw_t*)dlsym(RTLD_NEXT, "__cxa_throw"); +#endif // !STATICLIB __real___cxa_throw(ex, info, dest); -#else - static void (*const rethrow)(void*, void*, void(*)(void*)) __attribute__((noreturn)) = (void(*)(void*, void*, void(*)(void*)))dlsym(RTLD_NEXT, "__cxa_throw"); - rethrow(ex, info, dest); -#endif } namespace