@@ -160,29 +160,14 @@ BOOST_SYMBOL_EXPORT void assert_no_pending_traces() noexcept {
160160#include < exception>
161161#include < dlfcn.h>
162162
163+
163164#if !BOOST_STACKTRACE_ALWAYS_STORE_IN_PADDING
165+ #include < cstdlib>
166+ #include < cstring>
164167#include < mutex>
165168#include < unordered_map>
166169
167- #ifndef BOOST_STACKTRACE_LIBCXX_RUNTIME_MAY_CAUSE_MEMORY_LEAK
168-
169- #ifdef BOOST_HAS_THREADS
170-
171- #error On this platform memory leaks are possible if capturing stacktrace from \
172- exceptions is enabled and exceptions are thrown concurrently \
173- and libc++ runtime is used. \
174- \
175- Define `BOOST_STACKTRACE_LIBCXX_RUNTIME_MAY_CAUSE_MEMORY_LEAK` to \
176- suppress this error if the library would not be used with libc++ \
177- runtime (for example, it would be only used with GCC runtime). \
178- \
179- Otherwise, disable the boost_stacktrace_from_exception library build \
180- (for example by `./b2 boost.stacktrace.from_exception=off` option).
181-
182- #endif
183-
184- #endif
185-
170+ #include < unistd.h>
186171#endif
187172
188173namespace {
@@ -297,6 +282,32 @@ void* __cxa_allocate_exception(size_t thrown_size) throw() {
297282extern " C" BOOST_SYMBOL_EXPORT
298283void __cxa_decrement_exception_refcount (void *thrown_object) throw() {
299284 BOOST_ASSERT (is_libcpp_runtime ());
285+
286+ #if !defined(BOOST_STACKTRACE_LIBCXX_RUNTIME_MAY_CAUSE_MEMORY_LEAK) && defined(BOOST_HAS_THREADS)
287+ static const char * leaks_are_fine = std::getenv (" BOOST_STACKTRACE_LIBCXX_RUNTIME_MAY_CAUSE_MEMORY_LEAK" );
288+ if (!leaks_are_fine || leaks_are_fine[0 ] != ' 1' ) {
289+ const char * const warning =
290+ " \n\n "
291+ " =======================================================================================\n "
292+ " \n "
293+ " On this platform, memory leaks may occur if capturing stacktrace from exceptions is\n "
294+ " enabled and exceptions are thrown concurrently by libc++ runtime (libc++abi).\n "
295+ " \n "
296+ " A proper workaround is to use libstdc++ runtime (libgcc_s) instead.\n "
297+ " \n "
298+ " Alternatively, if you are willing to accept potential MEMORY LEAKS, set the environment\n "
299+ " variable `BOOST_STACKTRACE_LIBCXX_RUNTIME_MAY_CAUSE_MEMORY_LEAK=1` to proceed. You can\n "
300+ " also define the `BOOST_STACKTRACE_LIBCXX_RUNTIME_MAY_CAUSE_MEMORY_LEAK` macro when\n "
301+ " building the `boost_stacktrace_from_exception` library to disable this warning and to\n "
302+ " get the MEMORY LEAKS silently on libc++ runtime.\n "
303+ " \n "
304+ " =======================================================================================\n "
305+ ;
306+ write (STDERR_FILENO, warning, std::strlen (warning));
307+ std::abort ();
308+ }
309+ #endif
310+
300311 if (!thrown_object) {
301312 return ;
302313 }
0 commit comments