diff --git a/build/Jamfile.v2 b/build/Jamfile.v2 index d9c2418..cc07af8 100644 --- a/build/Jamfile.v2 +++ b/build/Jamfile.v2 @@ -51,6 +51,8 @@ explicit WinDbg ; mp-run-simple has_windbg_cached.cpp : : : Dbgeng ole32 : WinDbgCached ; explicit WinDbgCached ; +local libraries ; + lib boost_stacktrace_noop : # sources ../src/noop.cpp @@ -62,7 +64,7 @@ lib boost_stacktrace_noop #shared:BOOST_STACKTRACE_DYN_LINK=1 ; -boost-install boost_stacktrace_noop ; +libraries += boost_stacktrace_noop ; lib boost_stacktrace_backtrace : # sources @@ -78,7 +80,7 @@ lib boost_stacktrace_backtrace #shared:BOOST_STACKTRACE_DYN_LINK=1 ; -boost-install boost_stacktrace_backtrace ; +libraries += boost_stacktrace_backtrace ; lib boost_stacktrace_addr2line : # sources @@ -93,7 +95,7 @@ lib boost_stacktrace_addr2line #shared:BOOST_STACKTRACE_DYN_LINK=1 ; -boost-install boost_stacktrace_addr2line ; +libraries += boost_stacktrace_addr2line ; lib boost_stacktrace_basic : # sources @@ -108,7 +110,7 @@ lib boost_stacktrace_basic #shared:BOOST_STACKTRACE_DYN_LINK=1 ; -boost-install boost_stacktrace_basic ; +libraries += boost_stacktrace_basic ; lib boost_stacktrace_windbg : # sources @@ -123,7 +125,7 @@ lib boost_stacktrace_windbg #shared:BOOST_STACKTRACE_DYN_LINK=1 ; -boost-install boost_stacktrace_windbg ; +libraries += boost_stacktrace_windbg ; lib boost_stacktrace_windbg_cached : # sources @@ -138,5 +140,6 @@ lib boost_stacktrace_windbg_cached #shared:BOOST_STACKTRACE_DYN_LINK=1 ; -boost-install boost_stacktrace_windbg_cached ; +libraries += boost_stacktrace_windbg_cached ; +boost-install $(libraries) ; diff --git a/doc/stacktrace.qbk b/doc/stacktrace.qbk index df843d8..e6e419f 100644 --- a/doc/stacktrace.qbk +++ b/doc/stacktrace.qbk @@ -293,13 +293,13 @@ By default Boost.Stacktrace is a header-only library, but you may change that an In header only mode library could be tuned by macro. If one of the link macro from above is defined, you have to manually link with one of the libraries: [table:libconfig Config [[Macro name or default] [Library] [Effect] [Platforms] [Uses debug information [footnote This will provide more readable backtraces with *source code locations* if the binary is built with debug information.]] [Uses dynamic exports information [footnote This will provide readable function names in backtrace for functions that are exported by the binary. Compiling with `-rdynamic` flag, without `-fisibility=hidden` or marking functions as exported produce a better stacktraces.]] ] - [[['default for MSVC] / *BOOST_STACKTRACE_USE_WINDBG*] [*boost_stacktrace_windbg*] [ Uses COM to show debug info. ] [Windows] [yes] [no]] - [[['default other platforms]] [*boost_stacktrace_basic*] [Uses compiler intrinsics to collect stacktrace and if possible `::dladdr` to show information about the symbol. Requires linking with *libdl* library on POSIX platforms.] [Not MSVC compiler on POSIX or Windows] [no] [yes]] - [[*BOOST_STACKTRACE_USE_WINDBG_CACHED*] [*boost_stacktrace_windbg_cached*] [ Uses COM to show debug info and caches COM instances in TLS for better performance. Useful only for cases when traces are gathered very often. [footnote This may affect other components of your program that use COM, because this mode calls the `CoInitializeEx(0, COINIT_MULTITHREADED)` on first use and does not call `::CoUninitialize();` until the current thread is destroyed. ] ] [Windows] [yes] [no]] + [[['default for MSVC, Intel on Windows, MinGW-w64] / *BOOST_STACKTRACE_USE_WINDBG*] [*boost_stacktrace_windbg*] [ Uses COM to show debug info. May require linking with *ole32* and *dbgeng*. ] [MSVC, MinGW-w64, Intel on Windows] [yes] [no]] + [[['default for other platforms]] [*boost_stacktrace_basic*] [Uses compiler intrinsics to collect stacktrace and if possible `::dladdr` to show information about the symbol. Requires linking with *libdl* library on POSIX platforms.] [Any compiler on POSIX or MinGW] [no] [yes]] + [[*BOOST_STACKTRACE_USE_WINDBG_CACHED*] [*boost_stacktrace_windbg_cached*] [ Uses COM to show debug info and caches COM instances in TLS for better performance. Useful only for cases when traces are gathered very often. [footnote This may affect other components of your program that use COM, because this mode calls the `CoInitializeEx(0, COINIT_MULTITHREADED)` on first use and does not call `::CoUninitialize();` until the current thread is destroyed. ] May require linking with *ole32* and *dbgeng*. ] [MSVC, Intel on Windows] [yes] [no]] [[*BOOST_STACKTRACE_USE_BACKTRACE*] [*boost_stacktrace_backtrace*] [Requires linking with *libdl* on POSIX and *libbacktrace* libraries. *libbacktrace* is probably already installed in your system, or built into your compiler. - Otherwise (if you are a *MinGW* user for example) it can be downloaded [@https://github.com/ianlancetaylor/libbacktrace from here] or [@https://github.com/gcc-mirror/gcc/tree/master/libbacktrace from here]. ] [GCC/MinGW/Clang... on POSIX or Windows] [yes] [yes]] - [[*BOOST_STACKTRACE_USE_ADDR2LINE*] [*boost_stacktrace_addr2line*] [Use *addr2line* program to retrieve stacktrace. Requires linking with *libdl* library and `::fork` system call. Macro *BOOST_STACKTRACE_ADDR2LINE_LOCATION* must be defined to the absolute path to the addr2line executable if it is not located in /usr/bin/addr2line. ] [GCC/MinGW/Clang... on POSIX] [yes] [yes]] + Otherwise (if you are a *MinGW*/*MinGW-w64* user for example) it can be downloaded [@https://github.com/ianlancetaylor/libbacktrace from here] or [@https://github.com/gcc-mirror/gcc/tree/master/libbacktrace from here]. ] [Any compiler on POSIX, or MinGW, or MinGW-w64] [yes] [yes]] + [[*BOOST_STACKTRACE_USE_ADDR2LINE*] [*boost_stacktrace_addr2line*] [Use *addr2line* program to retrieve stacktrace. Requires linking with *libdl* library and `::fork` system call. Macro *BOOST_STACKTRACE_ADDR2LINE_LOCATION* must be defined to the absolute path to the addr2line executable if it is not located in /usr/bin/addr2line. ] [Any compiler on POSIX] [yes] [yes]] [[*BOOST_STACKTRACE_USE_NOOP*] [*boost_stacktrace_noop*] [Use this if you wish to disable backtracing. `stacktrace::size()` with that macro always returns 0. ] [All] [no] [no]] ] @@ -309,6 +309,25 @@ In header only mode library could be tuned by macro. If one of the link macro fr * if you wish to disable backtracing and you use the library in header only mode, you just need to define *BOOST_STACKTRACE_USE_NOOP* for the whole project * if you wish to disable backtracing and *BOOST_STACKTRACE_LINK* is defined, you just need link with *-lboost_stacktrace_noop* +[section MinGW and MinGW-w64 specific notes] + +MinGW-w64 and MinGW (without -w64) users have to install libbacktrace for getting better stacktraces. Follow the instruction: + +Let's assume that you've installed MinGW into C:\MinGW and downloaded [@https://github.com/ianlancetaylor/libbacktrace libbacktrace sources] into C:\libbacktrace-master + +* Configure & build libbacktrace from console: + * C:\MinGW\msys\1.0\bin\sh.exe + * cd /c/libbacktrace-master + * ./configure CC=/c/MinGW/bin/gcc.exe CXX=/c/MinGW/bin/g++.exe + * make + * ./libtool --mode=install /usr/bin/install -c libbacktrace.la '/c/libbacktrace-master' +* Add info to the project-config.jam in the Boost folder: + * using gcc : 6 : "C:\\MinGW\\bin\\g++.exe" : -I"C:\\libbacktrace-master\\" -L"C:\\libbacktrace-master\\" ; +* Now you can use a header only version by defining *BOOST_STACKTRACE_USE_BACKTRACE* for your project or build the stacktrace library from Boost folder: + * b2.exe toolset=gcc-6 --with-stacktrace + +[endsect] + [endsect] [section Acknowledgements] diff --git a/example/terminate_handler.cpp b/example/terminate_handler.cpp index 8b51935..7b5bd78 100644 --- a/example/terminate_handler.cpp +++ b/example/terminate_handler.cpp @@ -30,7 +30,9 @@ BOOST_NOINLINE void foo(int i) { void my_signal_handler(int signum) { ::signal(signum, SIG_DFL); + #ifndef BOOST_WINDOWS boost::stacktrace::safe_dump_to("./backtrace.dump"); + #endif ::raise(SIGABRT); } //] @@ -296,8 +298,12 @@ int main(int argc, const char* argv[]) { // We are copying files to make sure that stacktrace printing works independently from executable name copy_and_run(argv[0], '1', true); copy_and_run(argv[0], '2', false); + +#ifndef BOOST_WINDOWS + // There are some issues with async-safety of shared mmory writes on Windows. copy_and_run(argv[0], '3', true); copy_and_run(argv[0], '4', false); +#endif return test_inplace(); } diff --git a/include/boost/stacktrace/detail/safe_dump_posix.ipp b/include/boost/stacktrace/detail/safe_dump_posix.ipp index 37eef5a..97792c9 100644 --- a/include/boost/stacktrace/detail/safe_dump_posix.ipp +++ b/include/boost/stacktrace/detail/safe_dump_posix.ipp @@ -16,6 +16,7 @@ #include // ::write #include // ::open +#include // S_IWUSR and friends namespace boost { namespace stacktrace { namespace detail { diff --git a/include/boost/stacktrace/safe_dump_to.hpp b/include/boost/stacktrace/safe_dump_to.hpp index dbaa6d8..9d648b4 100644 --- a/include/boost/stacktrace/safe_dump_to.hpp +++ b/include/boost/stacktrace/safe_dump_to.hpp @@ -12,7 +12,10 @@ # pragma once #endif +#if defined(BOOST_WINDOWS) #include +#endif + #include #ifdef BOOST_INTEL diff --git a/include/boost/stacktrace/stacktrace.hpp b/include/boost/stacktrace/stacktrace.hpp index 3c72488..200dd9f 100644 --- a/include/boost/stacktrace/stacktrace.hpp +++ b/include/boost/stacktrace/stacktrace.hpp @@ -87,7 +87,11 @@ class basic_stacktrace { } // Failed to fit in `buffer_size`. Allocating memory: +#ifdef BOOST_NO_CXX11_ALLOCATOR typedef typename Allocator::template rebind::other allocator_void_t; +#else + typedef typename std::allocator_traits::template rebind_alloc allocator_void_t; +#endif std::vector buf(buffer_size * 2, 0, impl_.get_allocator()); do { const std::size_t frames_count = boost::stacktrace::detail::this_thread_frames::collect(&buf[0], buf.size(), frames_to_skip + 1);