diff options
author | Christopher Ferris <cferris@google.com> | 2023-02-01 21:27:26 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2023-02-01 21:27:26 +0000 |
commit | 1fb57bd8b7bc3e7ea9e51d1af14d0c2ea48b6cfd (patch) | |
tree | 3d739922811bd9e6b67b8e4ab41b763ecfe71287 | |
parent | 69a0dc7c420f4f304ff289fa7a56f3bdbb0cb42f (diff) | |
parent | 2ec58fe4b40aaa58252c796d39dff4e5b0b424d7 (diff) | |
download | unwinding-1fb57bd8b7bc3e7ea9e51d1af14d0c2ea48b6cfd.tar.gz |
Merge "Revert^2 "Add rust demangling."" am: 63369c7750 am: 5dd10e676e am: 2ec58fe4b4
Original change: https://android-review.googlesource.com/c/platform/system/unwinding/+/2403073
Change-Id: If32f0743cec94af1566adbb6d002e3d498fa847a
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r-- | libunwindstack/Android.bp | 6 | ||||
-rw-r--r-- | libunwindstack/AndroidUnwinder.cpp | 10 | ||||
-rw-r--r-- | libunwindstack/Demangle.cpp | 51 | ||||
-rw-r--r-- | libunwindstack/Unwinder.cpp | 15 | ||||
-rw-r--r-- | libunwindstack/include/unwindstack/Demangle.h | 25 | ||||
-rw-r--r-- | libunwindstack/tests/DemangleTest.cpp | 46 |
6 files changed, 133 insertions, 20 deletions
diff --git a/libunwindstack/Android.bp b/libunwindstack/Android.bp index 84619ee..7a63a22 100644 --- a/libunwindstack/Android.bp +++ b/libunwindstack/Android.bp @@ -54,6 +54,7 @@ cc_defaults { libunwindstack_common_src_files = [ "AndroidUnwinder.cpp", "ArmExidx.cpp", + "Demangle.cpp", "DexFiles.cpp", "DwarfCfa.cpp", "DwarfEhFrameWithHdr.cpp", @@ -123,6 +124,10 @@ cc_defaults { "libprocinfo", ], + whole_static_libs: [ + "librustc_demangle_static", + ], + shared_libs: [ "libbase", "liblog", @@ -273,6 +278,7 @@ cc_defaults { "tests/AndroidUnwinderTest.cpp", "tests/ArmExidxDecodeTest.cpp", "tests/ArmExidxExtractTest.cpp", + "tests/DemangleTest.cpp", "tests/DexFileTest.cpp", "tests/DexFilesTest.cpp", "tests/DwarfCfaLogTest.cpp", diff --git a/libunwindstack/AndroidUnwinder.cpp b/libunwindstack/AndroidUnwinder.cpp index d228aea..3b25604 100644 --- a/libunwindstack/AndroidUnwinder.cpp +++ b/libunwindstack/AndroidUnwinder.cpp @@ -28,6 +28,7 @@ #include <unwindstack/AndroidUnwinder.h> #include <unwindstack/Arch.h> +#include <unwindstack/Demangle.h> #include <unwindstack/DexFiles.h> #include <unwindstack/Error.h> #include <unwindstack/JitDebug.h> @@ -45,18 +46,11 @@ static constexpr int kThreadUnwindSignal = BIONIC_SIGNAL_BACKTRACE; static int kThreadUnwindSignal = SIGRTMIN; #endif -// Use the demangler from libc++. -extern "C" char* __cxa_demangle(const char*, char*, size_t*, int* status); - namespace unwindstack { void AndroidUnwinderData::DemangleFunctionNames() { for (auto& frame : frames) { - char* demangled_name = __cxa_demangle(frame.function_name.c_str(), nullptr, nullptr, nullptr); - if (demangled_name != nullptr) { - frame.function_name = demangled_name; - free(demangled_name); - } + frame.function_name = DemangleNameIfNeeded(frame.function_name); } } diff --git a/libunwindstack/Demangle.cpp b/libunwindstack/Demangle.cpp new file mode 100644 index 0000000..8d0bfd6 --- /dev/null +++ b/libunwindstack/Demangle.cpp @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <cxxabi.h> +#include <stdlib.h> + +#include <string> + +#include <rustc_demangle.h> + +#include <unwindstack/Demangle.h> + +namespace unwindstack { + +std::string DemangleNameIfNeeded(const std::string& name) { + if (name.length() < 2 || name[0] != '_') { + return name; + } + + char* demangled_str = nullptr; + if (name[1] == 'Z') { + // Try to demangle C++ name. + demangled_str = abi::__cxa_demangle(name.c_str(), nullptr, nullptr, nullptr); + } else if (name[1] == 'R') { + // Try to demangle rust name. + demangled_str = rustc_demangle(name.c_str(), nullptr, nullptr, nullptr); + } + + if (demangled_str == nullptr) { + return name; + } + + std::string demangled_name(demangled_str); + free(demangled_str); + return demangled_name; +} + +} // namespace unwindstack diff --git a/libunwindstack/Unwinder.cpp b/libunwindstack/Unwinder.cpp index facff86..7304000 100644 --- a/libunwindstack/Unwinder.cpp +++ b/libunwindstack/Unwinder.cpp @@ -25,10 +25,12 @@ #include <algorithm> #include <memory> +#include <string> #include <android-base/file.h> #include <android-base/stringprintf.h> +#include <unwindstack/Demangle.h> #include <unwindstack/DexFiles.h> #include <unwindstack/Elf.h> #include <unwindstack/JitDebug.h> @@ -39,9 +41,6 @@ #include "Check.h" -// Use the demangler from libc++. -extern "C" char* __cxa_demangle(const char*, char*, size_t*, int* status); - namespace unwindstack { // Inject extra 'virtual' frame that represents the dex pc data. @@ -326,15 +325,7 @@ std::string Unwinder::FormatFrame(ArchEnum arch, const FrameData& frame, bool di } if (!frame.function_name.empty()) { - char* demangled_name = __cxa_demangle(frame.function_name.c_str(), nullptr, nullptr, nullptr); - if (demangled_name == nullptr) { - data += " ("; - data += frame.function_name; - } else { - data += " ("; - data += demangled_name; - free(demangled_name); - } + data += " (" + DemangleNameIfNeeded(frame.function_name); if (frame.function_offset != 0) { data += android::base::StringPrintf("+%" PRId64, frame.function_offset); } diff --git a/libunwindstack/include/unwindstack/Demangle.h b/libunwindstack/include/unwindstack/Demangle.h new file mode 100644 index 0000000..8ea51bc --- /dev/null +++ b/libunwindstack/include/unwindstack/Demangle.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include <string> + +namespace unwindstack { + +std::string DemangleNameIfNeeded(const std::string& name); + +} // namespace unwindstack diff --git a/libunwindstack/tests/DemangleTest.cpp b/libunwindstack/tests/DemangleTest.cpp new file mode 100644 index 0000000..3047b6e --- /dev/null +++ b/libunwindstack/tests/DemangleTest.cpp @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <string> + +#include <gtest/gtest.h> + +#include <unwindstack/Demangle.h> + +namespace unwindstack { + +TEST(DemangleTest, none) { + EXPECT_EQ("", DemangleNameIfNeeded("")); + EXPECT_EQ("a", DemangleNameIfNeeded("a")); + EXPECT_EQ("_", DemangleNameIfNeeded("_")); + EXPECT_EQ("ab", DemangleNameIfNeeded("ab")); + EXPECT_EQ("abc", DemangleNameIfNeeded("abc")); + EXPECT_EQ("_R", DemangleNameIfNeeded("_R")); + EXPECT_EQ("_Z", DemangleNameIfNeeded("_Z")); +} + +TEST(DemangleTest, cxx_names) { + EXPECT_EQ("fake(bool)", DemangleNameIfNeeded("_Z4fakeb")); + EXPECT_EQ("demangle(int)", DemangleNameIfNeeded("_Z8demanglei")); +} + +TEST(DemangleTest, rust_names) { + EXPECT_EQ("std::rt::lang_start_internal", + DemangleNameIfNeeded("_RNvNtCs2WRBrrl1bb1_3std2rt19lang_start_internal")); + EXPECT_EQ("profcollectd::main", DemangleNameIfNeeded("_RNvCs4VPobU5SDH_12profcollectd4main")); +} + +} // namespace unwindstack |