From 09ae311009060c8bf6cda09873b78f81b268badd Mon Sep 17 00:00:00 2001 From: Gabriel Corona Date: Fri, 22 Jul 2016 15:56:29 +0200 Subject: [PATCH] [xbt] Install a custom exception handler It shows the current backtrace and the exception context (if any): backtrace, simulated process PID, etc. --- include/xbt/log.h | 2 ++ include/xbt/log.hpp | 2 ++ src/xbt/exception.cpp | 62 +++++++++++++++++++++++++++++++++++++++++++ src/xbt/xbt_main.c | 2 ++ 4 files changed, 68 insertions(+) diff --git a/include/xbt/log.h b/include/xbt/log.h index 4c24f32120..837829f1ab 100644 --- a/include/xbt/log.h +++ b/include/xbt/log.h @@ -659,5 +659,7 @@ extern xbt_log_layout_t xbt_log_default_layout; */ #define XBT_HERE(...) XBT_LOG(xbt_log_priority_trace, "-- was here" __VA_ARGS__) +XBT_PUBLIC(void) xbt_set_terminate(); + SG_END_DECL() #endif /* ! _XBT_LOG_H_ */ diff --git a/include/xbt/log.hpp b/include/xbt/log.hpp index 875b3ad714..6dbf711f5f 100644 --- a/include/xbt/log.hpp +++ b/include/xbt/log.hpp @@ -20,5 +20,7 @@ XBT_PUBLIC(void) logException( e_xbt_log_priority_t priority, const char* context, std::exception const& exception); +XBT_PUBLIC(void) installExceptionHandler(); + } } diff --git a/src/xbt/exception.cpp b/src/xbt/exception.cpp index 6e9cf0c258..49f6188893 100644 --- a/src/xbt/exception.cpp +++ b/src/xbt/exception.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -68,5 +69,66 @@ void logException( } } +static void showBacktrace(std::vector& bt) +{ + std::vector res = resolveBacktrace(&bt[0], bt.size()); + XBT_LOG(xbt_log_priority_critical, "Current backtrace:"); + for (std::string const& s : res) + XBT_LOG(xbt_log_priority_critical, " -> %s", s.c_str()); +} + +static std::terminate_handler previous_terminate_handler = nullptr; + +static void handler() +{ + // Avoid doing crazy things if we get an uncaught exception inside + // an uncaught exception + static std::atomic_flag lock = ATOMIC_FLAG_INIT; + if (lock.test_and_set()) { + XBT_ERROR("Multiple uncaught exceptions"); + std::abort(); + } + + // Get the current backtrace and exception + auto e = std::current_exception(); + auto bt = backtrace(); + try { + std::rethrow_exception(e); + } + + // We manage C++ exception ourselves + catch (std::exception& e) { + logException(xbt_log_priority_critical, "Uncaught exception", e); + showBacktrace(bt); + std::abort(); + } + + // We don't know how to manage other exceptions + catch (...) { + // If there was another handler let's delegate to it + if (previous_terminate_handler) + previous_terminate_handler(); + else { + XBT_ERROR("Unknown uncaught exception"); + showBacktrace(bt); + std::abort(); + } + } + +} + +void installExceptionHandler() +{ + static std::once_flag handler_flag; + std::call_once(handler_flag, [] { + previous_terminate_handler = std::set_terminate(handler); + }); +} + } } + +void xbt_set_terminate() +{ + simgrid::xbt::installExceptionHandler(); +} diff --git a/src/xbt/xbt_main.c b/src/xbt/xbt_main.c index 3451b60527..13ec9e30b5 100644 --- a/src/xbt/xbt_main.c +++ b/src/xbt/xbt_main.c @@ -137,6 +137,8 @@ static void xbt_postexit(void) /** @brief Initialize the xbt mechanisms. */ void xbt_init(int *argc, char **argv) { + xbt_set_terminate(); + if (xbt_initialized++) { XBT_DEBUG("XBT was initialized %d times.", xbt_initialized); return; -- 2.20.1