Compare commits

..

12 Commits

16 changed files with 112 additions and 25 deletions

View File

@@ -4,14 +4,21 @@
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/config.hpp>
#include <string>
#include <cstring>
#include <windows.h>
#include "dbgeng.h"
#ifdef BOOST_NO_CXX11_THREAD_LOCAL
# error Your compiler does not support C++11 thread_local storage. It`s impossible to build with BOOST_STACKTRACE_USE_WINDBG_CACHED.
#endif
int foo() {
static thread_local int i = 0;
static thread_local std::string i = std::string();
return i;
return i.size();
}
int main() {

View File

@@ -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" : <compileflags>-I"C:\\libbacktrace-master\\" <linkflags>-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]

View File

@@ -296,8 +296,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();
}

View File

@@ -17,6 +17,10 @@
#include <unwind.h>
#include <cstdio>
#if !defined(_GNU_SOURCE) && !defined(BOOST_STACKTRACE_GNU_SOURCE_NOT_REQUIRED) && !defined(BOOST_WINDOWS)
#error "Boost.Stacktrace requires `_Unwind_Backtrace` function. Define `_GNU_SOURCE` macro or `BOOST_STACKTRACE_GNU_SOURCE_NOT_REQUIRED` if _Unwind_Backtrace is available without `_GNU_SOURCE`."
#endif
namespace boost { namespace stacktrace { namespace detail {
struct unwind_state {

View File

@@ -20,7 +20,7 @@
#include <boost/stacktrace/safe_dump_to.hpp> // boost::stacktrace::detail::native_frame_ptr_t
#include <boost/stacktrace/detail/void_ptr_cast.hpp>
#include <boost/stacktrace/detail/push_options.pp>
#include <boost/stacktrace/detail/push_options.h>
/// @file boost/stacktrace/detail/frame_decl.hpp
/// Use <boost/stacktrace/frame.hpp> header instead of this one!
@@ -154,6 +154,6 @@ namespace detail {
}} // namespace boost::stacktrace
#include <boost/stacktrace/detail/pop_options.pp>
#include <boost/stacktrace/detail/pop_options.h>
#endif // BOOST_STACKTRACE_DETAIL_FRAME_DECL_HPP

View File

@@ -164,7 +164,7 @@ public:
#else
#ifdef BOOST_NO_CXX11_THREAD_LOCAL
# error Your compiler does not support C++11 thread_local storage. It's impossible to build with BOOST_STACKTRACE_USE_WINDBG_CACHED.
# error Your compiler does not support C++11 thread_local storage. It`s impossible to build with BOOST_STACKTRACE_USE_WINDBG_CACHED.
#endif
static com_holder< ::IDebugSymbols>& get_thread_local_debug_inst() BOOST_NOEXCEPT {

View File

@@ -13,6 +13,7 @@
#endif
#include <boost/stacktrace/detail/to_hex_array.hpp>
#include <boost/stacktrace/detail/location_from_symbol.hpp>
#include <boost/core/demangle.hpp>
#include <boost/lexical_cast.hpp>
@@ -44,9 +45,11 @@ inline void libbacktrace_error_callback(void* /*data*/, const char* /*msg*/, int
}
extern inline ::backtrace_state* construct_state() BOOST_NOEXCEPT {
inline ::backtrace_state* construct_state(const program_location& prog_location) BOOST_NOEXCEPT {
// Currently `backtrace_create_state` can not detect file name on Windows https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82543
// That's why we provide a `prog_location` here.
return ::backtrace_create_state(
0, 0 /*thread-safe*/, boost::stacktrace::detail::libbacktrace_error_callback, 0
prog_location.name(), 0 /*thread-safe*/, boost::stacktrace::detail::libbacktrace_error_callback, 0
);
// TODO: this does not seem to work well when this function is in .so:
@@ -69,6 +72,7 @@ extern inline ::backtrace_state* construct_state() BOOST_NOEXCEPT {
struct to_string_using_backtrace {
std::string res;
boost::stacktrace::detail::program_location prog_location;
::backtrace_state* state;
std::string filename;
std::size_t line;
@@ -100,7 +104,7 @@ struct to_string_using_backtrace {
}
to_string_using_backtrace() BOOST_NOEXCEPT {
state = boost::stacktrace::detail::construct_state();
state = boost::stacktrace::detail::construct_state(prog_location);
}
};
@@ -110,7 +114,8 @@ typedef to_string_impl_base<to_string_using_backtrace> to_string_impl;
inline std::string name_impl(const void* addr) {
std::string res;
::backtrace_state* state = boost::stacktrace::detail::construct_state();
boost::stacktrace::detail::program_location prog_location;
::backtrace_state* state = boost::stacktrace::detail::construct_state(prog_location);
boost::stacktrace::detail::pc_data data = {&res, 0, 0};
if (state) {
@@ -134,7 +139,8 @@ inline std::string name_impl(const void* addr) {
std::string frame::source_file() const {
std::string res;
::backtrace_state* state = boost::stacktrace::detail::construct_state();
boost::stacktrace::detail::program_location prog_location;
::backtrace_state* state = boost::stacktrace::detail::construct_state(prog_location);
boost::stacktrace::detail::pc_data data = {0, &res, 0};
if (state) {
@@ -151,7 +157,8 @@ std::string frame::source_file() const {
}
std::size_t frame::source_line() const {
::backtrace_state* state = boost::stacktrace::detail::construct_state();
boost::stacktrace::detail::program_location prog_location;
::backtrace_state* state = boost::stacktrace::detail::construct_state(prog_location);
boost::stacktrace::detail::pc_data data = {0, 0, 0};
if (state) {

View File

@@ -20,8 +20,8 @@
namespace boost { namespace stacktrace { namespace detail {
class location_from_symbol {
#if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
class location_from_symbol {
::Dl_info dli_;
public:
@@ -40,9 +40,19 @@ public:
const char* name() const BOOST_NOEXCEPT {
return dli_.dli_fname;
}
#else
BOOST_STATIC_CONSTEXPR boost::detail::winapi::DWORD_ DEFAULT_PATH_SIZE_ = 260;
};
class program_location {
public:
const char* name() const BOOST_NOEXCEPT {
return 0;
}
};
#else
class location_from_symbol {
BOOST_STATIC_CONSTEXPR boost::detail::winapi::DWORD_ DEFAULT_PATH_SIZE_ = 260;
char file_name_[DEFAULT_PATH_SIZE_];
public:
@@ -68,9 +78,28 @@ public:
const char* name() const BOOST_NOEXCEPT {
return file_name_;
}
#endif
};
class program_location {
BOOST_STATIC_CONSTEXPR boost::detail::winapi::DWORD_ DEFAULT_PATH_SIZE_ = 260;
char file_name_[DEFAULT_PATH_SIZE_];
public:
program_location() BOOST_NOEXCEPT {
file_name_[0] = '\0';
const boost::detail::winapi::HMODULE_ handle = 0;
if (!boost::detail::winapi::GetModuleFileNameA(handle, file_name_, DEFAULT_PATH_SIZE_)) {
file_name_[0] = '\0';
}
}
const char* name() const BOOST_NOEXCEPT {
return file_name_[0] ? file_name_ : 0;
}
};
#endif
}}} // namespace boost::stacktrace::detail
#endif // BOOST_STACKTRACE_DETAIL_LOCATION_FROM_SYMBOL_HPP

View File

@@ -16,6 +16,7 @@
#include <unistd.h> // ::write
#include <fcntl.h> // ::open
#include <sys/stat.h> // S_IWUSR and friends
namespace boost { namespace stacktrace { namespace detail {

View File

@@ -20,7 +20,7 @@
#include <boost/stacktrace/safe_dump_to.hpp> // boost::stacktrace::detail::native_frame_ptr_t
#include <boost/stacktrace/detail/frame_decl.hpp>
#include <boost/stacktrace/detail/push_options.pp>
#include <boost/stacktrace/detail/push_options.h>
namespace boost { namespace stacktrace {
@@ -50,7 +50,7 @@ std::basic_ostream<CharT, TraitsT>& operator<<(std::basic_ostream<CharT, TraitsT
/// @cond
#include <boost/stacktrace/detail/pop_options.pp>
#include <boost/stacktrace/detail/pop_options.h>
#ifndef BOOST_STACKTRACE_LINK
# if defined(BOOST_STACKTRACE_USE_NOOP)

View File

@@ -12,7 +12,8 @@
# pragma once
#endif
#include <boost/stacktrace/detail/push_options.pp>
#include <boost/detail/winapi/config.hpp>
#include <boost/stacktrace/detail/push_options.h>
#ifdef BOOST_INTEL
# pragma warning(push)
@@ -195,7 +196,7 @@ BOOST_FORCEINLINE std::size_t safe_dump_to(std::size_t skip, std::size_t max_dep
# pragma warning(pop)
#endif
#include <boost/stacktrace/detail/pop_options.pp>
#include <boost/stacktrace/detail/pop_options.h>
#if !defined(BOOST_STACKTRACE_LINK) || defined(BOOST_STACKTRACE_INTERNAL_BUILD_LIBS)
# if defined(BOOST_STACKTRACE_USE_NOOP)
@@ -207,7 +208,7 @@ BOOST_FORCEINLINE std::size_t safe_dump_to(std::size_t skip, std::size_t max_dep
# else
# include <boost/stacktrace/detail/safe_dump_posix.ipp>
# endif
# if defined(BOOST_WINDOWS) && !defined(BOOST_GCC)
# if defined(BOOST_WINDOWS) && !defined(BOOST_WINAPI_IS_MINGW) // MinGW does not provide RtlCaptureStackBackTrace. MinGW-w64 does.
# include <boost/stacktrace/detail/collect_msvc.ipp>
# else
# include <boost/stacktrace/detail/collect_unwind.ipp>

View File

@@ -7,5 +7,10 @@
#define BOOST_STACKTRACE_INTERNAL_BUILD_LIBS
#define BOOST_STACKTRACE_USE_ADDR2LINE
#define BOOST_STACKTRACE_LINK
#ifndef _GNU_SOURCE
# define _GNU_SOURCE
#endif
#include <boost/stacktrace/detail/frame_unwind.ipp>
#include <boost/stacktrace/safe_dump_to.hpp>

View File

@@ -7,5 +7,10 @@
#define BOOST_STACKTRACE_INTERNAL_BUILD_LIBS
#define BOOST_STACKTRACE_USE_BACKTRACE
#define BOOST_STACKTRACE_LINK
#ifndef _GNU_SOURCE
# define _GNU_SOURCE
#endif
#include <boost/stacktrace/detail/frame_unwind.ipp>
#include <boost/stacktrace/safe_dump_to.hpp>

View File

@@ -6,5 +6,10 @@
#define BOOST_STACKTRACE_INTERNAL_BUILD_LIBS
#define BOOST_STACKTRACE_LINK
#ifndef _GNU_SOURCE
# define _GNU_SOURCE
#endif
#include <boost/stacktrace/detail/frame_unwind.ipp>
#include <boost/stacktrace/safe_dump_to.hpp>