summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYabin Cui <yabinc@google.com>2017-06-02 14:47:33 -0700
committerYabin Cui <yabinc@google.com>2017-06-02 14:49:00 -0700
commit52190a377feeb1dccaae5034c51f0130c24dea09 (patch)
tree1577f2d5b9310453026aaa9f07870b2adef95596
parent668878b3b73878edb9bcf960bd44cc07ec136cb0 (diff)
downloadextras-52190a377feeb1dccaae5034c51f0130c24dea09.tar.gz
simpleperf: add thread name in report_sample.proto.
Bug: http://b/62189080 Test: run simpleperf_unit_test. Change-Id: I3c96f6474e56b2f51a00f85082973e5d1c1aec72
-rw-r--r--simpleperf/cmd_report_sample.cpp47
-rw-r--r--simpleperf/cmd_report_sample_test.cpp12
-rw-r--r--simpleperf/report_sample.proto7
-rw-r--r--simpleperf/thread_tree.cpp8
-rw-r--r--simpleperf/thread_tree.h1
5 files changed, 65 insertions, 10 deletions
diff --git a/simpleperf/cmd_report_sample.cpp b/simpleperf/cmd_report_sample.cpp
index f43f6821..73af7d90 100644
--- a/simpleperf/cmd_report_sample.cpp
+++ b/simpleperf/cmd_report_sample.cpp
@@ -92,8 +92,10 @@ class ReportSampleCommand : public Command {
uint64_t* pvaddr_in_file, uint32_t* pfile_id, int32_t* psymbol_id);
bool GetCallEntry(const ThreadEntry* thread, bool in_kernel, uint64_t ip, bool omit_unknown_dso,
uint64_t* pvaddr_in_file, Dso** pdso, const Symbol** psymbol);
+ bool WriteRecordInProtobuf(proto::Record& proto_record);
bool PrintLostSituationInProtobuf();
bool PrintFileInfoInProtobuf();
+ bool PrintThreadInfoInProtobuf();
bool PrintSampleRecord(const SampleRecord& record);
void PrintLostSituation();
@@ -178,6 +180,9 @@ bool ReportSampleCommand::Run(const std::vector<std::string>& args) {
if (!PrintFileInfoInProtobuf()) {
return false;
}
+ if (!PrintThreadInfoInProtobuf()) {
+ return false;
+ }
coded_os_->WriteLittleEndian32(0);
if (coded_os_->HadError()) {
LOG(ERROR) << "print protobuf report failed";
@@ -313,6 +318,12 @@ bool ReportSampleCommand::DumpProtobufReport(const std::string& filename) {
return false;
}
files.push_back(file.symbol_size());
+ } else if (proto_record.has_thread()) {
+ auto& thread = proto_record.thread();
+ FprintIndented(report_fp_, 0, "thread:\n");
+ FprintIndented(report_fp_, 1, "thread_id: %u\n", thread.thread_id());
+ FprintIndented(report_fp_, 1, "process_id: %u\n", thread.process_id());
+ FprintIndented(report_fp_, 1, "thread_name: %s\n", thread.thread_name().c_str());
} else {
LOG(ERROR) << "unexpected record type ";
return false;
@@ -404,9 +415,13 @@ bool ReportSampleCommand::PrintSampleRecordInProtobuf(const SampleRecord& r) {
}
}
}
+ return WriteRecordInProtobuf(proto_record);
+}
+
+bool ReportSampleCommand::WriteRecordInProtobuf(proto::Record& proto_record) {
coded_os_->WriteLittleEndian32(proto_record.ByteSize());
if (!proto_record.SerializeToCodedStream(coded_os_)) {
- LOG(ERROR) << "failed to write sample to protobuf";
+ LOG(ERROR) << "failed to write record to protobuf";
return false;
}
return true;
@@ -458,12 +473,7 @@ bool ReportSampleCommand::PrintLostSituationInProtobuf() {
proto::LostSituation* lost = proto_record.mutable_lost();
lost->set_sample_count(sample_count_);
lost->set_lost_count(lost_count_);
- coded_os_->WriteLittleEndian32(proto_record.ByteSize());
- if (!proto_record.SerializeToCodedStream(coded_os_)) {
- LOG(ERROR) << "failed to write lost situation to protobuf";
- return false;
- }
- return true;
+ return WriteRecordInProtobuf(proto_record);
}
static bool CompareDsoByDumpId(Dso* d1, Dso* d2) {
@@ -500,9 +510,26 @@ bool ReportSampleCommand::PrintFileInfoInProtobuf() {
std::string* symbol = file->add_symbol();
*symbol = sym->DemangledName();
}
- coded_os_->WriteLittleEndian32(proto_record.ByteSize());
- if (!proto_record.SerializeToCodedStream(coded_os_)) {
- LOG(ERROR) << "failed to write file info to protobuf";
+ if (!WriteRecordInProtobuf(proto_record)) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool ReportSampleCommand::PrintThreadInfoInProtobuf() {
+ std::vector<const ThreadEntry*> threads = thread_tree_.GetAllThreads();
+ auto compare_thread_id = [](const ThreadEntry* t1, const ThreadEntry* t2) {
+ return t1->tid < t2->tid;
+ };
+ std::sort(threads.begin(), threads.end(), compare_thread_id);
+ for (auto& thread : threads) {
+ proto::Record proto_record;
+ proto::Thread* proto_thread = proto_record.mutable_thread();
+ proto_thread->set_thread_id(thread->tid);
+ proto_thread->set_process_id(thread->pid);
+ proto_thread->set_thread_name(thread->comm);
+ if (!WriteRecordInProtobuf(proto_record)) {
return false;
}
}
diff --git a/simpleperf/cmd_report_sample_test.cpp b/simpleperf/cmd_report_sample_test.cpp
index 3e92396d..2a712be4 100644
--- a/simpleperf/cmd_report_sample_test.cpp
+++ b/simpleperf/cmd_report_sample_test.cpp
@@ -79,3 +79,15 @@ TEST(cmd_report_sample, sample_has_event_count) {
ASSERT_TRUE(android::base::ReadFileToString(tmpfile2.path, &data));
ASSERT_NE(data.find("event_count:"), std::string::npos);
}
+
+TEST(cmd_report_sample, has_thread_record) {
+ TemporaryFile tmpfile;
+ TemporaryFile tmpfile2;
+ ASSERT_TRUE(ReportSampleCmd()->Run({"-i", GetTestData(PERF_DATA_WITH_SYMBOLS),
+ "-o", tmpfile.path, "--protobuf"}));
+ ASSERT_TRUE(ReportSampleCmd()->Run(
+ {"--dump-protobuf-report", tmpfile.path, "-o", tmpfile2.path}));
+ std::string data;
+ ASSERT_TRUE(android::base::ReadFileToString(tmpfile2.path, &data));
+ ASSERT_NE(data.find("thread:"), std::string::npos);
+}
diff --git a/simpleperf/report_sample.proto b/simpleperf/report_sample.proto
index 5e1d8605..a40f8032 100644
--- a/simpleperf/report_sample.proto
+++ b/simpleperf/report_sample.proto
@@ -59,10 +59,17 @@ message File {
repeated string symbol = 3;
}
+message Thread {
+ optional uint32 thread_id = 1;
+ optional uint32 process_id = 2;
+ optional string thread_name = 3;
+}
+
message Record {
oneof record_data {
Sample sample = 1;
LostSituation lost = 2;
File file = 3;
+ Thread thread = 4;
}
} \ No newline at end of file
diff --git a/simpleperf/thread_tree.cpp b/simpleperf/thread_tree.cpp
index a6f86a8a..92a8a8fe 100644
--- a/simpleperf/thread_tree.cpp
+++ b/simpleperf/thread_tree.cpp
@@ -327,4 +327,12 @@ std::vector<Dso*> ThreadTree::GetAllDsos() const {
return result;
}
+std::vector<const ThreadEntry*> ThreadTree::GetAllThreads() const {
+ std::vector<const ThreadEntry*> threads;
+ for (auto& pair : thread_tree_) {
+ threads.push_back(pair.second.get());
+ }
+ return threads;
+}
+
} // namespace simpleperf
diff --git a/simpleperf/thread_tree.h b/simpleperf/thread_tree.h
index 8df6b7ba..621bc467 100644
--- a/simpleperf/thread_tree.h
+++ b/simpleperf/thread_tree.h
@@ -119,6 +119,7 @@ class ThreadTree {
void Update(const Record& record);
std::vector<Dso*> GetAllDsos() const;
+ std::vector<const ThreadEntry*> GetAllThreads() const;
private:
ThreadEntry* CreateThread(int pid, int tid);