diff --git a/backtrace_execinfo.cpp b/backtrace_execinfo.cpp index 144eb079..0fa7d513 100644 --- a/backtrace_execinfo.cpp +++ b/backtrace_execinfo.cpp @@ -17,9 +17,14 @@ #include "backtrace.hpp" -#include "debug.hpp" +#include "./debug.hpp" +#include "./exe.hpp" +#include "./io.hpp" #include "types/casts.hpp" +#include +#include +#include #include #include #include @@ -44,17 +49,42 @@ debug::backtrace::backtrace (void): } +//----------------------------------------------------------------------------- +static std::string +addr2line (const void *addr) +{ +#if defined(ADDR2LINE) + using pstream_t = std::unique_ptr; + + std::ostringstream cmd; + cmd << ADDR2LINE << " -e " << util::image_path () << ' ' << std::hex << addr; + + pstream_t stream ( + ::popen (cmd.str ().c_str (), "r"), + ::pclose + ); + + // inefficient to copy from vector to string, but it's not a high priority path + auto data = util::slurp (stream.get ()); + return std::string (data.cbegin (), data.cend ()); + +#else + return "\n"; +#endif +} + + //----------------------------------------------------------------------------- ostream& debug::operator <<(ostream &os, const debug::backtrace &rhs) { const auto frames = rhs.frames (); // We don't use the array form of unique_ptr as clang fails on ambigious constructors - typedef unique_ptr unique_str; - unique_str names (backtrace_symbols (frames.data (), frames.size ()), ::free); + typedef unique_ptr str_t; + str_t names (backtrace_symbols (frames.data (), frames.size ()), ::free); for (unsigned int i = 0; i < frames.size (); ++i) - os << frames[i] << "\t" << names.get()[i] << "\n"; + os << frames[i] << '\t' << names.get()[i] << '\t' << addr2line (frames[i]); return os; } diff --git a/configure.ac b/configure.ac index dc07ca4c..1da26c94 100644 --- a/configure.ac +++ b/configure.ac @@ -95,6 +95,9 @@ PKG_CHECK_MODULES([ZLIB], [zlib >= 1.2.0]) AC_SUBST(ZLIB_CFLAGS) AC_SUBST(ZLIB_LIBS) +AC_CHECK_TOOL([ADDR2LINE], [addr2line], [:]) +AS_IF([test "x$ADDR2LINE" != "x:"], [AC_DEFINE_UNQUOTED([ADDR2LINE], ["$ADDR2LINE"], [addr2line tool name])]) + ############################################################################### ## Performance and build optimisations