diff options
author | Yabin Cui <yabinc@google.com> | 2021-08-19 10:51:00 -0700 |
---|---|---|
committer | Yabin Cui <yabinc@google.com> | 2021-08-19 12:39:05 -0700 |
commit | fef951409c62edae2eba555d382348c93b433721 (patch) | |
tree | a39c26aebab4ccdcdb59d64d1a5762301aeedd26 | |
parent | 02af000e94f99f9c5fb46794b7268878cbc77fbd (diff) | |
download | extras-fef951409c62edae2eba555d382348c93b433721.tar.gz |
simpleperf: use proguard mapping file for compiled java symbols.
Bug: 195892224
Test: run simpleperf_unit_test
Change-Id: Ia74654d5703eb23dc4ae6e6faeb1cbc53615636e
-rw-r--r-- | simpleperf/dso.cpp | 2 | ||||
-rw-r--r-- | simpleperf/dso.h | 2 | ||||
-rw-r--r-- | simpleperf/dso_test.cpp | 8 | ||||
-rw-r--r-- | simpleperf/report_utils.cpp | 29 | ||||
-rw-r--r-- | simpleperf/report_utils_test.cpp | 32 |
5 files changed, 59 insertions, 14 deletions
diff --git a/simpleperf/dso.cpp b/simpleperf/dso.cpp index db70a879..815e8cb0 100644 --- a/simpleperf/dso.cpp +++ b/simpleperf/dso.cpp @@ -229,7 +229,7 @@ void Symbol::SetDemangledName(std::string_view name) const { } } -std::string_view Symbol::FunctionNameForJITSymbol() const { +std::string_view Symbol::FunctionName() const { // Name with signature is like "void ctep.v(cteo, ctgc, ctbn)". std::string_view name = DemangledName(); auto brace_pos = name.find('('); diff --git a/simpleperf/dso.h b/simpleperf/dso.h index 00a08040..866aadfd 100644 --- a/simpleperf/dso.h +++ b/simpleperf/dso.h @@ -67,7 +67,7 @@ struct Symbol { const char* DemangledName() const; void SetDemangledName(std::string_view name) const; // Return function name without signature. - std::string_view FunctionNameForJITSymbol() const; + std::string_view FunctionName() const; bool HasDumpId() const { return dump_id_ != UINT_MAX; } diff --git a/simpleperf/dso_test.cpp b/simpleperf/dso_test.cpp index 9d1cc3fd..1338c1c0 100644 --- a/simpleperf/dso_test.cpp +++ b/simpleperf/dso_test.cpp @@ -302,9 +302,11 @@ TEST(dso, symbol_map_file) { ASSERT_EQ(0x12345678, dso->IpToVaddrInFile(0x12345678, 0xe9201000, 0xa5000)); } -TEST(dso, FunctionNameForJITSymbol) { +TEST(dso, FunctionName) { Symbol symbol = Symbol("void ctep.v(cteo, ctgc, ctbn)", 0x0, 0x1); - ASSERT_EQ(symbol.FunctionNameForJITSymbol(), "ctep.v"); + ASSERT_EQ(symbol.FunctionName(), "ctep.v"); + symbol = Symbol("ctep.v(cteo, ctgc, ctbn)", 0x0, 0x1); + ASSERT_EQ(symbol.FunctionName(), "ctep.v"); symbol = Symbol("ctep.v", 0x0, 0x1); - ASSERT_EQ(symbol.FunctionNameForJITSymbol(), "ctep.v"); + ASSERT_EQ(symbol.FunctionName(), "ctep.v"); } diff --git a/simpleperf/report_utils.cpp b/simpleperf/report_utils.cpp index ccaaa69b..0cc1191a 100644 --- a/simpleperf/report_utils.cpp +++ b/simpleperf/report_utils.cpp @@ -176,7 +176,7 @@ void CallChainReportBuilder::ConvertJITFrame(std::vector<CallChainReportEntry>& // This is a JIT java method, merge it with the interpreted java method having the same // name if possible. Otherwise, merge it with other JIT java methods having the same name // by assigning a common dso_name. - if (auto it = java_method_map_.find(std::string(entry.symbol->FunctionNameForJITSymbol())); + if (auto it = java_method_map_.find(std::string(entry.symbol->FunctionName())); it != java_method_map_.end()) { entry.dso = it->second.dso; entry.symbol = it->second.symbol; @@ -215,18 +215,29 @@ void CallChainReportBuilder::CollectJavaMethods() { } } +static bool IsJavaEntry(const CallChainReportEntry& entry) { + static const char* COMPILED_JAVA_FILE_SUFFIXES[] = {".odex", ".oat", ".dex"}; + if (entry.execution_type == CallChainExecutionType::JIT_JVM_METHOD || + entry.execution_type == CallChainExecutionType::INTERPRETED_JVM_METHOD) { + return true; + } + if (entry.execution_type == CallChainExecutionType::NATIVE_METHOD) { + const std::string& path = entry.dso->Path(); + for (const char* suffix : COMPILED_JAVA_FILE_SUFFIXES) { + if (android::base::EndsWith(path, suffix)) { + return true; + } + } + } + return false; +} + void CallChainReportBuilder::DeObfuscateJavaMethods(std::vector<CallChainReportEntry>& callchain) { for (auto& entry : callchain) { - if (entry.execution_type != CallChainExecutionType::JIT_JVM_METHOD && - entry.execution_type != CallChainExecutionType::INTERPRETED_JVM_METHOD) { + if (!IsJavaEntry(entry)) { continue; } - std::string_view name; - if (entry.execution_type == CallChainExecutionType::JIT_JVM_METHOD) { - name = entry.symbol->FunctionNameForJITSymbol(); - } else { - name = entry.symbol->DemangledName(); - } + std::string_view name = entry.symbol->FunctionName(); if (auto split_pos = name.rfind('.'); split_pos != name.npos) { std::string obfuscated_classname(name.substr(0, split_pos)); if (auto it = proguard_class_map_.find(obfuscated_classname); diff --git a/simpleperf/report_utils_test.cpp b/simpleperf/report_utils_test.cpp index 8def39ee..1745a854 100644 --- a/simpleperf/report_utils_test.cpp +++ b/simpleperf/report_utils_test.cpp @@ -333,6 +333,38 @@ TEST_F(CallChainReportBuilderTest, add_proguard_mapping_file_for_jit_method_with ASSERT_EQ(entries[0].execution_type, CallChainExecutionType::JIT_JVM_METHOD); } +TEST_F(CallChainReportBuilderTest, + add_proguard_mapping_file_for_compiled_java_method_with_signature) { + TemporaryFile tmpfile; + close(tmpfile.release()); + ASSERT_TRUE(android::base::WriteStringToFile( + "android.support.v4.app.RemoteActionCompatParcelizer -> ctep:\n" + " 13:13:androidx.core.app.RemoteActionCompat read(androidx.versionedparcelable.Versioned" + "Parcel) -> v\n", + tmpfile.path)); + + for (const char* suffix : {".odex", ".oat", ".dex"}) { + std::string compiled_java_path = "compiled_java" + std::string(suffix); + SetSymbols(compiled_java_path, DSO_ELF_FILE, + {Symbol("void ctep.v(cteo, ctgc, ctbn)", 0x0, 0x100)}); + thread_tree.AddThreadMap(1, 1, 0x4000, 0x1000, 0x0, compiled_java_path); + std::vector<uint64_t> fake_ips = { + 0x4000, // 4000, // void ctep.v(cteo, ctgc, ctbn) + }; + + CallChainReportBuilder builder(thread_tree); + builder.AddProguardMappingFile(tmpfile.path); + std::vector<CallChainReportEntry> entries = builder.Build(thread, fake_ips, 0); + ASSERT_EQ(entries.size(), 1); + ASSERT_EQ(entries[0].ip, 0x4000); + ASSERT_STREQ(entries[0].symbol->DemangledName(), + "android.support.v4.app.RemoteActionCompatParcelizer.read"); + ASSERT_EQ(entries[0].dso->Path(), compiled_java_path); + ASSERT_EQ(entries[0].vaddr_in_file, 0x0); + ASSERT_EQ(entries[0].execution_type, CallChainExecutionType::NATIVE_METHOD); + } +} + TEST_F(CallChainReportBuilderTest, convert_jit_frame_for_jit_method_with_signature) { std::vector<uint64_t> fake_ips = { 0x2200, // 2200, // ctep.v |