@@ -160,29 +160,13 @@ 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>
164166#include < mutex>
165167#include < unordered_map>
166168
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-
169+ #include < unistd.h>
186170#endif
187171
188172namespace {
@@ -297,6 +281,32 @@ void* __cxa_allocate_exception(size_t thrown_size) throw() {
297281extern " C" BOOST_SYMBOL_EXPORT
298282void __cxa_decrement_exception_refcount (void *thrown_object) throw() {
299283 BOOST_ASSERT (is_libcpp_runtime ());
284+
285+ #if !defined(BOOST_STACKTRACE_LIBCXX_RUNTIME_MAY_CAUSE_MEMORY_LEAK) && defined(BOOST_HAS_THREADS)
286+ static const char * leaks_are_fine = std::getenv (" BOOST_STACKTRACE_LIBCXX_RUNTIME_MAY_CAUSE_MEMORY_LEAK" );
287+ if (!leaks_are_fine || leaks_are_fine[0 ] != ' 1' ) {
288+ const char * const warning =
289+ " \n\n "
290+ " =======================================================================================\n "
291+ " \n "
292+ " On this platform, memory leaks may occur if capturing stacktrace from exceptions is\n "
293+ " enabled and exceptions are thrown concurrently by libc++ runtime (libc++abi).\n "
294+ " \n "
295+ " A proper workaround is to use libstdc++ runtime (libgcc_s) instead.\n "
296+ " \n "
297+ " Alternatively, if you are willing to accept potential MEMORY LEAKS, set the environment\n "
298+ " variable `BOOST_STACKTRACE_LIBCXX_RUNTIME_MAY_CAUSE_MEMORY_LEAK=1` to proceed. You can\n "
299+ " also define the `BOOST_STACKTRACE_LIBCXX_RUNTIME_MAY_CAUSE_MEMORY_LEAK` macro when\n "
300+ " building the `boost_stacktrace_from_exception` library to disable this warning and to\n "
301+ " get the MEMORY LEAKS silently on libc++ runtime.\n "
302+ " \n "
303+ " =======================================================================================\n "
304+ ;
305+ write (STDERR_FILENO, warning, strlen (warning));
306+ std::abort ();
307+ }
308+ #endif
309+
300310 if (!thrown_object) {
301311 return ;
302312 }
0 commit comments