feat(demangle): use cxx abi demangler (#1023)

This commit is contained in:
Sergiu Deitsch 2024-01-03 19:24:35 +01:00 committed by GitHub
parent bdd14b6ab1
commit 51e7a439dc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 56 additions and 9 deletions

View File

@ -170,6 +170,12 @@ int main(void)
}
" HAVE___SYNC_VAL_COMPARE_AND_SWAP)
if (WITH_FUZZING STREQUAL none)
# Disable compiler demangler if fuzzing is active; we only want to use the
# glog demangler then.
check_cxx_symbol_exists (abi::__cxa_demangle cxxabi.h HAVE___CXA_DEMANGLE)
endif (WITH_FUZZING STREQUAL none)
if (WITH_TLS)
set (GLOG_THREAD_LOCAL_STORAGE 1)
endif (WITH_TLS)
@ -576,6 +582,13 @@ if (BUILD_TESTING)
target_link_libraries (demangle_unittest PRIVATE glog_test)
add_test (NAME demangle COMMAND demangle_unittest)
if (HAVE___CXA_DEMANGLE)
# Demangle tests use a different (reduced) representation of symbols
set_tests_properties (demangle PROPERTIES DISABLED ON)
endif (HAVE___CXA_DEMANGLE)
if (HAVE_STACKTRACE)
add_executable (stacktrace_unittest
src/stacktrace_unittest.cc
@ -598,7 +611,6 @@ if (BUILD_TESTING)
target_link_libraries (signalhandler_unittest PRIVATE glog_test)
endif (HAVE_STACKTRACE AND HAVE_SYMBOLIZE)
add_test (NAME demangle COMMAND demangle_unittest)
add_test (NAME logging COMMAND logging_unittest)
set_tests_properties (logging PROPERTIES TIMEOUT 30)

View File

@ -118,4 +118,7 @@
/* Define if thread-local storage is enabled. */
#cmakedefine GLOG_THREAD_LOCAL_STORAGE
/* define if abi::__cxa_demangle is available in cxxabi.h */
#cmakedefine HAVE___CXA_DEMANGLE
#endif // GLOG_CONFIG_H

View File

@ -1,4 +1,4 @@
// Copyright (c) 2006, Google Inc.
// Copyright (c) 2024, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@ -36,18 +36,24 @@
#include "demangle.h"
#include <algorithm>
#include <cstddef>
#include <cstdlib>
#include <limits>
#include "utilities.h"
#if defined(HAVE___CXA_DEMANGLE)
# include <cxxabi.h>
#endif
#if defined(GLOG_OS_WINDOWS)
# include <dbghelp.h>
#endif
namespace google {
#if !defined(GLOG_OS_WINDOWS)
#if !defined(GLOG_OS_WINDOWS) && !defined(HAVE___CXA_DEMANGLE)
namespace {
struct AbbrevPair {
const char* const abbrev;
@ -1334,6 +1340,18 @@ bool Demangle(const char* mangled, char* out, size_t out_size) {
(void)out_size;
return false;
# endif
#elif defined(HAVE___CXA_DEMANGLE)
int status = -1;
std::size_t n = 0;
std::unique_ptr<char, decltype(&std::free)> unmangled{
abi::__cxa_demangle(mangled, nullptr, &n, &status), &std::free};
if (!unmangled) {
return false;
}
std::copy_n(unmangled.get(), std::min(n, out_size), out);
return status == 0;
#else
State state;
InitState(&state, mangled, out, out_size);

View File

@ -1,4 +1,4 @@
// Copyright (c) 2006, Google Inc.
// Copyright (c) 2024, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@ -146,7 +146,11 @@ void ATTRIBUTE_NOINLINE Foo::func(int x) {
TEST(Symbolize, SymbolizeWithDemangling) {
Foo::func(100);
# if !defined(_MSC_VER) || !defined(NDEBUG)
# if defined(HAVE___CXA_DEMANGLE)
EXPECT_STREQ("Foo::func(int)", TrySymbolize((void*)(&Foo::func)));
# else
EXPECT_STREQ("Foo::func()", TrySymbolize((void*)(&Foo::func)));
# endif
# endif
}
# endif
@ -282,12 +286,14 @@ static const char* SymbolizeStackConsumption(void* pc, int* stack_consumed) {
return g_symbolize_result;
}
# ifdef __ppc64__
# if !defined(HAVE___CXA_DEMANGLE)
# ifdef __ppc64__
// Symbolize stack consumption should be within 4kB.
const int kStackConsumptionUpperLimit = 4096;
# else
constexpr int kStackConsumptionUpperLimit = 4096;
# else
// Symbolize stack consumption should be within 2kB.
const int kStackConsumptionUpperLimit = 2048;
constexpr int kStackConsumptionUpperLimit = 2048;
# endif
# endif
TEST(Symbolize, SymbolizeStackConsumption) {
@ -298,7 +304,9 @@ TEST(Symbolize, SymbolizeStackConsumption) {
&stack_consumed);
EXPECT_STREQ("nonstatic_func", symbol);
EXPECT_GT(stack_consumed, 0);
# if !defined(HAVE___CXA_DEMANGLE)
EXPECT_LT(stack_consumed, kStackConsumptionUpperLimit);
# endif
// The name of an internal linkage symbol is not specified; allow either a
// mangled or an unmangled name here.
@ -308,10 +316,12 @@ TEST(Symbolize, SymbolizeStackConsumption) {
EXPECT_TRUE(strcmp("static_func", symbol) == 0 ||
strcmp("static_func()", symbol) == 0);
EXPECT_GT(stack_consumed, 0);
# if !defined(HAVE___CXA_DEMANGLE)
EXPECT_LT(stack_consumed, kStackConsumptionUpperLimit);
# endif
}
# ifdef TEST_WITH_MODERN_GCC
# if defined(TEST_WITH_MODERN_GCC) && !defined(HAVE___CXA_DEMANGLE)
TEST(Symbolize, SymbolizeWithDemanglingStackConsumption) {
Foo::func(100);
int stack_consumed;
@ -320,7 +330,11 @@ TEST(Symbolize, SymbolizeWithDemanglingStackConsumption) {
symbol = SymbolizeStackConsumption(reinterpret_cast<void*>(&Foo::func),
&stack_consumed);
# if defined(HAVE___CXA_DEMANGLE)
EXPECT_STREQ("Foo::func(int)", symbol);
# else
EXPECT_STREQ("Foo::func()", symbol);
# endif
EXPECT_GT(stack_consumed, 0);
EXPECT_LT(stack_consumed, kStackConsumptionUpperLimit);
}