From: Gunnar Beutner Date: Sun, 23 Mar 2014 18:39:25 +0000 (+0100) Subject: Move Addr2Line function to the Utility class. X-Git-Tag: v0.0.9~34^2~13 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=27955843c051cd57ef9c0b2b7eed43d5fcc7ad6d;p=icinga2 Move Addr2Line function to the Utility class. Refs #5846 --- diff --git a/lib/base/stacktrace.cpp b/lib/base/stacktrace.cpp index 71ab6772c..ba3716639 100644 --- a/lib/base/stacktrace.cpp +++ b/lib/base/stacktrace.cpp @@ -22,7 +22,6 @@ #include "base/utility.h" #include "base/convert.h" #include "base/application.h" -#include #ifdef HAVE_BACKTRACE_SYMBOLS # include @@ -100,43 +99,6 @@ void StackTrace::Initialize(void) #endif /* _WIN32 */ } -/** - * Looks up source file name and line number information for the specified - * ELF executable and RVA. - * - * @param exe The ELF file. - * @param rva The RVA. - * @returns Source file and line number. - */ -String StackTrace::Addr2Line(const String& exe, uintptr_t rva) -{ -#ifndef _WIN32 - std::ostringstream msgbuf; - msgbuf << "addr2line -s -e " << Application::GetExePath(exe) << " " << std::hex << rva << " 2>/dev/null"; - - String args = msgbuf.str(); - - FILE *fp = popen(args.CStr(), "r"); - - if (!fp) - return "RVA: " + Convert::ToString(rva); - - char buffer[512] = {}; - fgets(buffer, sizeof(buffer), fp); - fclose(fp); - - String line = buffer; - boost::algorithm::trim_right(line); - - if (line.GetLength() == 0) - return "RVA: " + Convert::ToString(rva); - - return line; -#else /* _WIN32 */ - return String(); -#endif /* _WIN32 */ -} - /** * Prints a stacktrace to the specified stream. * @@ -176,15 +138,7 @@ void StackTrace::Print(std::ostream& fp, int ignoreFrames) const path = path.SubStr(slashp + 1); message = path + ": " + sym_demangled + " (" + String(sym_end); - -#ifdef HAVE_DLADDR - Dl_info dli; - - if (dladdr(m_Frames[i], &dli) > 0) { - uintptr_t rva = reinterpret_cast(m_Frames[i]) - reinterpret_cast(dli.dli_fbase); - message += " (" + Addr2Line(dli.dli_fname, rva) + ")"; - } -#endif /* HAVE_DLADDR */ + message += " (" + Utility::GetSymbolSource(m_Frames[i]); } } diff --git a/lib/base/stacktrace.h b/lib/base/stacktrace.h index a26228383..cd6828ff8 100644 --- a/lib/base/stacktrace.h +++ b/lib/base/stacktrace.h @@ -50,7 +50,6 @@ private: static boost::once_flag m_OnceFlag; static void Initialize(void); - static String Addr2Line(const String& exe, uintptr_t rva); }; I2_BASE_API std::ostream& operator<<(std::ostream& stream, const StackTrace& trace); diff --git a/lib/base/utility.cpp b/lib/base/utility.cpp index 44c5c1f4b..189f77333 100644 --- a/lib/base/utility.cpp +++ b/lib/base/utility.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #ifdef __FreeBSD__ # include @@ -81,6 +82,69 @@ String Utility::GetTypeName(const std::type_info& ti) return DemangleSymbolName(ti.name()); } +/** + * Looks up source file name and line number information for the specified + * ELF executable and RVA. + * + * @param exe The ELF file. + * @param rva The RVA. + * @returns Source file and line number. + */ +String Utility::Addr2Line(const String& exe, uintptr_t rva) +{ +#ifndef _WIN32 + std::ostringstream msgbuf; + msgbuf << "addr2line -s -e " << Application::GetExePath(exe) << " " << std::hex << rva << " 2>/dev/null"; + + String args = msgbuf.str(); + + FILE *fp = popen(args.CStr(), "r"); + + if (!fp) + return "RVA: " + Convert::ToString(rva); + + char buffer[512] = {}; + fgets(buffer, sizeof(buffer), fp); + fclose(fp); + + String line = buffer; + boost::algorithm::trim_right(line); + + if (line.GetLength() == 0) + return "RVA: " + Convert::ToString(rva); + + return line; +#else /* _WIN32 */ + return String(); +#endif /* _WIN32 */ +} + +String Utility::GetSymbolName(const void *addr) +{ +#ifdef HAVE_DLADDR + Dl_info dli; + + if (dladdr(addr, &dli) > 0) + return dli.dli_sname; +#endif /* HAVE_DLADDR */ + + return ""; +} + +String Utility::GetSymbolSource(const void *addr) +{ +#ifdef HAVE_DLADDR + Dl_info dli; + + if (dladdr(addr, &dli) > 0) { + uintptr_t rva = reinterpret_cast(addr) - reinterpret_cast(dli.dli_fbase); + return Addr2Line(dli.dli_fname, rva); + } +#endif /* HAVE_DLADDR */ + + return ""; +} + /** * Performs wildcard pattern matching. * diff --git a/lib/base/utility.h b/lib/base/utility.h index 4a384acde..dbea5a6f2 100644 --- a/lib/base/utility.h +++ b/lib/base/utility.h @@ -59,6 +59,9 @@ class I2_BASE_API Utility public: static String DemangleSymbolName(const String& sym); static String GetTypeName(const std::type_info& ti); + static String Addr2Line(const String& exe, uintptr_t rva); + static String GetSymbolName(const void *addr); + static String GetSymbolSource(const void *addr); static bool Match(const String& pattern, const String& text);