OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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 "chrome/browser/process_info_snapshot.h" | 5 #include "chrome/browser/process_info_snapshot.h" |
6 | 6 |
7 #include <sys/sysctl.h> | 7 #include <sys/sysctl.h> |
8 | 8 |
9 #include <sstream> | 9 #include <sstream> |
10 | 10 |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
120 | 120 |
121 return true; | 121 return true; |
122 } | 122 } |
123 | 123 |
124 // Capture the information by calling '/bin/ps'. | 124 // Capture the information by calling '/bin/ps'. |
125 // Note: we ignore the "tsiz" (text size) display option of ps because it's | 125 // Note: we ignore the "tsiz" (text size) display option of ps because it's |
126 // always zero (tested on 10.5 and 10.6). | 126 // always zero (tested on 10.5 and 10.6). |
127 static bool GetProcessMemoryInfoUsingPS( | 127 static bool GetProcessMemoryInfoUsingPS( |
128 const std::vector<base::ProcessId>& pid_list, | 128 const std::vector<base::ProcessId>& pid_list, |
129 std::map<int,ProcessInfoSnapshot::ProcInfoEntry>& proc_info_entries) { | 129 std::map<int,ProcessInfoSnapshot::ProcInfoEntry>& proc_info_entries) { |
130 const char kPsPathName[] = "/bin/ps"; | 130 const FilePath kProgram("/bin/ps"); |
131 std::vector<std::string> argv; | 131 CommandLine command_line(kProgram); |
132 argv.push_back(kPsPathName); | |
133 | 132 |
134 // Get resident set size, virtual memory size. | 133 // Get resident set size, virtual memory size. |
135 argv.push_back("-o"); | 134 command_line.AppendArg("-o"); |
136 argv.push_back("pid=,rss=,vsz="); | 135 command_line.AppendArg("pid=,rss=,vsz="); |
137 // Only display the specified PIDs. | 136 // Only display the specified PIDs. |
138 for (std::vector<base::ProcessId>::const_iterator it = pid_list.begin(); | 137 for (std::vector<base::ProcessId>::const_iterator it = pid_list.begin(); |
139 it != pid_list.end(); ++it) { | 138 it != pid_list.end(); ++it) { |
140 argv.push_back("-p"); | 139 command_line.AppendArg("-p"); |
141 argv.push_back(base::Int64ToString(static_cast<int64>(*it))); | 140 command_line.AppendArg(base::Int64ToString(static_cast<int64>(*it))); |
142 } | 141 } |
143 | 142 |
144 std::string output; | 143 std::string output; |
145 CommandLine command_line(argv); | |
146 // Limit output read to a megabyte for safety. | 144 // Limit output read to a megabyte for safety. |
147 if (!base::GetAppOutputRestricted(command_line, &output, 1024 * 1024)) { | 145 if (!base::GetAppOutputRestricted(command_line, &output, 1024 * 1024)) { |
148 LOG(ERROR) << "Failure running " << kPsPathName << " to acquire data."; | 146 LOG(ERROR) << "Failure running " << kProgram.value() << " to acquire data."; |
149 return false; | 147 return false; |
150 } | 148 } |
151 | 149 |
152 std::istringstream in(output, std::istringstream::in); | 150 std::istringstream in(output, std::istringstream::in); |
153 std::string line; | 151 std::string line; |
154 | 152 |
155 // Process lines until done. | 153 // Process lines until done. |
156 while (true) { | 154 while (true) { |
157 // The format is as specified above to ps (see ps(1)): | 155 // The format is as specified above to ps (see ps(1)): |
158 // "-o pid=,rss=,vsz=". | 156 // "-o pid=,rss=,vsz=". |
159 // Try to read the PID; if we get it, we should be able to get the rest of | 157 // Try to read the PID; if we get it, we should be able to get the rest of |
160 // the line. | 158 // the line. |
161 pid_t pid; | 159 pid_t pid; |
162 in >> pid; | 160 in >> pid; |
163 if (in.eof()) | 161 if (in.eof()) |
164 break; | 162 break; |
165 | 163 |
166 ProcessInfoSnapshot::ProcInfoEntry proc_info = proc_info_entries[pid]; | 164 ProcessInfoSnapshot::ProcInfoEntry proc_info = proc_info_entries[pid]; |
167 proc_info.pid = pid; | 165 proc_info.pid = pid; |
168 in >> proc_info.rss; | 166 in >> proc_info.rss; |
169 in >> proc_info.vsize; | 167 in >> proc_info.vsize; |
170 proc_info.rss *= 1024; // Convert from kilobytes to bytes. | 168 proc_info.rss *= 1024; // Convert from kilobytes to bytes. |
171 proc_info.vsize *= 1024; | 169 proc_info.vsize *= 1024; |
172 in.ignore(1, ' '); // Eat the space. | 170 in.ignore(1, ' '); // Eat the space. |
173 std::getline(in, proc_info.command); // Get the rest of the line. | 171 std::getline(in, proc_info.command); // Get the rest of the line. |
174 if (!in.good()) { | 172 if (!in.good()) { |
175 LOG(ERROR) << "Error parsing output from " << kPsPathName << "."; | 173 LOG(ERROR) << "Error parsing output from " << kProgram.value() << "."; |
176 return false; | 174 return false; |
177 } | 175 } |
178 | 176 |
179 if (!proc_info.pid || ! proc_info.vsize) { | 177 if (!proc_info.pid || ! proc_info.vsize) { |
180 LOG(WARNING) << "Invalid data from " << kPsPathName << "."; | 178 LOG(WARNING) << "Invalid data from " << kProgram.value() << "."; |
181 return false; | 179 return false; |
182 } | 180 } |
183 | 181 |
184 // Record the process information. | 182 // Record the process information. |
185 proc_info_entries[proc_info.pid] = proc_info; | 183 proc_info_entries[proc_info.pid] = proc_info; |
186 } | 184 } |
187 | 185 |
188 return true; | 186 return true; |
189 } | 187 } |
190 | 188 |
191 static bool GetProcessMemoryInfoUsingTop( | 189 static bool GetProcessMemoryInfoUsingTop( |
192 std::map<int,ProcessInfoSnapshot::ProcInfoEntry>& proc_info_entries) { | 190 std::map<int,ProcessInfoSnapshot::ProcInfoEntry>& proc_info_entries) { |
193 const char kTopPathName[] = "/usr/bin/top"; | 191 const FilePath kProgram("/usr/bin/top"); |
194 std::vector<std::string> argv; | 192 CommandLine command_line(kProgram); |
195 argv.push_back(kTopPathName); | |
196 | 193 |
197 // -stats tells top to print just the given fields as ordered. | 194 // -stats tells top to print just the given fields as ordered. |
198 argv.push_back("-stats"); | 195 command_line.AppendArg("-stats"); |
199 argv.push_back("pid," // Process ID | 196 command_line.AppendArg("pid," // Process ID |
200 "rsize," // Resident memory | 197 "rsize," // Resident memory |
201 "rshrd," // Resident shared memory | 198 "rshrd," // Resident shared memory |
202 "rprvt," // Resident private memory | 199 "rprvt," // Resident private memory |
203 "vsize"); // Total virtual memory | 200 "vsize"); // Total virtual memory |
204 // Run top in logging (non-interactive) mode. | 201 // Run top in logging (non-interactive) mode. |
205 argv.push_back("-l"); | 202 command_line.AppendArg("-l"); |
206 argv.push_back("1"); | 203 command_line.AppendArg("1"); |
207 // Set the delay between updates to 0. | 204 // Set the delay between updates to 0. |
208 argv.push_back("-s"); | 205 command_line.AppendArg("-s"); |
209 argv.push_back("0"); | 206 command_line.AppendArg("0"); |
210 | 207 |
211 std::string output; | 208 std::string output; |
212 CommandLine command_line(argv); | |
213 // Limit output read to a megabyte for safety. | 209 // Limit output read to a megabyte for safety. |
214 if (!base::GetAppOutputRestricted(command_line, &output, 1024 * 1024)) { | 210 if (!base::GetAppOutputRestricted(command_line, &output, 1024 * 1024)) { |
215 LOG(ERROR) << "Failure running " << kTopPathName << " to acquire data."; | 211 LOG(ERROR) << "Failure running " << kProgram.value() << " to acquire data."; |
216 return false; | 212 return false; |
217 } | 213 } |
218 | 214 |
219 // Process lines until done. Lines should look something like this: | 215 // Process lines until done. Lines should look something like this: |
220 // PID RSIZE RSHRD RPRVT VSIZE | 216 // PID RSIZE RSHRD RPRVT VSIZE |
221 // 58539 1276K+ 336K+ 740K+ 2378M+ | 217 // 58539 1276K+ 336K+ 740K+ 2378M+ |
222 // 58485 1888K+ 592K+ 1332K+ 2383M+ | 218 // 58485 1888K+ 592K+ 1332K+ 2383M+ |
223 std::istringstream top_in(output, std::istringstream::in); | 219 std::istringstream top_in(output, std::istringstream::in); |
224 std::string line; | 220 std::string line; |
225 while (std::getline(top_in, line)) { | 221 while (std::getline(top_in, line)) { |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
267 proc_info.vsize = values[3]; | 263 proc_info.vsize = values[3]; |
268 // Record the process information. | 264 // Record the process information. |
269 proc_info_entries[proc_info.pid] = proc_info; | 265 proc_info_entries[proc_info.pid] = proc_info; |
270 } | 266 } |
271 | 267 |
272 return true; | 268 return true; |
273 } | 269 } |
274 | 270 |
275 static bool GetProcessMemoryInfoUsingTop_10_5( | 271 static bool GetProcessMemoryInfoUsingTop_10_5( |
276 std::map<int,ProcessInfoSnapshot::ProcInfoEntry>& proc_info_entries) { | 272 std::map<int,ProcessInfoSnapshot::ProcInfoEntry>& proc_info_entries) { |
277 const char kTopPathName[] = "/usr/bin/top"; | 273 const FilePath kProgram("/usr/bin/top"); |
278 std::vector<std::string> argv; | 274 CommandLine command_line(kProgram); |
279 argv.push_back(kTopPathName); | |
280 | 275 |
281 // -p tells top to print just the given fields as ordered. | 276 // -p tells top to print just the given fields as ordered. |
282 argv.push_back("-p"); | 277 command_line.AppendArg("-p"); |
283 argv.push_back("^aaaaaaaaaaaaaaaaaaaa " // Process ID (PID) | 278 command_line.AppendArg( |
284 "^jjjjjjjjjjjjjjjjjjjj " // Resident memory (RSIZE) | 279 "^aaaaaaaaaaaaaaaaaaaa " // Process ID (PID) |
285 "^iiiiiiiiiiiiiiiiiiii " // Resident shared memory (RSHRD) | 280 "^jjjjjjjjjjjjjjjjjjjj " // Resident memory (RSIZE) |
286 "^hhhhhhhhhhhhhhhhhhhh " // Resident private memory (RPRVT) | 281 "^iiiiiiiiiiiiiiiiiiii " // Resident shared memory (RSHRD) |
287 "^llllllllllllllllllll"); // Total virtual memory (VSIZE) | 282 "^hhhhhhhhhhhhhhhhhhhh " // Resident private memory (RPRVT) |
| 283 "^llllllllllllllllllll"); // Total virtual memory (VSIZE) |
288 // Run top in logging (non-interactive) mode. | 284 // Run top in logging (non-interactive) mode. |
289 argv.push_back("-l"); | 285 command_line.AppendArg("-l"); |
290 argv.push_back("1"); | 286 command_line.AppendArg("1"); |
291 // Set the delay between updates to 0. | 287 // Set the delay between updates to 0. |
292 argv.push_back("-s"); | 288 command_line.AppendArg("-s"); |
293 argv.push_back("0"); | 289 command_line.AppendArg("0"); |
294 | 290 |
295 std::string output; | 291 std::string output; |
296 CommandLine command_line(argv); | |
297 // Limit output read to a megabyte for safety. | 292 // Limit output read to a megabyte for safety. |
298 if (!base::GetAppOutputRestricted(command_line, &output, 1024 * 1024)) { | 293 if (!base::GetAppOutputRestricted(command_line, &output, 1024 * 1024)) { |
299 LOG(ERROR) << "Failure running " << kTopPathName << " to acquire data."; | 294 LOG(ERROR) << "Failure running " << kProgram.value() << " to acquire data."; |
300 return false; | 295 return false; |
301 } | 296 } |
302 | 297 |
303 // Process lines until done. Lines should look something like this: | 298 // Process lines until done. Lines should look something like this: |
304 // PID RSIZE RSHRD RPRVT VSIZE | 299 // PID RSIZE RSHRD RPRVT VSIZE |
305 // 16943 815104 262144 290816 18489344 | 300 // 16943 815104 262144 290816 18489344 |
306 // 16922 954368 720896 278528 18976768 | 301 // 16922 954368 720896 278528 18976768 |
307 std::istringstream top_in(output, std::istringstream::in); | 302 std::istringstream top_in(output, std::istringstream::in); |
308 std::string line; | 303 std::string line; |
309 while (std::getline(top_in, line)) { | 304 while (std::getline(top_in, line)) { |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
456 ws_usage->shareable = 0; | 451 ws_usage->shareable = 0; |
457 ws_usage->shared = 0; | 452 ws_usage->shared = 0; |
458 return false; | 453 return false; |
459 } | 454 } |
460 | 455 |
461 ws_usage->priv = proc_info.rprvt / 1024; | 456 ws_usage->priv = proc_info.rprvt / 1024; |
462 ws_usage->shareable = proc_info.rss / 1024; | 457 ws_usage->shareable = proc_info.rss / 1024; |
463 ws_usage->shared = proc_info.rshrd / 1024; | 458 ws_usage->shared = proc_info.rshrd / 1024; |
464 return true; | 459 return true; |
465 } | 460 } |
OLD | NEW |