diff options
author | Abseil Team <absl-team@google.com> | 2023-09-26 15:27:07 -0700 |
---|---|---|
committer | Copybara-Service <copybara-worker@google.com> | 2023-09-26 15:27:47 -0700 |
commit | 6ab667fd8deba75443fdc0d5c5bbf4588431f1b4 (patch) | |
tree | 1e001cba5a64ac395b77fa561333487729683baa | |
parent | cced061b3e68da386aaadca0d87e03538ce2bc72 (diff) |
Add an internal wrapper for `abi::__cxa_demangle()`.
PiperOrigin-RevId: 568665135
Change-Id: I42ec9bc6cfe923777f7b60ea032c7b64428493c9
-rw-r--r-- | absl/base/config.h | 13 | ||||
-rw-r--r-- | absl/container/BUILD.bazel | 1 | ||||
-rw-r--r-- | absl/container/CMakeLists.txt | 1 | ||||
-rw-r--r-- | absl/container/internal/layout.h | 25 | ||||
-rw-r--r-- | absl/debugging/BUILD.bazel | 5 | ||||
-rw-r--r-- | absl/debugging/internal/demangle.cc | 24 | ||||
-rw-r--r-- | absl/debugging/internal/demangle.h | 68 | ||||
-rw-r--r-- | absl/debugging/internal/demangle_test.cc | 22 |
8 files changed, 55 insertions, 104 deletions
diff --git a/absl/base/config.h b/absl/base/config.h index 52d42f0f..a8425ba7 100644 --- a/absl/base/config.h +++ b/absl/base/config.h @@ -864,19 +864,6 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' || #define ABSL_INTERNAL_HAS_RTTI 1 #endif -// `ABSL_INTERNAL_HAS_CXA_DEMANGLE` determines whether `abi::__cxa_demangle` is -// available. -#ifdef ABSL_INTERNAL_HAS_CXA_DEMANGLE -#error ABSL_INTERNAL_HAS_CXA_DEMANGLE cannot be directly set -#elif defined(OS_ANDROID) && (defined(__i386__) || defined(__x86_64__)) -#define ABSL_INTERNAL_HAS_CXA_DEMANGLE 0 -#elif (__GNUC__ >= 4 || (__GNUC__ >= 3 && __GNUC_MINOR__ >= 4)) && \ - !defined(__mips__) -#define ABSL_INTERNAL_HAS_CXA_DEMANGLE 1 -#elif defined(__clang__) && !defined(_MSC_VER) -#define ABSL_INTERNAL_HAS_CXA_DEMANGLE 1 -#endif - // ABSL_INTERNAL_HAVE_SSE is used for compile-time detection of SSE support. // See https://gcc.gnu.org/onlinedocs/gcc/x86-Options.html for an overview of // which architectures support the various x86 instruction sets. diff --git a/absl/container/BUILD.bazel b/absl/container/BUILD.bazel index 69413ff9..7462b125 100644 --- a/absl/container/BUILD.bazel +++ b/absl/container/BUILD.bazel @@ -731,7 +731,6 @@ cc_library( deps = [ "//absl/base:config", "//absl/base:core_headers", - "//absl/debugging:demangle_internal", "//absl/meta:type_traits", "//absl/strings", "//absl/types:span", diff --git a/absl/container/CMakeLists.txt b/absl/container/CMakeLists.txt index 116ddab2..a1633514 100644 --- a/absl/container/CMakeLists.txt +++ b/absl/container/CMakeLists.txt @@ -777,7 +777,6 @@ absl_cc_library( DEPS absl::config absl::core_headers - absl::debugging_internal absl::meta absl::strings absl::span diff --git a/absl/container/internal/layout.h b/absl/container/internal/layout.h index 05de05c9..a59a2430 100644 --- a/absl/container/internal/layout.h +++ b/absl/container/internal/layout.h @@ -172,7 +172,6 @@ #include <utility> #include "absl/base/config.h" -#include "absl/debugging/internal/demangle.h" #include "absl/meta/type_traits.h" #include "absl/strings/str_cat.h" #include "absl/types/span.h" @@ -182,6 +181,14 @@ #include <sanitizer/asan_interface.h> #endif +#if defined(__GXX_RTTI) +#define ABSL_INTERNAL_HAS_CXA_DEMANGLE +#endif + +#ifdef ABSL_INTERNAL_HAS_CXA_DEMANGLE +#include <cxxabi.h> +#endif + namespace absl { ABSL_NAMESPACE_BEGIN namespace container_internal { @@ -287,9 +294,19 @@ constexpr size_t Max(size_t a, size_t b, Ts... rest) { template <class T> std::string TypeName() { std::string out; - absl::StrAppend(&out, "<", - absl::debugging_internal::DemangleString(typeid(T).name()), - ">"); + int status = 0; + char* demangled = nullptr; +#ifdef ABSL_INTERNAL_HAS_CXA_DEMANGLE + demangled = abi::__cxa_demangle(typeid(T).name(), nullptr, nullptr, &status); +#endif + if (status == 0 && demangled != nullptr) { // Demangling succeeded. + absl::StrAppend(&out, "<", demangled, ">"); + free(demangled); + } else { +#if defined(__GXX_RTTI) || defined(_CPPRTTI) + absl::StrAppend(&out, "<", typeid(T).name(), ">"); +#endif + } return out; } diff --git a/absl/debugging/BUILD.bazel b/absl/debugging/BUILD.bazel index f50c73f3..42124bfb 100644 --- a/absl/debugging/BUILD.bazel +++ b/absl/debugging/BUILD.bazel @@ -217,10 +217,7 @@ cc_library( hdrs = ["internal/demangle.h"], copts = ABSL_DEFAULT_COPTS, linkopts = ABSL_DEFAULT_LINKOPTS, - visibility = [ - "//absl/container:__pkg__", - "//absl/debugging:__pkg__", - ], + visibility = ["//visibility:private"], deps = [ "//absl/base", "//absl/base:config", diff --git a/absl/debugging/internal/demangle.cc b/absl/debugging/internal/demangle.cc index 381a2b50..f2832915 100644 --- a/absl/debugging/internal/demangle.cc +++ b/absl/debugging/internal/demangle.cc @@ -21,15 +21,7 @@ #include <cstdint> #include <cstdio> -#include <cstdlib> #include <limits> -#include <string> - -#include "absl/base/config.h" - -#if ABSL_INTERNAL_HAS_CXA_DEMANGLE -#include <cxxabi.h> -#endif namespace absl { ABSL_NAMESPACE_BEGIN @@ -1991,22 +1983,6 @@ bool Demangle(const char* mangled, char* out, size_t out_size) { state.parse_state.out_cur_idx > 0; } -std::string DemangleString(const char* mangled) { - std::string out; - int status = 0; - char* demangled = nullptr; -#if ABSL_INTERNAL_HAS_CXA_DEMANGLE - demangled = abi::__cxa_demangle(mangled, nullptr, nullptr, &status); -#endif - if (status == 0 && demangled != nullptr) { - out.append(demangled); - free(demangled); - } else { - out.append(mangled); - } - return out; -} - } // namespace debugging_internal ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/debugging/internal/demangle.h b/absl/debugging/internal/demangle.h index 146d1150..e1f15698 100644 --- a/absl/debugging/internal/demangle.h +++ b/absl/debugging/internal/demangle.h @@ -12,23 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef ABSL_DEBUGGING_INTERNAL_DEMANGLE_H_ -#define ABSL_DEBUGGING_INTERNAL_DEMANGLE_H_ - -#include <string> -#include "absl/base/config.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace debugging_internal { - -// Demangle `mangled`. On success, return true and write the -// demangled symbol name to `out`. Otherwise, return false. -// `out` is modified even if demangling is unsuccessful. +// An async-signal-safe and thread-safe demangler for Itanium C++ ABI +// (aka G++ V3 ABI). // -// This function provides an alternative to libstdc++'s abi::__cxa_demangle, -// which is not async signal safe (it uses malloc internally). It's intended to -// be used in async signal handlers to symbolize stack traces. +// The demangler is implemented to be used in async signal handlers to +// symbolize stack traces. We cannot use libstdc++'s +// abi::__cxa_demangle() in such signal handlers since it's not async +// signal safe (it uses malloc() internally). // // Note that this demangler doesn't support full demangling. More // specifically, it doesn't print types of function parameters and @@ -40,31 +30,39 @@ namespace debugging_internal { // // Example: // -// | Mangled Name | Demangle | DemangleString -// |---------------|-------------|----------------------- -// | _Z1fv | f() | f() -// | _Z1fi | f() | f(int) -// | _Z3foo3bar | foo() | foo(bar) -// | _Z1fIiEvi | f<>() | void f<int>(int) -// | _ZN1N1fE | N::f | N::f -// | _ZN3Foo3BarEv | Foo::Bar() | Foo::Bar() -// | _Zrm1XS_" | operator%() | operator%(X, X) -// | _ZN3FooC1Ev | Foo::Foo() | Foo::Foo() -// | _Z1fSs | f() | f(std::basic_string<char, -// | | | std::char_traits<char>, -// | | | std::allocator<char> >) +// | Mangled Name | The Demangler | abi::__cxa_demangle() +// |---------------|---------------|----------------------- +// | _Z1fv | f() | f() +// | _Z1fi | f() | f(int) +// | _Z3foo3bar | foo() | foo(bar) +// | _Z1fIiEvi | f<>() | void f<int>(int) +// | _ZN1N1fE | N::f | N::f +// | _ZN3Foo3BarEv | Foo::Bar() | Foo::Bar() +// | _Zrm1XS_" | operator%() | operator%(X, X) +// | _ZN3FooC1Ev | Foo::Foo() | Foo::Foo() +// | _Z1fSs | f() | f(std::basic_string<char, +// | | | std::char_traits<char>, +// | | | std::allocator<char> >) // // See the unit test for more examples. // // Note: we might want to write demanglers for ABIs other than Itanium // C++ ABI in the future. -bool Demangle(const char* mangled, char* out, size_t out_size); - -// A wrapper around `abi::__cxa_demangle()`. On success, returns the demangled -// name. On failure, returns the input mangled name. // -// This function is not async-signal-safe. -std::string DemangleString(const char* mangled); + +#ifndef ABSL_DEBUGGING_INTERNAL_DEMANGLE_H_ +#define ABSL_DEBUGGING_INTERNAL_DEMANGLE_H_ + +#include "absl/base/config.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN +namespace debugging_internal { + +// Demangle `mangled`. On success, return true and write the +// demangled symbol name to `out`. Otherwise, return false. +// `out` is modified even if demangling is unsuccessful. +bool Demangle(const char* mangled, char* out, size_t out_size); } // namespace debugging_internal ABSL_NAMESPACE_END diff --git a/absl/debugging/internal/demangle_test.cc b/absl/debugging/internal/demangle_test.cc index 26ed9cee..faec72b5 100644 --- a/absl/debugging/internal/demangle_test.cc +++ b/absl/debugging/internal/demangle_test.cc @@ -17,7 +17,6 @@ #include <cstdlib> #include <string> -#include "gmock/gmock.h" #include "gtest/gtest.h" #include "absl/base/config.h" #include "absl/debugging/internal/stack_consumption.h" @@ -29,8 +28,6 @@ ABSL_NAMESPACE_BEGIN namespace debugging_internal { namespace { -using ::testing::ContainsRegex; - // A wrapper function for Demangle() to make the unit test simple. static const char *DemangleIt(const char * const mangled) { static char demangled[4096]; @@ -240,25 +237,6 @@ TEST(DemangleRegression, DeeplyNestedArrayType) { TestOnInput(data.c_str()); } -struct Base { - virtual ~Base() = default; -}; - -struct Derived : public Base {}; - -TEST(DemangleStringTest, SupportsSymbolNameReturnedByTypeId) { - EXPECT_EQ(DemangleString(typeid(int).name()), "int"); - // We want to test that `DemangleString` can demangle the symbol names - // returned by `typeid`, but without hard-coding the actual demangled values - // (because they are platform-specific). - EXPECT_THAT( - DemangleString(typeid(Base).name()), - ContainsRegex("absl.*debugging_internal.*anonymous namespace.*::Base")); - EXPECT_THAT(DemangleString(typeid(Derived).name()), - ContainsRegex( - "absl.*debugging_internal.*anonymous namespace.*::Derived")); -} - } // namespace } // namespace debugging_internal ABSL_NAMESPACE_END |