diff --git a/Makefile.am b/Makefile.am index c690f261..38bd7315 100644 --- a/Makefile.am +++ b/Makefile.am @@ -96,10 +96,12 @@ UTIL_FILES = \ version.hpp -if HAVE_EXECINFO +if PLATFORM_LINUX UTIL_FILES += backtrace_execinfo.cpp -else -UTIL_FILES += backtrace_null.cpp +endif + +if PLATFORM_WIN32 +UTIL_FILES += backtrace_win32.cpp endif CLEANFILES = json.cpp version.cpp ip.cpp diff --git a/backtrace.hpp b/backtrace.hpp index e818993d..dfe148e6 100644 --- a/backtrace.hpp +++ b/backtrace.hpp @@ -15,8 +15,9 @@ namespace debug { const decltype(m_frames)& frames(void) const { return m_frames; } }; + + std::ostream& + operator <<(std::ostream&, const debug::backtrace&); } -std::ostream& -operator <<(std::ostream&, const debug::backtrace&); diff --git a/backtrace_execinfo.cpp b/backtrace_execinfo.cpp index 06d2cff1..26f6124c 100644 --- a/backtrace_execinfo.cpp +++ b/backtrace_execinfo.cpp @@ -23,7 +23,7 @@ debug::backtrace::backtrace (void): ostream& -operator <<(ostream &os, const debug::backtrace &rhs) { +debug::operator <<(ostream &os, const debug::backtrace &rhs) { const auto frames = rhs.frames (); typedef unique_ptr unique_str; diff --git a/backtrace_win32.cpp b/backtrace_win32.cpp new file mode 100644 index 00000000..8c87dd8d --- /dev/null +++ b/backtrace_win32.cpp @@ -0,0 +1,48 @@ +#include "backtrace.hpp" + +#include "debug.hpp" +#include "except.hpp" +#include "memory.hpp" + +#include +#include +#include +#include + + +debug::backtrace::backtrace (void) { + m_frames.resize (DEFAULT_DEPTH); + + auto process = GetCurrentProcess(); + if (!SymInitialize (process, NULL, TRUE)) + win32_error::throw_code (); + + while (CaptureStackBackTrace (1, m_frames.size (), m_frames.data (), NULL) == m_frames.size ()) + m_frames.resize (m_frames.size () * 2); +} + + +std::ostream& +debug::operator <<(std::ostream &os, const debug::backtrace &rhs) { + os << "Fuck Windows and it's stupid backtracing\n"; + return os; + + auto process = GetCurrentProcess (); + if (!process) + win32_error::throw_code (); + + static const size_t MAX_LENGTH = 255; + scoped_malloc symbol_mem (calloc (sizeof (SYMBOL_INFO) + MAX_LENGTH + 1, 1)); + + SYMBOL_INFO *symbol = static_cast (symbol_mem.get ()); + symbol->MaxNameLen = MAX_LENGTH; + symbol->SizeOfStruct = sizeof (SYMBOL_INFO); + + for (void *frame: rhs.frames ()) { + std::cerr << process << " " << frame << " " << symbol << "\n"; + SymFromAddr (process, (DWORD64)frame, 0, symbol); + std::cerr << frame << "\t" << symbol->Name << "\n"; + } + + return os; +} diff --git a/configure.ac b/configure.ac index f61b33fd..d8bc7bb7 100644 --- a/configure.ac +++ b/configure.ac @@ -95,9 +95,14 @@ COMMON_CFLAGS="$COMMON_CFLAGS -D_GNU_SOURCE" case $host_os in mingw32) + AM_CONDITIONAL([PLATFORM_WIN32], [true]) + AM_CONDITIONAL([PLATFORM_LINUX], [false]) + COMMON_LDFLAGS="$COMMON_LDFLAGS -ldbghelp" ;; linux-gnu) + AM_CONDITIONAL([PLATFORM_WIN32], [false]) + AM_CONDITIONAL([PLATFORM_LINUX], [true]) ;; *)