From 9880c25e78b6adb391bd15a516d4966b3f0a951b Mon Sep 17 00:00:00 2001 From: Martin Quinson Date: Sat, 27 Oct 2018 22:22:21 +0200 Subject: [PATCH] Hide the content of a simgrid::xbt::Backtrace and inline a function --- include/xbt/backtrace.hpp | 13 +++----- src/xbt/backtrace.cpp | 65 +++++++++++++++++++-------------------- src/xbt/exception.cpp | 13 ++++---- 3 files changed, 41 insertions(+), 50 deletions(-) diff --git a/include/xbt/backtrace.hpp b/include/xbt/backtrace.hpp index cfcd475229..dfde1bd7c9 100644 --- a/include/xbt/backtrace.hpp +++ b/include/xbt/backtrace.hpp @@ -18,8 +18,6 @@ SG_BEGIN_DECL() XBT_PUBLIC void xbt_backtrace_display_current(); SG_END_DECL() -typedef void* xbt_backtrace_location_t; - namespace simgrid { namespace xbt { @@ -30,7 +28,7 @@ namespace xbt { * * @ingroup XBT_ex */ -typedef std::vector Backtrace; +typedef std::vector Backtrace; /** Try to demangle a C++ name * @@ -38,21 +36,18 @@ typedef std::vector Backtrace; */ XBT_PUBLIC std::unique_ptr demangle(const char* name); -/** Get the current backtrace */ +/** @brief Captures a backtrace for further use */ XBT_PUBLIC Backtrace backtrace(); /* Translate the backtrace in a human friendly form * * Try resolve symbols and source code location. */ -XBT_PUBLIC std::vector resolve_backtrace(xbt_backtrace_location_t const* loc, std::size_t count); +XBT_PUBLIC std::vector resolve_backtrace(const Backtrace& bt); } } -/** @brief Captures a backtrace for further use */ -XBT_PUBLIC size_t xbt_backtrace_current(xbt_backtrace_location_t* loc, size_t count); - /** @brief Display a previously captured backtrace */ -XBT_PUBLIC void xbt_backtrace_display(xbt_backtrace_location_t* loc, size_t count); +XBT_PUBLIC void xbt_backtrace_display(const simgrid::xbt::Backtrace& bt); #endif diff --git a/src/xbt/backtrace.cpp b/src/xbt/backtrace.cpp index ed512992a3..a74145f90a 100644 --- a/src/xbt/backtrace.cpp +++ b/src/xbt/backtrace.cpp @@ -36,9 +36,9 @@ static bool startWith(std::string str, const char* prefix) return strncmp(str.c_str(), prefix, strlen(prefix)) == 0; } -void xbt_backtrace_display(xbt_backtrace_location_t* loc, std::size_t count) +void xbt_backtrace_display(const simgrid::xbt::Backtrace& bt) { - std::vector backtrace = simgrid::xbt::resolve_backtrace(loc, count); + std::vector backtrace = simgrid::xbt::resolve_backtrace(bt); if (backtrace.empty()) { fprintf(stderr, "(backtrace not set -- maybe unavailable on this architecture?)\n"); return; @@ -58,12 +58,19 @@ void xbt_backtrace_display(xbt_backtrace_location_t* loc, std::size_t count) /** @brief show the backtrace of the current point (lovely while debugging) */ void xbt_backtrace_display_current() { - const std::size_t size = 10; - xbt_backtrace_location_t bt[size]; - size_t used = xbt_backtrace_current(bt, size); - xbt_backtrace_display(bt, used); + simgrid::xbt::Backtrace bt = simgrid::xbt::backtrace(); + xbt_backtrace_display(bt); } +#if HAVE_BACKTRACE +// For some reason, if I try to use it directly, GCC thinks I try to use xbt::backtrace. +// I suspect that this symbol is not presented as a regular function in execinfo.h +static int gnu_backtrace(simgrid::xbt::Backtrace& bt) +{ + return backtrace(bt.data(), bt.size()); +} +#endif + namespace simgrid { namespace xbt { @@ -85,30 +92,24 @@ std::unique_ptr demangle(const char* name) Backtrace backtrace() { - const std::size_t size = 10; - xbt_backtrace_location_t loc[size]; - size_t used = xbt_backtrace_current(loc, size); - return Backtrace(loc, loc + used); -} - -} -} - -size_t xbt_backtrace_current(xbt_backtrace_location_t* loc, std::size_t count) -{ - std::size_t used = 0; + simgrid::xbt::Backtrace res; #if HAVE_BACKTRACE - used = backtrace(loc, count); + res.resize(15); + int used = gnu_backtrace(res); if (used == 0) { std::fprintf(stderr, "The backtrace() function failed, which probably means that the memory is exhausted\n."); std::fprintf(stderr, "Bailing out now since there is nothing I can do without a decent amount of memory\n."); std::fprintf(stderr, "Please go fix the memleaks\n"); std::exit(1); } + res.shrink_to_fit(); #endif - return used; + return res; } +} // namespace xbt +} // namespace simgrid + namespace simgrid { namespace xbt { @@ -145,37 +146,33 @@ static std::string get_binary_path() return ""; } -std::vector resolve_backtrace(xbt_backtrace_location_t const* loc, std::size_t count) +std::vector resolve_backtrace(const Backtrace& bt) { std::vector result; #if HAVE_BACKTRACE && HAVE_EXECINFO_H && HAVE_POPEN && defined(ADDR2LINE) // FIXME: This code could be greatly improved/simplified with // http://cairo.sourcearchive.com/documentation/1.9.4/backtrace-symbols_8c-source.html - if (count == 0) + if (bt.size() == 0) return result; if (xbt_binary_name == nullptr) XBT_WARN("XBT not initialized, the backtrace will not be resolved."); - // Drop the first one: - loc++; - count--; - - char** backtrace_syms = backtrace_symbols(loc, count); + char** backtrace_syms = backtrace_symbols(bt.data(), bt.size()); std::string binary_name = get_binary_path(); if (binary_name.empty()) { - for (std::size_t i = 0; i < count; i++) - result.push_back(simgrid::xbt::string_printf("%p", loc[i])); + for (std::size_t i = 1; i < bt.size(); i++) // the first one is not interesting + result.push_back(simgrid::xbt::string_printf("%p", bt[i])); return result; } // Create the system command for add2line: std::ostringstream stream; stream << ADDR2LINE << " -f -e " << binary_name << ' '; - std::vector addrs(count); - for (std::size_t i = 0; i < count; i++) { + std::vector addrs(bt.size()); + for (std::size_t i = 1; i < bt.size(); i++) { // the first one is not interesting /* retrieve this address */ XBT_DEBUG("Retrieving address number %zu from '%s'", i, backtrace_syms[i]); char buff[256]; @@ -202,7 +199,7 @@ std::vector resolve_backtrace(xbt_backtrace_location_t const* loc, /* To read the output of addr2line */ char line_func[1024]; char line_pos[1024]; - for (std::size_t i = 0; i < count; i++) { + for (std::size_t i = 1; i < bt.size(); i++) { // The first one is not interesting XBT_DEBUG("Looking for symbol %zu, addr = '%s'", i, addrs[i].c_str()); if (fgets(line_func, 1024, pipe)) { line_func[strlen(line_func) - 1] = '\0'; @@ -220,7 +217,7 @@ std::vector resolve_backtrace(xbt_backtrace_location_t const* loc, if (strcmp("??", line_func) != 0) { auto name = simgrid::xbt::demangle(line_func); XBT_DEBUG("Found static symbol %s at %s", name.get(), line_pos); - result.push_back(simgrid::xbt::string_printf("%s at %s, %p", name.get(), line_pos, loc[i])); + result.push_back(simgrid::xbt::string_printf("%s at %s, %p", name.get(), line_pos, bt[i])); } else { /* Damn. The symbol is in a dynamic library. Let's get wild */ @@ -316,7 +313,7 @@ std::vector resolve_backtrace(xbt_backtrace_location_t const* loc, if (strcmp("??", line_func)) { auto name = simgrid::xbt::demangle(line_func); XBT_DEBUG("Found dynamic symbol %s at %s", name.get(), line_pos); - result.push_back(simgrid::xbt::string_printf("%s at %s, %p", name.get(), line_pos, loc[i])); + result.push_back(simgrid::xbt::string_printf("%s at %s, %p", name.get(), line_pos, bt[i])); } else { /* damn, nothing to do here. Let's print the raw address */ XBT_DEBUG("Dynamic symbol not found. Raw address = %s", backtrace_syms[i]); diff --git a/src/xbt/exception.cpp b/src/xbt/exception.cpp index 0a0f335d86..17c985042a 100644 --- a/src/xbt/exception.cpp +++ b/src/xbt/exception.cpp @@ -90,8 +90,7 @@ void log_exception(e_xbt_log_priority_t prio, const char* context, std::exceptio // Do we have a backtrace? if (with_context != nullptr && not simgrid::config::get_value("exception/cutpath")) { - auto backtrace = simgrid::xbt::resolve_backtrace(with_context->throw_point().backtrace_.data(), - with_context->throw_point().backtrace_.size()); + auto backtrace = simgrid::xbt::resolve_backtrace(with_context->throw_point().backtrace_); for (std::string const& s : backtrace) XBT_LOG(prio, " -> %s", s.c_str()); } @@ -116,13 +115,13 @@ void log_exception(e_xbt_log_priority_t prio, const char* context, std::exceptio } } -static void showBacktrace(std::vector& bt) +static void show_backtrace(const simgrid::xbt::Backtrace& bt) { if (simgrid::config::get_value("exception/cutpath")) { XBT_LOG(xbt_log_priority_critical, "Display of current backtrace disabled by --cfg=exception/cutpath."); return; } - std::vector res = resolve_backtrace(&bt[0], bt.size()); + std::vector res = resolve_backtrace(bt); XBT_LOG(xbt_log_priority_critical, "Current backtrace:"); for (std::string const& s : res) XBT_LOG(xbt_log_priority_critical, " -> %s", s.c_str()); @@ -142,7 +141,7 @@ static void handler() // Get the current backtrace and exception auto e = std::current_exception(); - auto bt = backtrace(); + simgrid::xbt::Backtrace bt = simgrid::xbt::backtrace(); try { std::rethrow_exception(e); } @@ -150,7 +149,7 @@ static void handler() // We manage C++ exception ourselves catch (std::exception& e) { log_exception(xbt_log_priority_critical, "Uncaught exception", e); - showBacktrace(bt); + show_backtrace(bt); std::abort(); } @@ -161,7 +160,7 @@ static void handler() previous_terminate_handler(); else { XBT_ERROR("Unknown uncaught exception"); - showBacktrace(bt); + show_backtrace(bt); std::abort(); } } -- 2.20.1