Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(451)

Unified Diff: systrace/atrace_helper/jni/process_info.cc

Issue 2946033002: Android systrace: Optimize memory dumps. (Closed)
Patch Set: for review Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: systrace/atrace_helper/jni/process_info.cc
diff --git a/systrace/atrace_helper/jni/process_info.cc b/systrace/atrace_helper/jni/process_info.cc
index 172217bf6536509045593eb3a9ae9c0c2114d7dc..b5c66a8417923e9da4ebfc2684348d7e205d7af0 100644
--- a/systrace/atrace_helper/jni/process_info.cc
+++ b/systrace/atrace_helper/jni/process_info.cc
@@ -13,90 +13,179 @@
#include "file_utils.h"
#include "logging.h"
-ProcessInfo::ProcessInfo(int pid) : memory_(pid), pid_(pid) {}
+using file_utils::ForEachPidInProcPath;
+using file_utils::ReadProcFile;
+using file_utils::ReadProcFileTrimmed;
-bool ProcessInfo::IsProcess(int pid) {
- char buf[256];
- ssize_t rsize = file_utils::ReadProcFile(pid, "status", buf, sizeof(buf));
+
+namespace {
+
+const char kAppExe[] = "/system/bin/app_process";
+const char kZygote[] = "zygote";
+
+std::string ReadProcString(int pid, const char* path) {
+ char buf[512];
+ if (!file_utils::ReadProcFileTrimmed(pid, path, buf, sizeof(buf)))
+ return "";
+ return buf;
+}
+
+int ReadTgid(int pid) {
+ char buf[512];
+ ssize_t rsize = ReadProcFile(pid, "status", buf, sizeof(buf));
if (rsize <= 0)
- return false;
+ return -1;
const char kTgid[] = "\nTgid:";
const char* tgid_line = strstr(buf, kTgid);
- CHECK(tgid_line);
- int tgid = 0;
+ if (!tgid_line)
+ return -1;
+ int tgid = -1;
if (sscanf(tgid_line + strlen(kTgid), "%d", &tgid) != 1)
- CHECK(false);
- return tgid == pid;
+ return -1;
+ return tgid;
}
-bool ProcessInfo::ReadProcessName() {
- if (!file_utils::ReadProcFileTrimmed(pid_, "cmdline", name_, sizeof(name_)))
- return false;
-
- // Fallback on "comm" for kernel threads.
- if (strlen(name_) == 0) {
- if (!file_utils::ReadProcFileTrimmed(pid_, "comm", name_, sizeof(name_)))
- return false;
- }
-
- // Get also the exe path, to distinguish system vs java apps and bitness.
+std::string ReadExe(int pid) {
+ char exe[PATH_MAX];
char exe_path[64];
- sprintf(exe_path, "/proc/%d/exe", pid_);
- exe_[0] = '\0';
- ssize_t res = readlink(exe_path, exe_, sizeof(exe_) - 1);
+ sprintf(exe_path, "/proc/%d/exe", pid);
+ exe[0] = '\0';
+ ssize_t res = readlink(exe_path, exe, sizeof(exe) - 1);
if (res >= 0)
- exe_[res] = '\0';
-
- return true;
+ exe[res] = '\0';
+ return exe;
}
-bool ProcessInfo::ReadThreadNames() {
- char tasks_path[64];
- sprintf(tasks_path, "/proc/%d/task", pid_);
- CHECK(threads_.empty());
- ThreadInfoMap* threads = &threads_;
- const int pid = pid_;
- file_utils::ForEachPidInProcPath(tasks_path, [pid, threads](int tid) {
- char comm[64];
- std::unique_ptr<ThreadInfo> thread_info(new ThreadInfo());
- sprintf(comm, "task/%d/comm", tid);
- if (!file_utils::ReadProcFileTrimmed(pid, comm, thread_info->name,
- sizeof(thread_info->name))) {
- return;
- }
- (*threads)[tid] = std::move(thread_info);
- });
+bool ReadOomStats(int pid, InstantProcessInfo::ProcessSnapshot* snapshot) {
+ char buf[64];
+ if (ReadProcFileTrimmed(pid, "oom_score", buf, sizeof(buf)))
+ snapshot->oom_score = atoi(buf);
+ else
+ return false;
+ if (ReadProcFileTrimmed(pid, "oom_score_adj", buf, sizeof(buf)))
+ snapshot->oom_score_adj = atoi(buf);
+ else
+ return false;
return true;
}
-bool ProcessInfo::ReadOOMStats() {
+bool ReadPageFaultsAndCpuTimeStats(
+ int pid, InstantProcessInfo::ProcessSnapshot* snapshot) {
+
char buf[512];
- if (file_utils::ReadProcFileTrimmed(pid_, "oom_adj", buf, sizeof(buf)))
- oom_adj_ = atoi(buf);
- else
+ if (!ReadProcFileTrimmed(pid, "stat", buf, sizeof(buf)))
return false;
+ int ret = sscanf(buf,
+ "%*d (%*[^)]) %*c %*d %*d %*d %*d %*d %*u %lu %*lu %lu %*lu %lu %lu",
+ &snapshot->minor_faults, &snapshot->major_faults,
+ &snapshot->utime, &snapshot->stime);
+ CHECK(ret == 4);
+ return true;
+}
- if (file_utils::ReadProcFileTrimmed(pid_, "oom_score", buf, sizeof(buf)))
- oom_score_ = atoi(buf);
- else
- return false;
+} // namespace
- if (file_utils::ReadProcFileTrimmed(pid_, "oom_score_adj", buf, sizeof(buf)))
- oom_score_adj_ = atoi(buf);
- else
- return false;
+
+bool PersistentProcessInfo::UpdateProcessInfo(int pid) {
+ ProcessInfo* process;
+ bool first_update = false;
+
+ if (!processes_.count(pid)) {
+ if (ReadTgid(pid) != pid)
+ return false;
+ process = new ProcessInfo();
+ processes_[pid] = std::unique_ptr<ProcessInfo>(process);
+ first_update = true;
+ } else {
+ process = processes_[pid].get();
+ }
+
+ // Get process name.
+ if (first_update) {
+ process->pid = pid;
+ process->name = ReadProcString(pid, "cmdline");
+ if (process->name.empty()) {
+ process->in_kernel = true;
+ process->name = ReadProcString(pid, "comm");
+ } else {
+ process->in_kernel = false;
+ process->exe = ReadExe(pid);
+ }
+ }
+
+ // Detect apps.
+ process->is_app = !process->in_kernel &&
+ !strncmp(process->exe.c_str(), kAppExe, sizeof(kAppExe) - 1) &&
+ strncmp(process->name.c_str(), kZygote, sizeof(kZygote) - 1);
+
+ // Get thread names.
+ if (!process->in_kernel) {
+ char tasks_path[64];
+ sprintf(tasks_path, "/proc/%d/task", pid);
+ ForEachPidInProcPath(tasks_path, [process, pid](int tid) {
+ if (process->threads.count(tid))
+ return;
+ ThreadInfo* thread = new ThreadInfo();
+ process->threads[tid] = std::unique_ptr<ThreadInfo>(thread);
+
+ char task_comm[64];
+ sprintf(task_comm, "task/%d/comm", tid);
+ thread->tid = tid;
+ thread->name = ReadProcString(pid, task_comm);
+ if (process->is_app && thread->name.empty())
+ thread->name = "UI Thread";
+ });
+ }
return true;
}
-bool ProcessInfo::ReadPageFaultsAndCPUTimeStats() {
- char buf[512];
- if (!file_utils::ReadProcFileTrimmed(pid_, "stat", buf, sizeof(buf)))
- return false;
- int ret = sscanf(buf,
- "%*d (%*[^)]) %*c %*d %*d %*d %*d %*d %*u %lu %*lu "
- "%lu %*lu %lu %lu %*ld %*ld %*ld %*ld %*ld %*ld %llu",
- &minflt_, &majflt_, &utime_, &stime_, &start_time_);
- CHECK(ret == 5);
+void ProcessDumpManager::SetFullDumpPredicate(const DumpPredicate& predicate) {
+ full_dump_predicate_ =
+ std::unique_ptr<DumpPredicate>(new DumpPredicate(predicate));
+}
+
+void ProcessDumpManager::SetGraphicsDumpPredicate(
+ const DumpPredicate& predicate) {
+ graphics_dump_predicate_ =
+ std::unique_ptr<DumpPredicate>(new DumpPredicate(predicate));
+}
+
+bool ProcessDumpManager::TakeSnapshot() {
+ global_snapshot_.processes_.clear();
+ global_snapshot_.timestamp_ = GetTimestamp();
+
+ ForEachPidInProcPath("/proc", [this](int pid) {
+ if (!persistent_.UpdateProcessInfo(pid))
+ return;
+
+ const PersistentProcessInfo::ProcessInfo* process =
+ persistent_.processes_[pid].get();
+
+ // Snapshot can't be obtained for kernel workers.
+ if (process->in_kernel)
+ return;
+
+ InstantProcessInfo::ProcessSnapshot* process_snapshot =
+ new InstantProcessInfo::ProcessSnapshot();
+ global_snapshot_.processes_[pid] =
+ std::unique_ptr<InstantProcessInfo::ProcessSnapshot>(process_snapshot);
+ process_snapshot->pid = pid;
+
+ ReadOomStats(pid, process_snapshot);
+ ReadPageFaultsAndCpuTimeStats(pid, process_snapshot);
+
+ if (full_dump_predicate_ &&
+ (*full_dump_predicate_.get())(process)) {
+ process_snapshot->memory.ReadFullStats(pid);
+ } else {
+ process_snapshot->memory.ReadLightStats(pid);
+ }
+
+ if (graphics_dump_predicate_ &&
+ (*graphics_dump_predicate_.get())(process)) {
+ process_snapshot->memory.ReadGpuStats(pid);
+ }
+ });
return true;
}

Powered by Google App Engine
This is Rietveld 408576698