MCPcopy Create free account
hub / github.com/boostorg/stacktrace / __cxa_decrement_exception_refcount

Function __cxa_decrement_exception_refcount

src/from_exception.cpp:282–332  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

280// __cxa_decrement_exception_refcount has an inlined call to
281// __cxa_free_exception. Overriding libc++ specific function
282extern "C" BOOST_SYMBOL_EXPORT
283void __cxa_decrement_exception_refcount(void *thrown_object) throw() {
284 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
311 if (!thrown_object) {
312 return;
313 }
314
315 static const auto orig_decrement_refcount = []() {
316 void* const ptr = ::dlsym(RTLD_NEXT, "__cxa_decrement_exception_refcount");
317 BOOST_ASSERT_MSG(ptr, "Failed to find '__cxa_decrement_exception_refcount'");
318 return reinterpret_cast<void(*)(void*)>(ptr);
319 }();
320
321 const auto* exception_header = exception_begin_llvm_ptr(thrown_object);
322
323 // The following line has a race and could give false positives and false
324 // negatives. In first case we remove the trace earlier, in the second case
325 // we get a memory leak.
326 if (exception_header->referenceCount == 1) {
327 const std::lock_guard<std::mutex> guard{g_mapping_mutex};
328 g_exception_to_dump_mapping.erase(thrown_object);
329 }
330
331 orig_decrement_refcount(thrown_object);
332}
333
334#endif
335

Callers

nothing calls this directly

Calls 2

is_libcpp_runtimeFunction · 0.85
exception_begin_llvm_ptrFunction · 0.85

Tested by

no test coverage detected