Merge "Simpleperf: add --max-stack and --percent-limit options for report cmd."
diff --git a/simpleperf/SampleDisplayer.h b/simpleperf/SampleDisplayer.h
index 606f639..bc74e3d 100644
--- a/simpleperf/SampleDisplayer.h
+++ b/simpleperf/SampleDisplayer.h
@@ -96,6 +96,10 @@
template <typename SampleT, typename CallChainNodeT>
class CallgraphDisplayer {
public:
+ CallgraphDisplayer(uint32_t max_stack = UINT32_MAX,
+ double percent_limit = 0.0)
+ : max_stack_(max_stack), percent_limit_(percent_limit) {}
+
virtual ~CallgraphDisplayer() {}
void operator()(FILE* fp, const SampleT* sample) {
@@ -113,21 +117,23 @@
void DisplayCallGraphEntry(FILE* fp, size_t depth, std::string prefix,
const std::unique_ptr<CallChainNodeT>& node,
uint64_t parent_period, bool last) {
- if (depth > 20) {
- LOG(WARNING) << "truncated callgraph at depth " << depth;
+ if (depth > max_stack_) {
return;
}
- prefix += "|";
- fprintf(fp, "%s\n", prefix.c_str());
- if (last) {
- prefix.back() = ' ';
- }
std::string percentage_s = "-- ";
if (node->period + node->children_period != parent_period) {
double percentage =
100.0 * (node->period + node->children_period) / parent_period;
+ if (percentage < percent_limit_) {
+ return;
+ }
percentage_s = android::base::StringPrintf("--%.2f%%-- ", percentage);
}
+ prefix += "|";
+ fprintf(fp, "%s\n", prefix.c_str());
+ if (last) {
+ prefix.back() = ' ';
+ }
fprintf(fp, "%s%s%s\n", prefix.c_str(), percentage_s.c_str(),
PrintSampleName(node->chain[0]).c_str());
prefix.append(percentage_s.size(), ' ');
@@ -146,6 +152,10 @@
virtual std::string PrintSampleName(const SampleT* sample) {
return sample->symbol->DemangledName();
}
+
+ private:
+ uint32_t max_stack_;
+ double percent_limit_;
};
// SampleDisplayer is a class using a collections of display functions to show a
diff --git a/simpleperf/cmd_record.cpp b/simpleperf/cmd_record.cpp
index a076778..1cbbd8f 100644
--- a/simpleperf/cmd_record.cpp
+++ b/simpleperf/cmd_record.cpp
@@ -26,6 +26,7 @@
#include <android-base/logging.h>
#include <android-base/file.h>
+#include <android-base/parsedouble.h>
#include <android-base/parseint.h>
#include <android-base/strings.h>
@@ -418,10 +419,8 @@
if (!NextArgumentOrError(args, &i)) {
return false;
}
- errno = 0;
- char* endptr;
- duration_in_sec_ = strtod(args[i].c_str(), &endptr);
- if (duration_in_sec_ <= 0 || *endptr != '\0' || errno == ERANGE) {
+ if (!android::base::ParseDouble(args[i].c_str(), &duration_in_sec_,
+ 1e-9)) {
LOG(ERROR) << "Invalid duration: " << args[i].c_str();
return false;
}
diff --git a/simpleperf/cmd_report.cpp b/simpleperf/cmd_report.cpp
index 830ec13..7fd0f61 100644
--- a/simpleperf/cmd_report.cpp
+++ b/simpleperf/cmd_report.cpp
@@ -25,6 +25,7 @@
#include <vector>
#include <android-base/logging.h>
+#include <android-base/parsedouble.h>
#include <android-base/parseint.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
@@ -276,10 +277,12 @@
" the graph shows how functions call others.\n"
" Default is caller mode.\n"
"-i <file> Specify path of record file, default is perf.data.\n"
+"--max-stack <frames> Set max stack frames shown when printing call graph.\n"
"-n Print the sample count for each item.\n"
"--no-demangle Don't demangle symbol names.\n"
"--no-show-ip Don't show vaddr in file for unknown symbols.\n"
"-o report_file_name Set report file name, default is stdout.\n"
+"--percent-limit <percent> Set min percentage shown when printing call graph.\n"
"--pids pid1,pid2,... Report only for selected pids.\n"
"--sort key1,key2,... Select keys used to sort and print the report. The\n"
" appearance order of keys decides the order of keys used\n"
@@ -312,7 +315,9 @@
system_wide_collection_(false),
accumulate_callchain_(false),
print_callgraph_(false),
- callgraph_show_callee_(false) {}
+ callgraph_show_callee_(false),
+ callgraph_max_stack_(UINT32_MAX),
+ callgraph_percent_limit_(0) {}
bool Run(const std::vector<std::string>& args);
@@ -341,6 +346,8 @@
bool accumulate_callchain_;
bool print_callgraph_;
bool callgraph_show_callee_;
+ uint32_t callgraph_max_stack_;
+ double callgraph_percent_limit_;
std::string report_filename_;
};
@@ -423,6 +430,14 @@
}
record_filename_ = args[i];
+ } else if (args[i] == "--max-stack") {
+ if (!NextArgumentOrError(args, &i)) {
+ return false;
+ }
+ if (!android::base::ParseUint(args[i].c_str(), &callgraph_max_stack_)) {
+ LOG(ERROR) << "invalid arg for --max-stack: " << args[i];
+ return false;
+ }
} else if (args[i] == "-n") {
print_sample_count = true;
@@ -435,7 +450,14 @@
return false;
}
report_filename_ = args[i];
-
+ } else if (args[i] == "--percent-limit") {
+ if (!NextArgumentOrError(args, &i)) {
+ return false;
+ }
+ if (!android::base::ParseDouble(args[i].c_str(),
+ &callgraph_percent_limit_, 0.0)) {
+ LOG(ERROR) << "invalid arg for --percent-limit: " << args[i];
+ }
} else if (args[i] == "--pids" || args[i] == "--tids") {
const std::string& option = args[i];
std::unordered_set<int>& filter =
@@ -562,7 +584,8 @@
displayer.AddExclusiveDisplayFunction(
ReportCmdCallgraphDisplayerWithVaddrInFile());
} else {
- displayer.AddExclusiveDisplayFunction(ReportCmdCallgraphDisplayer());
+ displayer.AddExclusiveDisplayFunction(ReportCmdCallgraphDisplayer(
+ callgraph_max_stack_, callgraph_percent_limit_));
}
}
}
diff --git a/simpleperf/cmd_report_test.cpp b/simpleperf/cmd_report_test.cpp
index 704076a..e00b5ee 100644
--- a/simpleperf/cmd_report_test.cpp
+++ b/simpleperf/cmd_report_test.cpp
@@ -415,6 +415,28 @@
ASSERT_TRUE(success);
}
+TEST_F(ReportCommandTest, max_stack_and_percent_limit_option) {
+ Report(PERF_DATA_MAX_STACK_AND_PERCENT_LIMIT, {"-g"});
+ ASSERT_TRUE(success);
+ ASSERT_NE(content.find("89.03"), std::string::npos);
+
+ Report(PERF_DATA_MAX_STACK_AND_PERCENT_LIMIT, {"-g", "--max-stack", "0"});
+ ASSERT_TRUE(success);
+ ASSERT_EQ(content.find("89.03"), std::string::npos);
+ Report(PERF_DATA_MAX_STACK_AND_PERCENT_LIMIT, {"-g", "--max-stack", "1"});
+ ASSERT_TRUE(success);
+ ASSERT_NE(content.find("89.03"), std::string::npos);
+
+ Report(PERF_DATA_MAX_STACK_AND_PERCENT_LIMIT,
+ {"-g", "--percent-limit", "90"});
+ ASSERT_TRUE(success);
+ ASSERT_EQ(content.find("89.03"), std::string::npos);
+ Report(PERF_DATA_MAX_STACK_AND_PERCENT_LIMIT,
+ {"-g", "--percent-limit", "70"});
+ ASSERT_TRUE(success);
+ ASSERT_NE(content.find("89.03"), std::string::npos);
+}
+
#if defined(__linux__)
#include "event_selection_set.h"
diff --git a/simpleperf/cmd_stat.cpp b/simpleperf/cmd_stat.cpp
index 9c5cf8f..06258f3 100644
--- a/simpleperf/cmd_stat.cpp
+++ b/simpleperf/cmd_stat.cpp
@@ -27,6 +27,7 @@
#include <vector>
#include <android-base/logging.h>
+#include <android-base/parsedouble.h>
#include <android-base/strings.h>
#include "command.h"
@@ -452,10 +453,8 @@
if (!NextArgumentOrError(args, &i)) {
return false;
}
- errno = 0;
- char* endptr;
- duration_in_sec_ = strtod(args[i].c_str(), &endptr);
- if (duration_in_sec_ <= 0 || *endptr != '\0' || errno == ERANGE) {
+ if (!android::base::ParseDouble(args[i].c_str(), &duration_in_sec_,
+ 1e-9)) {
LOG(ERROR) << "Invalid duration: " << args[i].c_str();
return false;
}
@@ -463,10 +462,8 @@
if (!NextArgumentOrError(args, &i)) {
return false;
}
- errno = 0;
- char* endptr;
- interval_in_ms_ = strtod(args[i].c_str(), &endptr);
- if (interval_in_ms_ <= 0 || *endptr != '\0' || errno == ERANGE) {
+ if (!android::base::ParseDouble(args[i].c_str(), &interval_in_ms_,
+ 1e-9)) {
LOG(ERROR) << "Invalid interval: " << args[i].c_str();
return false;
}
diff --git a/simpleperf/get_test_data.h b/simpleperf/get_test_data.h
index 339871e..4550843 100644
--- a/simpleperf/get_test_data.h
+++ b/simpleperf/get_test_data.h
@@ -99,4 +99,7 @@
// generated_by_linux_perf.data is generated by `perf record -F 1 -a -g -- sleep 0.1`.
static const std::string PERF_DATA_GENERATED_BY_LINUX_PERF = "generated_by_linux_perf.data";
+// generated by `simpleperf record -g ls`.
+static const std::string PERF_DATA_MAX_STACK_AND_PERCENT_LIMIT = "perf_test_max_stack_and_percent_limit.data";
+
#endif // SIMPLE_PERF_GET_TEST_DATA_H_
diff --git a/simpleperf/testdata/perf_test_max_stack_and_percent_limit.data b/simpleperf/testdata/perf_test_max_stack_and_percent_limit.data
new file mode 100644
index 0000000..b3fc225
--- /dev/null
+++ b/simpleperf/testdata/perf_test_max_stack_and_percent_limit.data
Binary files differ