diff --git a/Makefile.am b/Makefile.am index ec1bc824..e14dff64 100644 --- a/Makefile.am +++ b/Makefile.am @@ -301,12 +301,18 @@ UTIL_FILES += \ win32/registry.cpp endif -if HAVE_EXECINFO -UTIL_FILES += backtrace_execinfo.cpp -else -UTIL_FILES += backtrace_null.cpp + +BACKTRACE_FILES = +if HAVE_CAPTURESTACKBACKTRACE +BACKTRACE_FILES += backtrace_win32.cpp endif +if HAVE_EXECINFO +BACKTRACE_FILES += backtrace_execinfo.cpp +endif + +UTIL_FILES += $(BACKTRACE_FILES) + ############################################################################### ## Local build rules diff --git a/backtrace.hpp b/backtrace.hpp index 7ac3c487..1d5d61aa 100644 --- a/backtrace.hpp +++ b/backtrace.hpp @@ -25,15 +25,15 @@ //----------------------------------------------------------------------------- namespace debug { class backtrace { - protected: - static const unsigned int DEFAULT_DEPTH = 16; - std::vector m_frames; + protected: + static const unsigned int DEFAULT_DEPTH = 16; + std::vector m_frames; - public: - backtrace (void); + public: + backtrace (void); - const decltype(m_frames)& frames(void) const - { return m_frames; } + const decltype(m_frames)& frames(void) const + { return m_frames; } }; std::ostream& diff --git a/backtrace_execinfo.cpp b/backtrace_execinfo.cpp index 251095c7..c9be021c 100644 --- a/backtrace_execinfo.cpp +++ b/backtrace_execinfo.cpp @@ -33,8 +33,8 @@ /////////////////////////////////////////////////////////////////////////////// debug::backtrace::backtrace (void): - m_frames (DEFAULT_DEPTH) { - + m_frames (DEFAULT_DEPTH) +{ size_t last; size_t size = m_frames.size (); diff --git a/backtrace_win32.cpp b/backtrace_win32.cpp index 82d21f4f..b53fd7d2 100644 --- a/backtrace_win32.cpp +++ b/backtrace_win32.cpp @@ -12,14 +12,14 @@ * limitations under the License. * * Copyright: - * 2012, Danny Robson + * 2012-2016, Danny Robson */ -#include "backtrace.hpp" +#include "./backtrace.hpp" -#include "debug.hpp" -#include "except.hpp" -#include "memory.hpp" +#include "./win32/handle.hpp" +#include "./debug.hpp" +#include "./except.hpp" #include #include @@ -27,38 +27,49 @@ #include -debug::backtrace::backtrace (void) { +/////////////////////////////////////////////////////////////////////////////// +debug::backtrace::backtrace (void) +{ m_frames.resize (DEFAULT_DEPTH); auto process = GetCurrentProcess(); if (!SymInitialize (process, NULL, TRUE)) - win32_error::throw_code (); + util::win32_error::throw_code (); + + while (true) { + auto res = CaptureStackBackTrace (1, m_frames.size (), m_frames.data (), NULL); + if (res != m_frames.size ()) { + m_frames.resize (res); + break; + } - 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; + static auto self = util::win32::handle::current_process (); + static auto ready = SymInitialize (self, nullptr, TRUE); + CHECK (ready); - auto process = GetCurrentProcess (); - if (!process) - win32_error::throw_code (); + static constexpr size_t MAX_LENGTH = 255; + struct { + SYMBOL_INFO info; + char name[MAX_LENGTH + 1]; + } symbol; - 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); + symbol.info.MaxNameLen = MAX_LENGTH; + symbol.info.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"; + symbol.name[0] = '\0'; + SymFromAddr (self, (DWORD64)frame, 0, &symbol.info); + symbol.name[MAX_LENGTH] = '\0'; + + std::cerr << self << "\t" << frame << "\t" << symbol.name << "\n"; } return os; diff --git a/configure.ac b/configure.ac index fc9683e6..de6e39b2 100644 --- a/configure.ac +++ b/configure.ac @@ -53,6 +53,9 @@ AC_FUNC_MMAP AC_CHECK_FUNC([backtrace]) AM_CONDITIONAL([HAVE_EXECINFO], [test "x$ac_cv_func_backtrace" == "xyes"]) +AC_CHECK_FUNC([RtlCaptureStackBackTrace]) +AM_CONDITIONAL([HAVE_CAPTURESTACKBACKTRACE], [test "x$ac_cv_func_RtlCaptureStackBackTrace" == "xyes"]) + AC_MSG_CHECKING([for SymFromAddr]) save_LIBS="$LIBS" LIBS+=-ldbghelp