Added support to read multiple fields from cmdline.
Bug:73058765
Change-Id: I855d50393048ea9700d7ea050b95df1fc405e6d7
diff --git a/src/process_stats/process_info.h b/src/process_stats/process_info.h
index 1c8a5d9..2739644 100644
--- a/src/process_stats/process_info.h
+++ b/src/process_stats/process_info.h
@@ -6,6 +6,7 @@
#define SRC_PROCESS_STATS_PROCESS_INFO_H_
#include <map>
+#include <vector>
struct ThreadInfo {
int tid;
@@ -18,7 +19,7 @@
bool in_kernel;
bool is_app;
char exe[256];
- char cmdline[256];
+ std::vector<std::string> cmdline;
std::map<int, ThreadInfo> threads;
};
diff --git a/src/process_stats/procfs_utils.cc b/src/process_stats/procfs_utils.cc
index 1c2d2e6..4aa9744 100644
--- a/src/process_stats/procfs_utils.cc
+++ b/src/process_stats/procfs_utils.cc
@@ -50,7 +50,17 @@
return -1;
const char* line = strstr(buf, status_string);
PERFETTO_DCHECK(line);
- return atoi(line + sizeof(status_string) - 1);
+ return atoi(line + strlen(status_string));
+}
+
+inline std::vector<std::string> SplitOnNull(const char* input) {
+ std::vector<std::string> output;
+ do {
+ // This works because it will only push the string up to a null character.
+ output.push_back(std::string(input));
+ input += output.back().size() + 1;
+ } while (input[0] != 0);
+ return output;
}
} // namespace
@@ -66,14 +76,19 @@
std::unique_ptr<ProcessInfo> ReadProcessInfo(int pid) {
ProcessInfo* process = new ProcessInfo();
process->pid = pid;
- // TODO(taylori) Parse full cmdline into a vector.
- ReadProcString(pid, "cmdline", process->cmdline, sizeof(process->cmdline));
- if (process->cmdline[0] == 0) {
- ReadProcString(pid, "comm", process->cmdline, sizeof(process->cmdline));
+ char cmdline_buf[256];
+ process->cmdline = SplitOnNull("\0");
+ ReadProcString(pid, "cmdline", cmdline_buf, sizeof(cmdline_buf));
+ if (cmdline_buf[0] == 0) {
+ // Nothing in cmdline_buf so read name from /comm instead.
+ char name[256];
+ ReadProcString(pid, "comm", name, sizeof(name));
+ process->cmdline.push_back(name);
process->in_kernel = true;
} else {
+ process->cmdline = SplitOnNull(cmdline_buf);
ReadExePath(pid, process->exe, sizeof(process->exe));
- process->is_app = IsApp(process->cmdline, process->exe);
+ process->is_app = IsApp(process->cmdline[0].c_str(), process->exe);
}
process->ppid = ReadPpid(pid);
return std::unique_ptr<ProcessInfo>(process);
diff --git a/src/traced/probes/probes_producer.cc b/src/traced/probes/probes_producer.cc
index 7c81c1d..5ac726c 100644
--- a/src/traced/probes/probes_producer.cc
+++ b/src/traced/probes/probes_producer.cc
@@ -156,8 +156,8 @@
auto* process_writer = process_tree->add_processes();
process_writer->set_pid(process->pid);
process_writer->set_ppid(process->ppid);
- process_writer->add_cmdline(process->cmdline);
-
+ for (const auto& field : process->cmdline)
+ process_writer->add_cmdline(field.c_str());
for (auto& thread : process->threads) {
auto* thread_writer = process_writer->add_threads();
thread_writer->set_tid(thread.second.tid);
diff --git a/tools/trace_to_text/main.cc b/tools/trace_to_text/main.cc
index 7c9c92d..7fe7c63 100644
--- a/tools/trace_to_text/main.cc
+++ b/tools/trace_to_text/main.cc
@@ -845,9 +845,15 @@
// TODO(taylori): Confirm correct format for this.
std::string FormatProcess(const Process& process) {
char line[2048];
- sprintf(line, "process: pid=%d ppid=%d cmdline=%s\\n", process.pid(),
- process.ppid(), process.cmdline(0).c_str());
+ sprintf(line, "process: pid=%d ppid=%d cmdline=", process.pid(),
+ process.ppid());
std::string output = std::string(line);
+ for (auto field : process.cmdline()) {
+ char cmd[2048];
+ sprintf(cmd, "%s ", field.c_str());
+ output += std::string(cmd);
+ }
+ output += "\\n";
for (auto thread : process.threads()) {
char thread_line[2048];
sprintf(thread_line, "thread: tid=%d name=%s\\n", thread.tid(),