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

Side by Side 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 unified diff | Download patch
OLDNEW
1 // Copyright 2017 The Chromium Authors. All rights reserved. 1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "process_info.h" 5 #include "process_info.h"
6 6
7 #include <ctype.h> 7 #include <ctype.h>
8 #include <dirent.h> 8 #include <dirent.h>
9 #include <stdio.h> 9 #include <stdio.h>
10 #include <stdlib.h> 10 #include <stdlib.h>
11 #include <sys/types.h> 11 #include <sys/types.h>
12 12
13 #include "file_utils.h" 13 #include "file_utils.h"
14 #include "logging.h" 14 #include "logging.h"
15 15
16 ProcessInfo::ProcessInfo(int pid) : memory_(pid), pid_(pid) {} 16 using file_utils::ForEachPidInProcPath;
17 using file_utils::ReadProcFile;
18 using file_utils::ReadProcFileTrimmed;
17 19
18 bool ProcessInfo::IsProcess(int pid) { 20
19 char buf[256]; 21 namespace {
20 ssize_t rsize = file_utils::ReadProcFile(pid, "status", buf, sizeof(buf)); 22
23 const char kAppExe[] = "/system/bin/app_process";
24 const char kZygote[] = "zygote";
25
26 std::string ReadProcString(int pid, const char* path) {
27 char buf[512];
28 if (!file_utils::ReadProcFileTrimmed(pid, path, buf, sizeof(buf)))
29 return "";
30 return buf;
31 }
32
33 int ReadTgid(int pid) {
34 char buf[512];
35 ssize_t rsize = ReadProcFile(pid, "status", buf, sizeof(buf));
21 if (rsize <= 0) 36 if (rsize <= 0)
22 return false; 37 return -1;
23 const char kTgid[] = "\nTgid:"; 38 const char kTgid[] = "\nTgid:";
24 const char* tgid_line = strstr(buf, kTgid); 39 const char* tgid_line = strstr(buf, kTgid);
25 CHECK(tgid_line); 40 if (!tgid_line)
26 int tgid = 0; 41 return -1;
42 int tgid = -1;
27 if (sscanf(tgid_line + strlen(kTgid), "%d", &tgid) != 1) 43 if (sscanf(tgid_line + strlen(kTgid), "%d", &tgid) != 1)
28 CHECK(false); 44 return -1;
29 return tgid == pid; 45 return tgid;
30 } 46 }
31 47
32 bool ProcessInfo::ReadProcessName() { 48 std::string ReadExe(int pid) {
33 if (!file_utils::ReadProcFileTrimmed(pid_, "cmdline", name_, sizeof(name_))) 49 char exe[PATH_MAX];
50 char exe_path[64];
51 sprintf(exe_path, "/proc/%d/exe", pid);
52 exe[0] = '\0';
53 ssize_t res = readlink(exe_path, exe, sizeof(exe) - 1);
54 if (res >= 0)
55 exe[res] = '\0';
56 return exe;
57 }
58
59 bool ReadOomStats(int pid, InstantProcessInfo::ProcessSnapshot* snapshot) {
60 char buf[64];
61 if (ReadProcFileTrimmed(pid, "oom_score", buf, sizeof(buf)))
62 snapshot->oom_score = atoi(buf);
63 else
34 return false; 64 return false;
65 if (ReadProcFileTrimmed(pid, "oom_score_adj", buf, sizeof(buf)))
66 snapshot->oom_score_adj = atoi(buf);
67 else
68 return false;
69 return true;
70 }
35 71
36 // Fallback on "comm" for kernel threads. 72 bool ReadPageFaultsAndCpuTimeStats(
37 if (strlen(name_) == 0) { 73 int pid, InstantProcessInfo::ProcessSnapshot* snapshot) {
38 if (!file_utils::ReadProcFileTrimmed(pid_, "comm", name_, sizeof(name_))) 74
75 char buf[512];
76 if (!ReadProcFileTrimmed(pid, "stat", buf, sizeof(buf)))
77 return false;
78 int ret = sscanf(buf,
79 "%*d (%*[^)]) %*c %*d %*d %*d %*d %*d %*u %lu %*lu %lu %*lu %lu %lu",
80 &snapshot->minor_faults, &snapshot->major_faults,
81 &snapshot->utime, &snapshot->stime);
82 CHECK(ret == 4);
83 return true;
84 }
85
86 } // namespace
87
88
89 bool PersistentProcessInfo::UpdateProcessInfo(int pid) {
90 ProcessInfo* process;
91 bool first_update = false;
92
93 if (!processes_.count(pid)) {
94 if (ReadTgid(pid) != pid)
39 return false; 95 return false;
96 process = new ProcessInfo();
97 processes_[pid] = std::unique_ptr<ProcessInfo>(process);
98 first_update = true;
99 } else {
100 process = processes_[pid].get();
40 } 101 }
41 102
42 // Get also the exe path, to distinguish system vs java apps and bitness. 103 // Get process name.
43 char exe_path[64]; 104 if (first_update) {
44 sprintf(exe_path, "/proc/%d/exe", pid_); 105 process->pid = pid;
45 exe_[0] = '\0'; 106 process->name = ReadProcString(pid, "cmdline");
46 ssize_t res = readlink(exe_path, exe_, sizeof(exe_) - 1); 107 if (process->name.empty()) {
47 if (res >= 0) 108 process->in_kernel = true;
48 exe_[res] = '\0'; 109 process->name = ReadProcString(pid, "comm");
110 } else {
111 process->in_kernel = false;
112 process->exe = ReadExe(pid);
113 }
114 }
115
116 // Detect apps.
117 process->is_app = !process->in_kernel &&
118 !strncmp(process->exe.c_str(), kAppExe, sizeof(kAppExe) - 1) &&
119 strncmp(process->name.c_str(), kZygote, sizeof(kZygote) - 1);
120
121 // Get thread names.
122 if (!process->in_kernel) {
123 char tasks_path[64];
124 sprintf(tasks_path, "/proc/%d/task", pid);
125 ForEachPidInProcPath(tasks_path, [process, pid](int tid) {
126 if (process->threads.count(tid))
127 return;
128 ThreadInfo* thread = new ThreadInfo();
129 process->threads[tid] = std::unique_ptr<ThreadInfo>(thread);
130
131 char task_comm[64];
132 sprintf(task_comm, "task/%d/comm", tid);
133 thread->tid = tid;
134 thread->name = ReadProcString(pid, task_comm);
135 if (process->is_app && thread->name.empty())
136 thread->name = "UI Thread";
137 });
138 }
49 139
50 return true; 140 return true;
51 } 141 }
52 142
53 bool ProcessInfo::ReadThreadNames() { 143 void ProcessDumpManager::SetFullDumpPredicate(const DumpPredicate& predicate) {
54 char tasks_path[64]; 144 full_dump_predicate_ =
55 sprintf(tasks_path, "/proc/%d/task", pid_); 145 std::unique_ptr<DumpPredicate>(new DumpPredicate(predicate));
56 CHECK(threads_.empty()); 146 }
57 ThreadInfoMap* threads = &threads_; 147
58 const int pid = pid_; 148 void ProcessDumpManager::SetGraphicsDumpPredicate(
59 file_utils::ForEachPidInProcPath(tasks_path, [pid, threads](int tid) { 149 const DumpPredicate& predicate) {
60 char comm[64]; 150 graphics_dump_predicate_ =
61 std::unique_ptr<ThreadInfo> thread_info(new ThreadInfo()); 151 std::unique_ptr<DumpPredicate>(new DumpPredicate(predicate));
62 sprintf(comm, "task/%d/comm", tid); 152 }
63 if (!file_utils::ReadProcFileTrimmed(pid, comm, thread_info->name, 153
64 sizeof(thread_info->name))) { 154 bool ProcessDumpManager::TakeSnapshot() {
155 global_snapshot_.processes_.clear();
156 global_snapshot_.timestamp_ = GetTimestamp();
157
158 ForEachPidInProcPath("/proc", [this](int pid) {
159 if (!persistent_.UpdateProcessInfo(pid))
65 return; 160 return;
161
162 const PersistentProcessInfo::ProcessInfo* process =
163 persistent_.processes_[pid].get();
164
165 // Snapshot can't be obtained for kernel workers.
166 if (process->in_kernel)
167 return;
168
169 InstantProcessInfo::ProcessSnapshot* process_snapshot =
170 new InstantProcessInfo::ProcessSnapshot();
171 global_snapshot_.processes_[pid] =
172 std::unique_ptr<InstantProcessInfo::ProcessSnapshot>(process_snapshot);
173 process_snapshot->pid = pid;
174
175 ReadOomStats(pid, process_snapshot);
176 ReadPageFaultsAndCpuTimeStats(pid, process_snapshot);
177
178 if (full_dump_predicate_ &&
179 (*full_dump_predicate_.get())(process)) {
180 process_snapshot->memory.ReadFullStats(pid);
181 } else {
182 process_snapshot->memory.ReadLightStats(pid);
66 } 183 }
67 (*threads)[tid] = std::move(thread_info); 184
185 if (graphics_dump_predicate_ &&
186 (*graphics_dump_predicate_.get())(process)) {
187 process_snapshot->memory.ReadGpuStats(pid);
188 }
68 }); 189 });
69 return true; 190 return true;
70 } 191 }
71
72 bool ProcessInfo::ReadOOMStats() {
73 char buf[512];
74 if (file_utils::ReadProcFileTrimmed(pid_, "oom_adj", buf, sizeof(buf)))
75 oom_adj_ = atoi(buf);
76 else
77 return false;
78
79 if (file_utils::ReadProcFileTrimmed(pid_, "oom_score", buf, sizeof(buf)))
80 oom_score_ = atoi(buf);
81 else
82 return false;
83
84 if (file_utils::ReadProcFileTrimmed(pid_, "oom_score_adj", buf, sizeof(buf)))
85 oom_score_adj_ = atoi(buf);
86 else
87 return false;
88
89 return true;
90 }
91
92 bool ProcessInfo::ReadPageFaultsAndCPUTimeStats() {
93 char buf[512];
94 if (!file_utils::ReadProcFileTrimmed(pid_, "stat", buf, sizeof(buf)))
95 return false;
96 int ret = sscanf(buf,
97 "%*d (%*[^)]) %*c %*d %*d %*d %*d %*d %*u %lu %*lu "
98 "%lu %*lu %lu %lu %*ld %*ld %*ld %*ld %*ld %*ld %llu",
99 &minflt_, &majflt_, &utime_, &stime_, &start_time_);
100 CHECK(ret == 5);
101 return true;
102 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698