summaryrefslogtreecommitdiff
path: root/libcxxabi/src
diff options
context:
space:
mode:
authorLouis Dionne <ldionne.2@gmail.com>2022-05-09 16:41:38 -0400
committerLouis Dionne <ldionne.2@gmail.com>2022-05-12 13:17:15 -0400
commit6089fd6c0b1cca4fd16583b25954c132a9b58ebd (patch)
tree4841d4f65547efc2229630c1b5f8c83a66199e55 /libcxxabi/src
parent47be07074a73bd469b16af440923e3cf3b6b3f10 (diff)
downloadllvm-6089fd6c0b1cca4fd16583b25954c132a9b58ebd.tar.gz
[libc++abi] Refactor exception type demangling into a separate function
As a fly-by fix, also let `__cxa_demangle` allocate its buffer alone, since we are not allowed to pass a non-malloc'd buffer to it. Differential Revision: https://reviews.llvm.org/D125268
Diffstat (limited to 'libcxxabi/src')
-rw-r--r--libcxxabi/src/cxa_default_handlers.cpp29
1 files changed, 16 insertions, 13 deletions
diff --git a/libcxxabi/src/cxa_default_handlers.cpp b/libcxxabi/src/cxa_default_handlers.cpp
index 2c42f652db55..800204c1dd86 100644
--- a/libcxxabi/src/cxa_default_handlers.cpp
+++ b/libcxxabi/src/cxa_default_handlers.cpp
@@ -10,6 +10,7 @@
//===----------------------------------------------------------------------===//
#include <exception>
+#include <memory>
#include <stdlib.h>
#include "abort_message.h"
#include "cxxabi.h"
@@ -22,6 +23,18 @@
static constinit const char* cause = "uncaught";
+#ifndef _LIBCXXABI_NO_EXCEPTIONS
+// Demangle the given string, or return the string as-is in case of an error.
+static std::unique_ptr<char const, void (*)(char const*)> demangle(char const* str)
+{
+#if !defined(LIBCXXABI_NON_DEMANGLING_TERMINATE)
+ if (const char* result = __cxxabiv1::__cxa_demangle(str, nullptr, nullptr, nullptr))
+ return {result, [](char const* p) { std::free(const_cast<char*>(p)); }};
+#endif
+ return {str, [](char const*) { /* nothing to free */ }};
+}
+#endif
+
__attribute__((noreturn))
static void demangling_terminate_handler()
{
@@ -45,17 +58,7 @@ static void demangling_terminate_handler()
exception_header + 1;
const __shim_type_info* thrown_type =
static_cast<const __shim_type_info*>(exception_header->exceptionType);
-#if !defined(LIBCXXABI_NON_DEMANGLING_TERMINATE)
- // Try to get demangled name of thrown_type
- int status;
- char buf[1024];
- size_t len = sizeof(buf);
- const char* name = __cxa_demangle(thrown_type->name(), buf, &len, &status);
- if (status != 0)
- name = thrown_type->name();
-#else
- const char* name = thrown_type->name();
-#endif
+ auto name = demangle(thrown_type->name());
// If the uncaught exception can be caught with std::exception&
const __shim_type_info* catch_type =
static_cast<const __shim_type_info*>(&typeid(std::exception));
@@ -64,12 +67,12 @@ static void demangling_terminate_handler()
// Include the what() message from the exception
const std::exception* e = static_cast<const std::exception*>(thrown_object);
abort_message("terminating due to %s exception of type %s: %s",
- cause, name, e->what());
+ cause, name.get(), e->what());
}
else
// Else just note that we're terminating due to an exception
abort_message("terminating due to %s exception of type %s",
- cause, name);
+ cause, name.get());
}
else
// Else we're terminating due to a foreign exception