summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYabin Cui <yabinc@google.com>2018-07-17 16:06:21 -0700
committerYabin Cui <yabinc@google.com>2018-07-17 17:49:45 -0700
commit38335f4c3a6f14ee1f30e896757537e7d310c25c (patch)
tree09850e2f307522402033fe7cd5a771096507d6b7
parent57bb921048889b011480317b6153a5f68935ba0f (diff)
downloadextras-38335f4c3a6f14ee1f30e896757537e7d310c25c.tar.gz
simpleperf: record complete process name.
The kernel limits length of process name to 15. But many app processes have name with length longer than 15. This patch records complete process name: When receiving a comm record for a process, try reading complete name from /proc/pid/cmdline and storing the name in the comm record. Bug: none Test: run simpleperf manually, it shows complete app name in reports. Test: run simpleperf_unit_test. Change-Id: Id29f2a2522ef5d2949828450be2d9d2f508a328d
-rw-r--r--simpleperf/cmd_record.cpp18
-rw-r--r--simpleperf/environment.cpp14
-rw-r--r--simpleperf/environment.h2
-rw-r--r--simpleperf/record.cpp23
-rw-r--r--simpleperf/record.h2
-rw-r--r--simpleperf/record_test.cpp14
6 files changed, 68 insertions, 5 deletions
diff --git a/simpleperf/cmd_record.cpp b/simpleperf/cmd_record.cpp
index 2597629f..3ae111cf 100644
--- a/simpleperf/cmd_record.cpp
+++ b/simpleperf/cmd_record.cpp
@@ -277,7 +277,7 @@ class RecordCommand : public Command {
bool ProcessJITDebugInfo(const std::vector<JITSymFile>& jit_symfiles,
const std::vector<DexSymFile>& dex_symfiles, bool sync_kernel_records);
- void UpdateRecordForEmbeddedPath(Record* record);
+ void UpdateRecord(Record* record);
bool UnwindRecord(SampleRecord& r);
bool PostUnwindRecords();
bool JoinCallChains();
@@ -1037,8 +1037,8 @@ bool RecordCommand::DumpProcessMaps(pid_t pid, const std::unordered_set<pid_t>&
}
}
// Dump process name.
- std::string name;
- if (GetThreadName(pid, &name)) {
+ std::string name = GetCompleteProcessName(pid);
+ if (!name.empty()) {
CommRecord record(attr, pid, pid, name, event_id, last_record_timestamp_);
if (!ProcessRecord(&record)) {
return false;
@@ -1057,7 +1057,7 @@ bool RecordCommand::DumpProcessMaps(pid_t pid, const std::unordered_set<pid_t>&
}
bool RecordCommand::ProcessRecord(Record* record) {
- UpdateRecordForEmbeddedPath(record);
+ UpdateRecord(record);
if (ShouldOmitRecord(record)) {
return true;
}
@@ -1241,12 +1241,20 @@ void UpdateMmapRecordForEmbeddedPath(RecordType& r, bool has_prot, uint32_t prot
}
}
-void RecordCommand::UpdateRecordForEmbeddedPath(Record* record) {
+void RecordCommand::UpdateRecord(Record* record) {
if (record->type() == PERF_RECORD_MMAP) {
UpdateMmapRecordForEmbeddedPath(*static_cast<MmapRecord*>(record), false, 0);
} else if (record->type() == PERF_RECORD_MMAP2) {
auto r = static_cast<Mmap2Record*>(record);
UpdateMmapRecordForEmbeddedPath(*r, true, r->data->prot);
+ } else if (record->type() == PERF_RECORD_COMM) {
+ auto r = static_cast<CommRecord*>(record);
+ if (r->data->pid == r->data->tid) {
+ std::string s = GetCompleteProcessName(r->data->pid);
+ if (!s.empty()) {
+ r->SetCommandName(s);
+ }
+ }
}
}
diff --git a/simpleperf/environment.cpp b/simpleperf/environment.cpp
index 7b05c7d1..b90606ba 100644
--- a/simpleperf/environment.cpp
+++ b/simpleperf/environment.cpp
@@ -754,3 +754,17 @@ bool MappedFileOnlyExistInMemory(const char* filename) {
strncmp(filename, "//", 2) == 0 ||
strncmp(filename, "/dev/", 5) == 0;
}
+
+std::string GetCompleteProcessName(pid_t pid) {
+ std::string s;
+ if (!android::base::ReadFileToString(android::base::StringPrintf("/proc/%d/cmdline", pid), &s)) {
+ s.clear();
+ }
+ for (size_t i = 0; i < s.size(); ++i) {
+ if (isspace(s[i])) {
+ s.resize(i);
+ break;
+ }
+ }
+ return s;
+}
diff --git a/simpleperf/environment.h b/simpleperf/environment.h
index b2bb549b..db547f8b 100644
--- a/simpleperf/environment.h
+++ b/simpleperf/environment.h
@@ -129,4 +129,6 @@ std::string GetHardwareFromCpuInfo(const std::string& cpu_info);
bool MappedFileOnlyExistInMemory(const char* filename);
+std::string GetCompleteProcessName(pid_t pid);
+
#endif // SIMPLE_PERF_ENVIRONMENT_H_
diff --git a/simpleperf/record.cpp b/simpleperf/record.cpp
index ab2ef72a..1e9c945b 100644
--- a/simpleperf/record.cpp
+++ b/simpleperf/record.cpp
@@ -343,6 +343,29 @@ CommRecord::CommRecord(const perf_event_attr& attr, uint32_t pid, uint32_t tid,
UpdateBinary(new_binary);
}
+void CommRecord::SetCommandName(const std::string& name) {
+ if (name.compare(comm) == 0) {
+ return;
+ }
+ // The kernel uses a 8-byte aligned space to store command name. Follow it here to allow the same
+ // reading code.
+ size_t old_name_len = Align(strlen(comm) + 1, 8);
+ size_t new_name_len = Align(name.size() + 1, 8);
+ size_t new_size = size() - old_name_len + new_name_len;
+ char* new_binary = new char[new_size];
+ char* p = new_binary;
+ header.size = new_size;
+ MoveToBinaryFormat(header, p);
+ MoveToBinaryFormat(*data, p);
+ data = reinterpret_cast<CommRecordDataType*>(p - sizeof(CommRecordDataType));
+ comm = p;
+ strcpy(p, name.c_str());
+ p += new_name_len;
+ sample_id.WriteToBinaryFormat(p);
+ CHECK_EQ(p, new_binary + new_size);
+ UpdateBinary(new_binary);
+}
+
void CommRecord::DumpData(size_t indent) const {
PrintIndented(indent, "pid %u, tid %u, comm %s\n", data->pid, data->tid,
comm);
diff --git a/simpleperf/record.h b/simpleperf/record.h
index e002370c..3ba73ec0 100644
--- a/simpleperf/record.h
+++ b/simpleperf/record.h
@@ -327,6 +327,8 @@ struct CommRecord : public Record {
CommRecord(const perf_event_attr& attr, uint32_t pid, uint32_t tid,
const std::string& comm, uint64_t event_id, uint64_t time);
+ void SetCommandName(const std::string& name);
+
protected:
void DumpData(size_t indent) const override;
};
diff --git a/simpleperf/record_test.cpp b/simpleperf/record_test.cpp
index c14fdacb..954acfaa 100644
--- a/simpleperf/record_test.cpp
+++ b/simpleperf/record_test.cpp
@@ -131,3 +131,17 @@ TEST_F(RecordTest, SampleRecord_AdjustCallChainGeneratedByKernel) {
expected.header.misc = PERF_RECORD_MISC_KERNEL;
CheckRecordEqual(r, expected);
}
+
+TEST_F(RecordTest, CommRecord) {
+ CommRecord r(event_attr, 1, 2, "init_name", 3, 4);
+ size_t record_size = r.size();
+ std::string new_name = "a_much_longer_name";
+ r.SetCommandName(new_name);
+ ASSERT_EQ(r.size(), record_size + 8);
+ ASSERT_EQ(std::string(r.comm), new_name);
+ ASSERT_EQ(r.data->pid, 1u);
+ ASSERT_EQ(r.data->tid, 2u);
+ ASSERT_EQ(r.sample_id.id_data.id, 3u);
+ ASSERT_EQ(r.sample_id.time_data.time, 4u);
+ CheckRecordMatchBinary(r);
+}