Merge "Snap for 4787638 from 5552beb813d2a5ae60c4eef9a4a5646b7ab430d7 to oreo-mr1-cts-release" into oreo-mr1-cts-release
diff --git a/simpleperf/cmd_kmem.cpp b/simpleperf/cmd_kmem.cpp
index 51f9a58..59ec2c3 100644
--- a/simpleperf/cmd_kmem.cpp
+++ b/simpleperf/cmd_kmem.cpp
@@ -612,7 +612,8 @@
slab_sample_tree_builder_->ProcessSampleRecord(
*static_cast<const SampleRecord*>(record.get()));
}
- } else if (record->type() == PERF_RECORD_TRACING_DATA) {
+ } else if (record->type() == PERF_RECORD_TRACING_DATA ||
+ record->type() == SIMPLE_PERF_RECORD_TRACING_DATA) {
const auto& r = *static_cast<TracingDataRecord*>(record.get());
ProcessTracingData(std::vector<char>(r.data, r.data + r.data_size));
}
diff --git a/simpleperf/cmd_record_test.cpp b/simpleperf/cmd_record_test.cpp
index c3f9cb4..e942332 100644
--- a/simpleperf/cmd_record_test.cpp
+++ b/simpleperf/cmd_record_test.cpp
@@ -391,12 +391,21 @@
TEST(record_cmd, handle_SIGHUP) {
TemporaryFile tmpfile;
- std::thread thread([]() {
- sleep(1);
+ int pipefd[2];
+ ASSERT_EQ(0, pipe(pipefd));
+ int read_fd = pipefd[0];
+ int write_fd = pipefd[1];
+ char data[8] = {};
+ std::thread thread([&]() {
+ android::base::ReadFully(read_fd, data, 7);
kill(getpid(), SIGHUP);
});
- thread.detach();
- ASSERT_TRUE(RecordCmd()->Run({"-o", tmpfile.path, "sleep", "1000000"}));
+ ASSERT_TRUE(RecordCmd()->Run({"-o", tmpfile.path, "--start_profiling_fd",
+ std::to_string(write_fd), "sleep", "1000000"}));
+ thread.join();
+ close(write_fd);
+ close(read_fd);
+ ASSERT_STREQ(data, "STARTED");
}
TEST(record_cmd, stop_when_no_more_targets) {
diff --git a/simpleperf/cmd_report.cpp b/simpleperf/cmd_report.cpp
index 29cf743..f026d32 100644
--- a/simpleperf/cmd_report.cpp
+++ b/simpleperf/cmd_report.cpp
@@ -777,7 +777,8 @@
size_t attr_id = record_file_reader_->GetAttrIndexOfRecord(record.get());
sample_tree_builder_[attr_id]->ProcessSampleRecord(
*static_cast<const SampleRecord*>(record.get()));
- } else if (record->type() == PERF_RECORD_TRACING_DATA) {
+ } else if (record->type() == PERF_RECORD_TRACING_DATA ||
+ record->type() == SIMPLE_PERF_RECORD_TRACING_DATA) {
const auto& r = *static_cast<TracingDataRecord*>(record.get());
if (!ProcessTracingData(std::vector<char>(r.data, r.data + r.data_size))) {
return false;
diff --git a/simpleperf/cmd_report_test.cpp b/simpleperf/cmd_report_test.cpp
index e146876..2790c27 100644
--- a/simpleperf/cmd_report_test.cpp
+++ b/simpleperf/cmd_report_test.cpp
@@ -471,6 +471,11 @@
ASSERT_EQ(content.find("skipped in brief callgraph mode"), std::string::npos);
}
+TEST_F(ReportCommandTest, report_big_trace_data) {
+ Report(PERF_DATA_WITH_BIG_TRACE_DATA);
+ ASSERT_TRUE(success);
+}
+
#if defined(__linux__)
#include "event_selection_set.h"
diff --git a/simpleperf/cmd_stat_test.cpp b/simpleperf/cmd_stat_test.cpp
index 3cdb4eb..3876b42 100644
--- a/simpleperf/cmd_stat_test.cpp
+++ b/simpleperf/cmd_stat_test.cpp
@@ -157,6 +157,11 @@
}
TEST(stat_cmd, handle_SIGHUP) {
+ if (!GetDefaultAppPackageName().empty()) {
+ // See http://b/79495636.
+ GTEST_LOG_(INFO) << "Omit this test in app's context.";
+ return;
+ }
std::thread thread([]() {
sleep(1);
kill(getpid(), SIGHUP);
diff --git a/simpleperf/get_test_data.h b/simpleperf/get_test_data.h
index 963fe00..625b3de 100644
--- a/simpleperf/get_test_data.h
+++ b/simpleperf/get_test_data.h
@@ -108,4 +108,6 @@
// generated by recording an app.
static const std::string PERF_DATA_WITH_WRONG_IP_IN_CALLCHAIN = "wrong_ip_callchain_perf.data";
+static const std::string PERF_DATA_WITH_BIG_TRACE_DATA = "perf_with_big_trace_data.data";
+
#endif // SIMPLE_PERF_GET_TEST_DATA_H_
diff --git a/simpleperf/record.cpp b/simpleperf/record.cpp
index 65e98ea..697434b 100644
--- a/simpleperf/record.cpp
+++ b/simpleperf/record.cpp
@@ -46,6 +46,9 @@
{SIMPLE_PERF_RECORD_DSO, "dso"},
{SIMPLE_PERF_RECORD_SYMBOL, "symbol"},
{SIMPLE_PERF_RECORD_EVENT_ID, "event_id"},
+ {SIMPLE_PERF_RECORD_CALLCHAIN, "callchain"},
+ {SIMPLE_PERF_RECORD_UNWINDING_RESULT, "unwinding_result"},
+ {SIMPLE_PERF_RECORD_TRACING_DATA, "tracing_data"},
};
auto it = record_type_names.find(record_type);
@@ -821,7 +824,7 @@
}
TracingDataRecord::TracingDataRecord(const std::vector<char>& tracing_data) {
- SetTypeAndMisc(PERF_RECORD_TRACING_DATA, 0);
+ SetTypeAndMisc(SIMPLE_PERF_RECORD_TRACING_DATA, 0);
data_size = tracing_data.size();
SetSize(header_size() + sizeof(uint32_t) + Align(tracing_data.size(), 64));
char* new_binary = new char[size()];
@@ -904,6 +907,8 @@
return std::unique_ptr<Record>(new SymbolRecord(p));
case SIMPLE_PERF_RECORD_EVENT_ID:
return std::unique_ptr<Record>(new EventIdRecord(p));
+ case SIMPLE_PERF_RECORD_TRACING_DATA:
+ return std::unique_ptr<Record>(new TracingDataRecord(p));
default:
return std::unique_ptr<Record>(new UnknownRecord(p));
}
diff --git a/simpleperf/record.h b/simpleperf/record.h
index d6ee2ce..cfe3191 100644
--- a/simpleperf/record.h
+++ b/simpleperf/record.h
@@ -46,6 +46,9 @@
SIMPLE_PERF_RECORD_SPLIT,
SIMPLE_PERF_RECORD_SPLIT_END,
SIMPLE_PERF_RECORD_EVENT_ID,
+ SIMPLE_PERF_RECORD_CALLCHAIN,
+ SIMPLE_PERF_RECORD_UNWINDING_RESULT,
+ SIMPLE_PERF_RECORD_TRACING_DATA,
};
// perf_event_header uses u16 to store record size. However, that is not
diff --git a/simpleperf/testdata/perf_with_big_trace_data.data b/simpleperf/testdata/perf_with_big_trace_data.data
new file mode 100644
index 0000000..5134ec5
--- /dev/null
+++ b/simpleperf/testdata/perf_with_big_trace_data.data
Binary files differ
diff --git a/simpleperf/tracing.cpp b/simpleperf/tracing.cpp
index 884a883..df86d59 100644
--- a/simpleperf/tracing.cpp
+++ b/simpleperf/tracing.cpp
@@ -24,6 +24,7 @@
#include <android-base/file.h>
#include <android-base/logging.h>
+#include <android-base/parseint.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
@@ -295,14 +296,23 @@
} else if (s[i] == ';') {
value = s.substr(start, i - start);
if (name == "field") {
- size_t pos = value.find_first_of('[');
- if (pos == std::string::npos) {
+ // Parse value with brackets like "comm[16]", or just a field name.
+ size_t left_bracket_pos = value.find('[');
+ if (left_bracket_pos == std::string::npos) {
field.name = value;
field.elem_count = 1;
} else {
- field.name = value.substr(0, pos);
- field.elem_count =
- static_cast<size_t>(strtoull(&value[pos + 1], nullptr, 10));
+ field.name = value.substr(0, left_bracket_pos);
+ field.elem_count = 1;
+ size_t right_bracket_pos = value.find(']', left_bracket_pos);
+ if (right_bracket_pos != std::string::npos) {
+ size_t len = right_bracket_pos - left_bracket_pos - 1;
+ size_t elem_count;
+ // Array size may not be a number, like field:u32 rates[IEEE80211_NUM_BANDS].
+ if (android::base::ParseUint(value.substr(left_bracket_pos + 1, len), &elem_count)) {
+ field.elem_count = elem_count;
+ }
+ }
}
} else if (name == "offset") {
field.offset =