From 1c509ca20d2ace0452a656958058632a6f3df783 Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Fri, 7 May 2021 06:45:10 -0500 Subject: [PATCH] [ox/std] Improve stacktrace clarity --- deps/ox/src/ox/std/stacktrace.cpp | 54 +++++++++++++++++++++++++------ deps/ox/src/ox/std/stacktrace.hpp | 2 +- 2 files changed, 46 insertions(+), 10 deletions(-) diff --git a/deps/ox/src/ox/std/stacktrace.cpp b/deps/ox/src/ox/std/stacktrace.cpp index 85436627..137fc03e 100644 --- a/deps/ox/src/ox/std/stacktrace.cpp +++ b/deps/ox/src/ox/std/stacktrace.cpp @@ -7,23 +7,59 @@ */ #if defined(OX_USE_STDLIB) && __has_include() -#include -#include #include + +#include +#include #include + +#if __has_include() +#include +#endif #endif -#include "stacktrace.hpp" +#include "error.hpp" +#include "string.hpp" +#include "trace.hpp" +#include "units.hpp" +#include "utility.hpp" +#include "vector.hpp" namespace ox { -void printStackTrace([[maybe_unused]]int shave) noexcept { #if defined(OX_USE_STDLIB) && __has_include() - std::array frames; - auto size = static_cast(backtrace(frames.data(), frames.size())); - if (size > shave) { - std::cout << "\nStacktrace:\n"; - backtrace_symbols_fd(frames.data() + shave, size - shave, STDERR_FILENO); +[[nodiscard]] +static String symbolicate([[maybe_unused]]const char **frames, [[maybe_unused]]std::size_t symbolsLen, [[maybe_unused]]const char *linePrefix) { +#if __has_include() + String out; + for (auto i = 0u; i < symbolsLen; ++i) { + Dl_info info; + if (dladdr(frames[i], &info) && info.dli_sname) { + int status = -1; + const auto name = abi::__cxa_demangle(info.dli_sname, nullptr, 0, &status); + if (status == 0) { + out += sfmt("\t{}: {}\n", i, name); + continue; + } + } + out += sfmt("\t{}\n", frames[i]); + } + return move(out); +#else // __has_include() + return {}; +#endif // __has_include() +} +#endif // defined(OX_USE_STDLIB) && __has_include() + +void printStackTrace([[maybe_unused]]unsigned shave) noexcept { +#if defined(OX_USE_STDLIB) && __has_include() + Vector frames(1000); + frames.resize(static_cast(backtrace(frames.data(), frames.size()))); + if (frames.size() > shave) { + const auto symbols = backtrace_symbols(frames.data() + shave, frames.size() - shave); + const auto symbolicatedStacktrace = symbolicate(bit_cast(frames.data()), frames.size() - shave, "\t"); + free(symbols); + oxErrf("Stacktrace:\n{}", symbolicatedStacktrace); } #endif } diff --git a/deps/ox/src/ox/std/stacktrace.hpp b/deps/ox/src/ox/std/stacktrace.hpp index 6045dc49..d8685e29 100644 --- a/deps/ox/src/ox/std/stacktrace.hpp +++ b/deps/ox/src/ox/std/stacktrace.hpp @@ -15,6 +15,6 @@ namespace ox { * * @param shave number of call levels to shave off the top */ -void printStackTrace(int shave = 1) noexcept; +void printStackTrace(unsigned shave = 1) noexcept; }