summaryrefslogtreecommitdiff
path: root/simpleperf
diff options
context:
space:
mode:
authorYabin Cui <yabinc@google.com>2021-04-13 14:31:58 -0700
committerYabin Cui <yabinc@google.com>2021-04-14 11:48:55 -0700
commitaf767bff14b0638becacccb77f08ac60d4c03052 (patch)
treebc5f19e199680ba350a6dd0ec6dd0156615eeb3f /simpleperf
parent40eef9e4aed37e4bc097b8dbe806882379e5586d (diff)
downloadextras-af767bff14b0638becacccb77f08ac60d4c03052.tar.gz
simpleperf: add proguard mapping file option to report interfaces.
Also use PreprocessOptions() in cmd_report_sample.cpp. Bug: 169454086 Test: run simpleperf_unit_test Change-Id: I9ce48ec418991205228311088a89f24f639a67d5
Diffstat (limited to 'simpleperf')
-rw-r--r--simpleperf/cmd_report_sample.cpp80
-rw-r--r--simpleperf/cmd_report_sample_test.cpp18
-rw-r--r--simpleperf/report_lib_interface.cpp8
-rw-r--r--simpleperf/testdata/perf_need_proguard_mapping.databin0 -> 25406 bytes
-rw-r--r--simpleperf/testdata/proguard_mapping.txt36
5 files changed, 103 insertions, 39 deletions
diff --git a/simpleperf/cmd_report_sample.cpp b/simpleperf/cmd_report_sample.cpp
index 186b120f..b547d3c9 100644
--- a/simpleperf/cmd_report_sample.cpp
+++ b/simpleperf/cmd_report_sample.cpp
@@ -123,8 +123,9 @@ static const char* ProtoUnwindingErrorCodeToString(
class ReportSampleCommand : public Command {
public:
ReportSampleCommand()
- : Command("report-sample", "report raw sample information in perf.data",
- // clang-format off
+ : Command(
+ "report-sample", "report raw sample information in perf.data",
+ // clang-format off
"Usage: simpleperf report-sample [options]\n"
"--dump-protobuf-report <file>\n"
" Dump report file generated by\n"
@@ -133,6 +134,7 @@ class ReportSampleCommand : public Command {
"-o report_file_name Set report file name. Default report file name is\n"
" report_sample.trace if --protobuf is used, otherwise\n"
" the report is written to stdout.\n"
+"--proguard-mapping-file <file> Add proguard mapping file to de-obfuscate symbols.\n"
"--protobuf Use protobuf format in cmd_report_sample.proto to output samples.\n"
" Need to set a report_file_name when using this option.\n"
"--show-callchain Print callchain samples.\n"
@@ -141,8 +143,8 @@ class ReportSampleCommand : public Command {
"--show-art-frames Show frames of internal methods in the ART Java interpreter.\n"
"--show-execution-type Show execution type of a method\n"
"--symdir <dir> Look for files with symbols in a directory recursively.\n"
- // clang-format on
- ),
+ // clang-format on
+ ),
record_filename_("perf.data"),
show_callchain_(false),
use_protobuf_(false),
@@ -285,44 +287,44 @@ bool ReportSampleCommand::Run(const std::vector<std::string>& args) {
}
bool ReportSampleCommand::ParseOptions(const std::vector<std::string>& args) {
- for (size_t i = 0; i < args.size(); ++i) {
- if (args[i] == "--dump-protobuf-report") {
- if (!NextArgumentOrError(args, &i)) {
- return false;
- }
- dump_protobuf_report_file_ = args[i];
- } else if (args[i] == "-i") {
- if (!NextArgumentOrError(args, &i)) {
- return false;
- }
- record_filename_ = args[i];
- } else if (args[i] == "-o") {
- if (!NextArgumentOrError(args, &i)) {
- return false;
- }
- report_filename_ = args[i];
- } else if (args[i] == "--protobuf") {
- use_protobuf_ = true;
- } else if (args[i] == "--show-callchain") {
- show_callchain_ = true;
- } else if (args[i] == "--remove-unknown-kernel-symbols") {
- remove_unknown_kernel_symbols_ = true;
- } else if (args[i] == "--show-art-frames") {
- callchain_report_builder_.SetRemoveArtFrame(false);
- } else if (args[i] == "--show-execution-type") {
- show_execution_type_ = true;
- } else if (args[i] == "--symdir") {
- if (!NextArgumentOrError(args, &i)) {
- return false;
- }
- if (!Dso::AddSymbolDir(args[i])) {
- return false;
- }
- } else {
- ReportUnknownOption(args, i);
+ const OptionFormatMap option_formats = {
+ {"--dump-protobuf-report", {OptionValueType::STRING, OptionType::SINGLE}},
+ {"-i", {OptionValueType::STRING, OptionType::SINGLE}},
+ {"-o", {OptionValueType::STRING, OptionType::SINGLE}},
+ {"--proguard-mapping-file", {OptionValueType::STRING, OptionType::MULTIPLE}},
+ {"--protobuf", {OptionValueType::NONE, OptionType::SINGLE}},
+ {"--show-callchain", {OptionValueType::NONE, OptionType::SINGLE}},
+ {"--remove-unknown-kernel-symbols", {OptionValueType::NONE, OptionType::SINGLE}},
+ {"--show-art-frames", {OptionValueType::NONE, OptionType::SINGLE}},
+ {"--show-execution-type", {OptionValueType::NONE, OptionType::SINGLE}},
+ {"--symdir", {OptionValueType::STRING, OptionType::MULTIPLE}},
+ };
+ OptionValueMap options;
+ std::vector<std::pair<OptionName, OptionValue>> ordered_options;
+ if (!PreprocessOptions(args, option_formats, &options, &ordered_options, nullptr)) {
+ return false;
+ }
+ options.PullStringValue("--dump-protobuf-report", &dump_protobuf_report_file_);
+ options.PullStringValue("-i", &record_filename_);
+ options.PullStringValue("-o", &report_filename_);
+ for (const OptionValue& value : options.PullValues("--proguard-mapping-file")) {
+ if (!callchain_report_builder_.AddProguardMappingFile(*value.str_value)) {
+ return false;
+ }
+ }
+ use_protobuf_ = options.PullBoolValue("--protobuf");
+ show_callchain_ = options.PullBoolValue("--show-callchain");
+ remove_unknown_kernel_symbols_ = options.PullBoolValue("--remove-unknown-kernel-symbols");
+ if (options.PullBoolValue("--show-art-frames")) {
+ callchain_report_builder_.SetRemoveArtFrame(false);
+ }
+ show_execution_type_ = options.PullBoolValue("--show-execution-type");
+ for (const OptionValue& value : options.PullValues("--symdir")) {
+ if (!Dso::AddSymbolDir(*value.str_value)) {
return false;
}
}
+ CHECK(options.values.empty());
if (use_protobuf_ && report_filename_.empty()) {
report_filename_ = "report_sample.trace";
diff --git a/simpleperf/cmd_report_sample_test.cpp b/simpleperf/cmd_report_sample_test.cpp
index 72c8e8fb..38e3c423 100644
--- a/simpleperf/cmd_report_sample_test.cpp
+++ b/simpleperf/cmd_report_sample_test.cpp
@@ -191,3 +191,21 @@ TEST(cmd_report_sample, show_unwinding_result) {
GetProtobufReport("perf_with_failed_unwinding_debug_info.data", &data, {"--show-callchain"});
ASSERT_NE(data.find("error_code: ERROR_INVALID_MAP"), std::string::npos);
}
+
+TEST(cmd_report_sample, proguard_mapping_file_option) {
+ std::string data;
+ // Symbols aren't de-obfuscated without proguard mapping file.
+ GetProtobufReport("perf_need_proguard_mapping.data", &data, {"--show-callchain"});
+ ASSERT_EQ(data.find("androidx.fragment.app.FragmentActivity.startActivityForResult"),
+ std::string::npos);
+ ASSERT_EQ(data.find("com.example.android.displayingbitmaps.ui.ImageGridFragment.onItemClick"),
+ std::string::npos);
+ // Symbols are de-obfuscated with proguard mapping file.
+ GetProtobufReport(
+ "perf_need_proguard_mapping.data", &data,
+ {"--show-callchain", "--proguard-mapping-file", GetTestData("proguard_mapping.txt")});
+ ASSERT_NE(data.find("androidx.fragment.app.FragmentActivity.startActivityForResult"),
+ std::string::npos);
+ ASSERT_NE(data.find("com.example.android.displayingbitmaps.ui.ImageGridFragment.onItemClick"),
+ std::string::npos);
+}
diff --git a/simpleperf/report_lib_interface.cpp b/simpleperf/report_lib_interface.cpp
index 6f39db46..d6a4bc09 100644
--- a/simpleperf/report_lib_interface.cpp
+++ b/simpleperf/report_lib_interface.cpp
@@ -135,6 +135,9 @@ class ReportLib {
callchain_report_builder_.SetRemoveArtFrame(remove_art_frame);
}
void MergeJavaMethods(bool merge) { callchain_report_builder_.SetConvertJITFrame(merge); }
+ bool AddProguardMappingFile(const char* mapping_file) {
+ return callchain_report_builder_.AddProguardMappingFile(mapping_file);
+ }
Sample* GetNextSample();
Event* GetEventOfCurrentSample() { return &current_event_; }
@@ -413,6 +416,7 @@ bool SetKallsymsFile(ReportLib* report_lib, const char* kallsyms_file) EXPORT;
void ShowIpForUnknownSymbol(ReportLib* report_lib) EXPORT;
void ShowArtFrames(ReportLib* report_lib, bool show) EXPORT;
void MergeJavaMethods(ReportLib* report_lib, bool merge) EXPORT;
+bool AddProguardMappingFile(ReportLib* report_lib, const char* mapping_file) EXPORT;
Sample* GetNextSample(ReportLib* report_lib) EXPORT;
Event* GetEventOfCurrentSample(ReportLib* report_lib) EXPORT;
@@ -461,6 +465,10 @@ bool SetKallsymsFile(ReportLib* report_lib, const char* kallsyms_file) {
return report_lib->SetKallsymsFile(kallsyms_file);
}
+bool AddProguardMappingFile(ReportLib* report_lib, const char* mapping_file) {
+ return report_lib->AddProguardMappingFile(mapping_file);
+}
+
Sample* GetNextSample(ReportLib* report_lib) {
return report_lib->GetNextSample();
}
diff --git a/simpleperf/testdata/perf_need_proguard_mapping.data b/simpleperf/testdata/perf_need_proguard_mapping.data
new file mode 100644
index 00000000..dba2d5b4
--- /dev/null
+++ b/simpleperf/testdata/perf_need_proguard_mapping.data
Binary files differ
diff --git a/simpleperf/testdata/proguard_mapping.txt b/simpleperf/testdata/proguard_mapping.txt
new file mode 100644
index 00000000..c37d45da
--- /dev/null
+++ b/simpleperf/testdata/proguard_mapping.txt
@@ -0,0 +1,36 @@
+androidx.fragment.app.FragmentActivity -> a.h.a.c:
+ int mNextCandidateRequestIndex -> l
+ androidx.lifecycle.LifecycleRegistry mFragmentLifecycleRegistry -> g
+ boolean mResumed -> i
+ boolean mStopped -> j
+ boolean mStartedActivityFromFragment -> k
+ androidx.fragment.app.FragmentController mFragments -> f
+ androidx.collection.SparseArrayCompat mPendingFragmentActivityResults -> m
+ boolean mCreated -> h
+ 82:128:void <init>() -> <init>
+ 536:552:void onStart() -> onStart
+ 446:447:void onStateNotSaved() -> onStateNotSaved
+ 559:566:void onStop() -> onStop
+ 583:584:void supportInvalidateOptionsMenu() -> p
+ 658:664:void startActivityForResult(android.content.Intent,int) -> startActivityForResult
+ 671:677:void startActivityForResult(android.content.Intent,int,android.os.Bundle) -> startActivityForResult
+ 685:692:void startIntentSenderForResult(android.content.IntentSender,int,android.content.Intent,int,int,int) -> startIntentSenderForResult
+ 700:707:void startIntentSenderForResult(android.content.IntentSender,int,android.content.Intent,int,int,int,android.os.Bundle) -> startIntentSenderForResult
+com.example.android.displayingbitmaps.ui.ImageGridFragment -> b.a.a.b.c.b:
+ com.example.android.displayingbitmaps.ui.ImageGridFragment$ImageAdapter mAdapter -> Y
+ int mImageThumbSpacing -> X
+ int mImageThumbSize -> W
+ com.example.android.displayingbitmaps.util.ImageFetcher mImageFetcher -> Z
+ 70:70:void <init>() -> <init>
+ 74:91:void onCreate(android.os.Bundle) -> a0
+ 196:197:void onCreateOptionsMenu(android.view.Menu,android.view.MenuInflater) -> d0
+ 97:153:android.view.View onCreateView(android.view.LayoutInflater,android.view.ViewGroup,android.os.Bundle) -> e0
+ 173:175:void onDestroy() -> f0
+ 201:208:boolean onOptionsItemSelected(android.view.MenuItem) -> o0
+ 180:192:void onItemClick(android.widget.AdapterView,android.view.View,int,long) -> onItemClick
+ 165:169:void onPause() -> q0
+ 58:58:com.example.android.displayingbitmaps.util.ImageFetcher access$000(com.example.android.displayingbitmaps.ui.ImageGridFragment) -> r1
+ 58:58:com.example.android.displayingbitmaps.ui.ImageGridFragment$ImageAdapter access$100(com.example.android.displayingbitmaps.ui.ImageGridFragment) -> s1
+ 58:58:int access$200(com.example.android.displayingbitmaps.ui.ImageGridFragment) -> t1
+ 58:58:int access$300(com.example.android.displayingbitmaps.ui.ImageGridFragment) -> u1
+ 158:161:void onResume() -> v0