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

Side by Side Diff: systrace/atrace_helper/jni/atrace_process_dump.cc

Issue 2946033002: Android systrace: Optimize memory dumps. (Closed)
Patch Set: tiny fix Created 3 years, 5 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
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "atrace_process_dump.h"
6
7 #include <stdint.h>
8
9 #include "file_utils.h"
10 #include "logging.h"
11 #include "procfs_utils.h"
12
13 AtraceProcessDump::AtraceProcessDump() {
14 self_pid_ = static_cast<int>(getpid());
15 }
16
17 AtraceProcessDump::~AtraceProcessDump() {
18 }
19
20 void AtraceProcessDump::RunAndPrintJson(FILE* stream) {
21 out_ = stream;
22
23 fprintf(out_, "{\"start_ts\": \"%llu\", \"snapshots\":[\n",
24 time_utils::GetTimestamp());
25
26 CHECK(dump_timer_);
27 dump_timer_->Start();
28 for (int dump_number = 0; dump_number < dump_count_; dump_number++) {
29 if (dump_number > 0) {
30 if (!dump_timer_->Wait())
31 break; // Interrupted by signal.
32 fprintf(out_, ",\n");
33 }
34 TakeGlobalSnapshot();
35 SerializeSnapshot();
36 fflush(out_);
37 }
38 fprintf(out_, "],\n");
39 SerializePersistentProcessInfo();
40 fprintf(out_, "}\n");
41 fflush(out_);
42 Cleanup();
43 }
44
45 void AtraceProcessDump::Stop() {
46 CHECK(dump_timer_);
47 dump_timer_->Stop();
48 }
49
50 void AtraceProcessDump::TakeGlobalSnapshot() {
51 snapshot_.clear();
52 snapshot_timestamp_ = time_utils::GetTimestamp();
53
54 file_utils::ForEachPidInProcPath("/proc", [this](int pid) {
55 // Skip if not regognized as a process.
56 if (!UpdatePersistentProcessInfo(pid))
57 return;
58 const ProcessInfo* process = processes_[pid].get();
59 // Snapshot can't be obtained for kernel workers.
60 if (process->in_kernel)
61 return;
62
63 ProcessSnapshot* process_snapshot = new ProcessSnapshot();
64 snapshot_[pid] = std::unique_ptr<ProcessSnapshot>(process_snapshot);
65
66 process_snapshot->pid = pid;
67 procfs_utils::ReadOomStats(process_snapshot);
68 procfs_utils::ReadPageFaultsAndCpuTimeStats(process_snapshot);
69
70 if (ShouldTakeFullDump(process)) {
71 process_snapshot->memory.ReadFullStats(pid);
72 } else {
73 process_snapshot->memory.ReadLightStats(pid);
74 }
75 if (graphics_stats_ && process->is_app) {
76 process_snapshot->memory.ReadGpuStats(pid);
77 }
78 });
79 }
80
81 bool AtraceProcessDump::UpdatePersistentProcessInfo(int pid) {
82 if (!processes_.count(pid)) {
83 if (procfs_utils::ReadTgid(pid) != pid)
84 return false;
85 processes_[pid] = procfs_utils::ReadProcessInfo(pid);
86 }
87 ProcessInfo* process = processes_[pid].get();
88 procfs_utils::ReadProcessThreads(process);
89
90 if (full_dump_mode_ == FullDumpMode::kOnlyWhitelisted &&
91 full_dump_whitelist_.count(process->name)) {
92 full_dump_whitelisted_pids_.insert(pid);
93 }
94 return true;
95 }
96
97 bool AtraceProcessDump::ShouldTakeFullDump(const ProcessInfo* process) {
98 if (full_dump_mode_ == FullDumpMode::kAllProcesses)
99 return !process->in_kernel && (process->pid != self_pid_);
100 if (full_dump_mode_ == FullDumpMode::kAllJavaApps)
101 return process->is_app;
102 if (full_dump_mode_ == FullDumpMode::kDisabled)
103 return false;
104 return full_dump_whitelisted_pids_.count(process->pid) > 0;
105 }
106
107 void AtraceProcessDump::SerializeSnapshot() {
108 fprintf(out_, "{\"ts\":\"%llu\",\"memdump\":{\n", snapshot_timestamp_);
109 for (auto it = snapshot_.begin(); it != snapshot_.end();) {
110 const ProcessSnapshot* process = it->second.get();
111 const ProcessMemoryStats* mem = &process->memory;
112 fprintf(out_, "\"%d\":{", process->pid);
113
114 fprintf(out_, "\"vm\":%llu,\"rss\":%llu",
115 mem->virt_kb(), mem->rss_kb());
116
117 fprintf(out_, ",\"oom_sc\":%d,\"oom_sc_adj\":%d"
118 ",\"min_flt\":%lu,\"maj_flt\":%lu"
119 ",\"utime\":%lu,\"stime\":%lu",
120 process->oom_score, process->oom_score_adj,
121 process->minor_faults, process->major_faults,
122 process->utime, process->stime);
123
124 if (mem->full_stats_available()) {
125 fprintf(out_, ",\"pss\":%llu,\"swp\":%llu"
126 ",\"pc\":%llu,\"pd\":%llu,\"sc\":%llu,\"sd\":%llu",
127 mem->pss_kb(), mem->swapped_kb(),
128 mem->private_clean_kb(), mem->private_dirty_kb(),
129 mem->shared_clean_kb(), mem->shared_dirty_kb());
130 }
131
132 if (mem->gpu_stats_available()) {
133 fprintf(out_, ",\"gpu_egl\":%llu,\"gpu_egl_pss\":%llu"
134 ",\"gpu_gl\":%llu,\"gpu_gl_pss\":%llu"
135 ",\"gpu_etc\":%llu,\"gpu_etc_pss\":%llu",
136 mem->gpu_graphics_kb(), mem->gpu_graphics_pss_kb(),
137 mem->gpu_gl_kb(), mem->gpu_gl_pss_kb(),
138 mem->gpu_other_kb(), mem->gpu_other_pss_kb());
139 }
140
141 // Memory maps are too heavy to serialize. Enable only in whitelisting mode.
142 if (print_smaps_ &&
143 full_dump_mode_ == FullDumpMode::kOnlyWhitelisted &&
144 mem->full_stats_available() &&
145 full_dump_whitelisted_pids_.count(process->pid)) {
146
147 fprintf(out_, ", \"mmaps\":[");
148 size_t n_mmaps = mem->mmaps_count();
149 for (size_t k = 0; k < n_mmaps; ++k) {
150 const ProcessMemoryStats::MmapInfo* mm = mem->mmap(k);
151 fprintf(out_,
152 "{\"vm\":\"%llx-%llx\",\"file\":\"%s\",\"flags\":\"%s\","
153 "\"pss\":%llu,\"rss\":%llu,\"swp\":%llu,"
154 "\"pc\":%llu,\"pd\":%llu,"
155 "\"sc\":%llu,\"sd\":%llu}",
156 mm->start_addr, mm->end_addr, mm->mapped_file, mm->prot_flags,
157 mm->pss_kb, mm->rss_kb, mm->swapped_kb,
158 mm->private_clean_kb, mm->private_dirty_kb,
159 mm->shared_clean_kb, mm->shared_dirty_kb);
160 if (k < n_mmaps - 1)
161 fprintf(out_, ", ");
162 }
163 fprintf(out_, "]");
164 }
165
166 if (++it != snapshot_.end())
167 fprintf(out_, "},\n");
168 else
169 fprintf(out_, "}}\n");
170 }
171 fprintf(out_, "}");
172 }
173
174 void AtraceProcessDump::SerializePersistentProcessInfo() {
175 fprintf(out_, "\"processes\":{");
176 for (auto it = processes_.begin(); it != processes_.end();) {
177 const ProcessInfo* process = it->second.get();
178 fprintf(out_, "\"%d\":{", process->pid);
179 fprintf(out_, "\"name\":\"%s\"", process->name);
180
181 if (!process->in_kernel) {
182 fprintf(out_, ",\"exe\":\"%s\",", process->exe);
183 fprintf(out_, "\"threads\":{\n");
184 const auto threads = &process->threads;
185 for (auto thread_it = threads->begin(); thread_it != threads->end();) {
186 const ThreadInfo* thread = &(thread_it->second);
187 fprintf(out_, "\"%d\":{", thread->tid);
188 fprintf(out_, "\"name\":\"%s\"", thread->name);
189
190 if (++thread_it != threads->end())
191 fprintf(out_, "},\n");
192 else
193 fprintf(out_, "}\n");
194 }
195 fprintf(out_, "}");
196 }
197
198 if (++it != processes_.end())
199 fprintf(out_, "},\n");
200 else
201 fprintf(out_, "}\n");
202 }
203 fprintf(out_, "}");
204 }
205
206 void AtraceProcessDump::Cleanup() {
207 processes_.clear();
208 snapshot_.clear();
209 full_dump_whitelisted_pids_.clear();
210 dump_timer_ = nullptr;
211 }
OLDNEW
« no previous file with comments | « systrace/atrace_helper/jni/atrace_process_dump.h ('k') | systrace/atrace_helper/jni/libmemtrack_wrapper.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698