Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions folly/Demangle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,19 @@ size_t demangle(const char* name, char* out, size_t outSize) {
}
}

// fallback to cxxabi if available
if (cxxabi_demangle) {
int status;
size_t len = outSize;
// Use the provided buffer instead of allocating
char* demangled = cxxabi_demangle(name, out, &len, &status);
if (status == 0 && demangled == out) {
// Successfully demangled into the provided buffer
return strlen(out);
}
// If demangling failed or allocated (shouldn't happen), fall through
}

// fallback - just return original
return folly::strlcpy(out, name, outSize);
}
Expand Down
9 changes: 4 additions & 5 deletions folly/Demangle.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,10 @@ inline fbstring demangle(const std::type_info& type) {
*
* This function does not allocate memory and is async-signal-safe.
*
* Note that the underlying function for the fbstring-returning demangle is
* somewhat standard (abi::__cxa_demangle, which uses malloc), the underlying
* function for this version is less so (cplus_demangle_v3_callback from
* libiberty), so it is possible for the fbstring version to work, while this
* version returns the original, mangled name.
* This function tries libiberty first (cplus_demangle_v3_callback), then falls
* back to cxxabi (abi::__cxa_demangle with the provided buffer) if libiberty
* is not available. If neither is available, it returns the original mangled
* name.
*/
size_t demangle(const char* name, char* out, size_t outSize);
inline size_t demangle(const std::type_info& type, char* buf, size_t bufSize) {
Expand Down
11 changes: 8 additions & 3 deletions folly/test/DemangleTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,10 @@ TEST_F(DemangleTest, demangle_return_string) {
TEST_F(DemangleTest, demangle_to_buffer) {
using type = folly_test::ThisIsAVeryLongStructureName;
auto const raw = typeid(type).name();
auto const expected =
demangle_build_has_liberty() ? pretty_name<type>() : raw;
// Buffer-based demangle now falls back to cxxabi if liberty is not available
auto const expected = (demangle_build_has_liberty() || demangle_build_has_cxxabi())
? pretty_name<type>()
: raw;

{
std::vector<char> buf;
Expand All @@ -69,7 +71,10 @@ TEST_F(DemangleTest, demangle_long_symbol) {

EXPECT_EQ(std::string(choice), demangle(raw).toStdString());

auto const expected = demangle_build_has_liberty() ? choice : raw;
// Buffer-based demangle now falls back to cxxabi if liberty is not available
auto const expected =
(demangle_build_has_liberty() || demangle_build_has_cxxabi()) ? choice
: raw;
constexpr size_t size = 15;
std::vector<char> buf;
buf.resize(1 + size);
Expand Down