fix memory consumption when using libbacktrace and speedup trace decoding

This commit is contained in:
Antony Polukhin
2018-10-07 20:08:27 +03:00
parent f0a9ba6809
commit 4123beb4af
3 changed files with 47 additions and 23 deletions

View File

@@ -60,30 +60,54 @@ inline void libbacktrace_error_callback(void* /*data*/, const char* /*msg*/, int
// Do nothing, just return.
}
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(
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:
// Not async-signal-safe, so this method is not called from async-safe functions.
//
// This function is not async signal safe because:
// * Dynamic initialization of a block-scope variable with static storage duration could lock a mutex
// * No guarantees on `backtrace_create_state` function.
// Not async-signal-safe, so this method is not called from async-safe functions.
//
// This function is not async signal safe because:
// * Dynamic initialization of a block-scope variable with static storage duration could lock a mutex
// * No guarantees on `backtrace_create_state` function.
//
// 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.
BOOST_SYMBOL_VISIBLE inline ::backtrace_state* construct_state(const program_location& prog_location) BOOST_NOEXCEPT {
// [dcl.inline]: A static local variable in an inline function with external linkage always refers to the same object.
/*
static ::backtrace_state* state = ::backtrace_create_state(
0, 1 , boost::stacktrace::detail::libbacktrace_error_callback, 0
);
// TODO: The most obvious solution:
//
//static ::backtrace_state* state = ::backtrace_create_state(
// prog_location.name(),
// 1, // allow safe concurrent usage of the same state
// boost::stacktrace::detail::libbacktrace_error_callback,
// 0 // pointer to data that will be passed to callback
//);
//
//
// Unfortunately, that solution segfaults when `construct_state()` function is in .so file
// and multiple threads concurrently work with state.
#ifndef BOOST_HAS_THREADS
static
#else
// Result of `construct_state()` invocation is not stored by the callers, so `thread_local`
// gives a single `state` per thread and that state is not shared between threads in any way.
# ifndef BOOST_NO_CXX11_THREAD_LOCAL
thread_local
# elif defined(__GNUC__)
static __thread
# else
/* just a local variable */
# endif
#endif
::backtrace_state* state = ::backtrace_create_state(
prog_location.name(),
0,
boost::stacktrace::detail::libbacktrace_error_callback,
0
);
return state;
*/
}
struct to_string_using_backtrace {

View File

@@ -220,14 +220,14 @@ for local p in [ glob ../example/*.cpp ]
test-suite stacktrace_torture
:
[ run torture.cpp test_impl.cpp : : : <debug-symbols>on <define>BOOST_STACKTRACE_USE_BACKTRACE $(BT_DEPS) : torture_backtrace_ho ]
[ run torture.cpp test_impl.cpp : : : <debug-symbols>on <define>BOOST_STACKTRACE_USE_ADDR2LINE $(AD2L_DEPS) : torture_addr2line_ho ]
#[ run torture.cpp test_impl.cpp : : : <debug-symbols>on <define>BOOST_STACKTRACE_USE_ADDR2LINE $(AD2L_DEPS) : torture_addr2line_ho ]
[ run torture.cpp test_impl.cpp : : : <debug-symbols>on $(WIND_DEPS) : torture_windbg_ho ]
[ run torture.cpp test_impl.cpp : : : <debug-symbols>on <define>BOOST_STACKTRACE_USE_WINDBG_CACHED $(WICA_DEPS) : torture_windbg_cached_ho ]
[ run torture.cpp test_impl.cpp : : : <debug-symbols>on $(FORCE_SYMBOL_EXPORT) $(BASIC_DEPS) : torture_basic_ho ]
[ run torture.cpp test_impl.cpp : : : <debug-symbols>on <define>BOOST_STACKTRACE_TEST_NO_DEBUG_AT_ALL $(BASIC_DEPS) : torture_basic_ho_empty ]
[ run torture.cpp test_impl.cpp : : : <debug-symbols>on <library>.//test_impl_lib_backtrace $(LINKSHARED_BT) : torture_backtrace_lib ]
[ run torture.cpp test_impl.cpp : : : <debug-symbols>on <library>.//test_impl_lib_addr2line $(LINKSHARED_AD2L) : torture_addr2line_lib ]
#[ run torture.cpp test_impl.cpp : : : <debug-symbols>on <library>.//test_impl_lib_addr2line $(LINKSHARED_AD2L) : torture_addr2line_lib ]
[ run torture.cpp test_impl.cpp : : : <debug-symbols>on <library>.//test_impl_lib_windbg $(LINKSHARED_WIND) : torture_windbg_lib ]
[ run torture.cpp test_impl.cpp : : : <debug-symbols>on <library>.//test_impl_lib_windbg_cached $(LINKSHARED_WIND_CACHED) : torture_windbg_cached_lib ]
[ run torture.cpp test_impl.cpp : : : <debug-symbols>on <library>.//test_impl_lib_basic $(LINKSHARED_BASIC) : torture_basic_lib ]

View File

@@ -18,7 +18,7 @@
int main() {
int result = 0;
for (unsigned i = 0; i < 10000; ++i) {
for (unsigned i = 0; i < 10000000; ++i) {
result += make_some_stacktrace1()[0].source_line();
}