mirror of https://github.com/Icinga/icinga2.git
parent
ac3cbfe801
commit
f8a2ddc464
|
@ -104,6 +104,7 @@ include(CheckLibraryExists)
|
|||
check_function_exists(vfork HAVE_VFORK)
|
||||
check_function_exists(backtrace_symbols HAVE_BACKTRACE_SYMBOLS)
|
||||
check_function_exists(pipe2 HAVE_PIPE2)
|
||||
check_function_exists(dladdr HAVE_DLADDR)
|
||||
check_library_exists(crypto BIO_f_zlib "" HAVE_BIOZLIB)
|
||||
|
||||
include(GNUInstallDirs)
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#cmakedefine HAVE_BACKTRACE_SYMBOLS
|
||||
#cmakedefine HAVE_PIPE2
|
||||
#cmakedefine HAVE_VFORK
|
||||
#cmakedefine HAVE_DLADDR
|
||||
|
||||
#define ICINGA_PREFIX "${CMAKE_INSTALL_PREFIX}"
|
||||
#define ICINGA_SYSCONFDIR "${CMAKE_INSTALL_FULL_SYSCONFDIR}"
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
#include "base/stacktrace.h"
|
||||
#include "base/qstring.h"
|
||||
#include "base/utility.h"
|
||||
#include "base/convert.h"
|
||||
#include <boost/algorithm/string/trim.hpp>
|
||||
|
||||
#ifdef HAVE_BACKTRACE_SYMBOLS
|
||||
# include <execinfo.h>
|
||||
|
@ -97,6 +99,39 @@ 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 " << exe << " " << std::hex << rva;
|
||||
|
||||
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);
|
||||
|
||||
String line = buffer;
|
||||
boost::algorithm::trim_right(line);
|
||||
|
||||
return line;
|
||||
#else /* _WIN32 */
|
||||
return String();
|
||||
#endif /* _WIN32 */
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a stacktrace to the specified stream.
|
||||
*
|
||||
|
@ -118,7 +153,7 @@ void StackTrace::Print(std::ostream& fp, int ignoreFrames) const
|
|||
|
||||
char *sym_begin = strchr(messages[i], '(');
|
||||
|
||||
if (sym_begin != NULL) {
|
||||
if (sym_begin) {
|
||||
char *sym_end = strchr(sym_begin, '+');
|
||||
|
||||
if (sym_end != NULL) {
|
||||
|
@ -128,7 +163,23 @@ void StackTrace::Print(std::ostream& fp, int ignoreFrames) const
|
|||
if (sym_demangled.IsEmpty())
|
||||
sym_demangled = "<unknown function>";
|
||||
|
||||
message = String(messages[i], sym_begin) + ": " + sym_demangled + " (" + String(sym_end);
|
||||
String path = String(messages[i], sym_begin);
|
||||
|
||||
size_t slashp = path.RFind("/");
|
||||
|
||||
if (slashp != String::NPos)
|
||||
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<uintptr_t>(m_Frames[i]) - reinterpret_cast<uintptr_t>(dli.dli_fbase);
|
||||
message += " (" + Addr2Line(dli.dli_fname, rva) + ")";
|
||||
}
|
||||
#endif /* HAVE_DLADDR */
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#define STACKTRACE_H
|
||||
|
||||
#include "base/i2-base.h"
|
||||
#include "base/qstring.h"
|
||||
#include <ostream>
|
||||
#include <boost/thread/once.hpp>
|
||||
|
||||
|
@ -49,6 +50,7 @@ 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);
|
||||
|
|
Loading…
Reference in New Issue