OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 |
11 #include "base/command_line.h" | 11 #include "base/command_line.h" |
12 #include "base/files/file_path.h" | 12 #include "base/files/file_path.h" |
13 #include "base/logging.h" | 13 #include "base/logging.h" |
| 14 #include "base/mac/mac_util.h" |
14 #include "base/process/launch.h" | 15 #include "base/process/launch.h" |
15 #include "base/strings/string_number_conversions.h" | 16 #include "base/strings/string_number_conversions.h" |
16 #include "base/strings/string_util.h" | 17 #include "base/strings/string_util.h" |
17 #include "base/threading/thread.h" | 18 #include "base/threading/thread.h" |
18 | 19 |
19 // Default constructor. | 20 // Default constructor. |
20 ProcessInfoSnapshot::ProcessInfoSnapshot() { } | 21 ProcessInfoSnapshot::ProcessInfoSnapshot() { } |
21 | 22 |
22 // Destructor: just call |Reset()| to release everything. | 23 // Destructor: just call |Reset()| to release everything. |
23 ProcessInfoSnapshot::~ProcessInfoSnapshot() { | 24 ProcessInfoSnapshot::~ProcessInfoSnapshot() { |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
160 in >> pid; | 161 in >> pid; |
161 if (in.eof()) | 162 if (in.eof()) |
162 break; | 163 break; |
163 | 164 |
164 ProcessInfoSnapshot::ProcInfoEntry proc_info = proc_info_entries[pid]; | 165 ProcessInfoSnapshot::ProcInfoEntry proc_info = proc_info_entries[pid]; |
165 proc_info.pid = pid; | 166 proc_info.pid = pid; |
166 in >> proc_info.rss; | 167 in >> proc_info.rss; |
167 in >> proc_info.vsize; | 168 in >> proc_info.vsize; |
168 proc_info.rss *= 1024; // Convert from kilobytes to bytes. | 169 proc_info.rss *= 1024; // Convert from kilobytes to bytes. |
169 proc_info.vsize *= 1024; | 170 proc_info.vsize *= 1024; |
170 in.ignore(1, ' '); // Eat the space. | 171 |
171 std::getline(in, proc_info.command); // Get the rest of the line. | 172 // If the fail or bad bits were set, then there was an error reading input. |
172 if (!in.good()) { | 173 if (in.fail()) { |
173 LOG(ERROR) << "Error parsing output from " << kProgram.value() << "."; | 174 LOG(ERROR) << "Error parsing output from " << kProgram.value() << "."; |
174 return false; | 175 return false; |
175 } | 176 } |
176 | 177 |
177 if (!proc_info.pid || ! proc_info.vsize) { | 178 if (!proc_info.pid || ! proc_info.vsize) { |
178 LOG(WARNING) << "Invalid data from " << kProgram.value() << "."; | 179 LOG(WARNING) << "Invalid data from " << kProgram.value() << "."; |
179 return false; | 180 return false; |
180 } | 181 } |
181 | 182 |
182 // Record the process information. | 183 // Record the process information. |
183 proc_info_entries[proc_info.pid] = proc_info; | 184 proc_info_entries[proc_info.pid] = proc_info; |
| 185 |
| 186 // Ignore the rest of the line. |
| 187 in.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); |
184 } | 188 } |
185 | 189 |
186 return true; | 190 return true; |
187 } | 191 } |
188 | 192 |
189 static bool GetProcessMemoryInfoUsingTop( | 193 static bool GetProcessMemoryInfoUsingTop( |
190 std::map<int,ProcessInfoSnapshot::ProcInfoEntry>& proc_info_entries) { | 194 std::map<int,ProcessInfoSnapshot::ProcInfoEntry>& proc_info_entries) { |
191 const base::FilePath kProgram("/usr/bin/top"); | 195 const base::FilePath kProgram("/usr/bin/top"); |
192 CommandLine command_line(kProgram); | 196 CommandLine command_line(kProgram); |
193 | 197 |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
302 // process doesn't have privileges to inspect the target process. | 306 // process doesn't have privileges to inspect the target process. |
303 for (std::vector<base::ProcessId>::iterator it = pid_list.begin(); | 307 for (std::vector<base::ProcessId>::iterator it = pid_list.begin(); |
304 it != pid_list.end(); ++it) { | 308 it != pid_list.end(); ++it) { |
305 std::string exectuable_name; | 309 std::string exectuable_name; |
306 if (GetExecutableNameForProcessID(*it, &exectuable_name)) { | 310 if (GetExecutableNameForProcessID(*it, &exectuable_name)) { |
307 ProcInfoEntry proc_info = proc_info_entries_[*it]; | 311 ProcInfoEntry proc_info = proc_info_entries_[*it]; |
308 proc_info.command = exectuable_name; | 312 proc_info.command = exectuable_name; |
309 } | 313 } |
310 } | 314 } |
311 | 315 |
| 316 // In OSX 10.9+, top no longer returns any useful information. 'rshrd' is no |
| 317 // longer supported, and 'rprvt' and 'vsize' return N/A. 'rsize' still works, |
| 318 // but the information is also available from ps. |
| 319 // http://crbug.com/383553 |
| 320 if (base::mac::IsOSMavericksOrLater()) |
| 321 return GetProcessMemoryInfoUsingPS(pid_list, proc_info_entries_); |
| 322 |
312 // Get memory information using top. | 323 // Get memory information using top. |
313 bool memory_info_success = GetProcessMemoryInfoUsingTop(proc_info_entries_); | 324 bool memory_info_success = GetProcessMemoryInfoUsingTop(proc_info_entries_); |
314 | 325 |
315 // If top didn't work then fall back to ps. | 326 // If top didn't work then fall back to ps. |
316 if (!memory_info_success) { | 327 if (!memory_info_success) { |
317 memory_info_success = GetProcessMemoryInfoUsingPS(pid_list, | 328 memory_info_success = GetProcessMemoryInfoUsingPS(pid_list, |
318 proc_info_entries_); | 329 proc_info_entries_); |
319 } | 330 } |
320 | 331 |
321 return memory_info_success; | 332 return memory_info_success; |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
387 ws_usage->shareable = 0; | 398 ws_usage->shareable = 0; |
388 ws_usage->shared = 0; | 399 ws_usage->shared = 0; |
389 return false; | 400 return false; |
390 } | 401 } |
391 | 402 |
392 ws_usage->priv = proc_info.rprvt / 1024; | 403 ws_usage->priv = proc_info.rprvt / 1024; |
393 ws_usage->shareable = proc_info.rss / 1024; | 404 ws_usage->shareable = proc_info.rss / 1024; |
394 ws_usage->shared = proc_info.rshrd / 1024; | 405 ws_usage->shared = proc_info.rshrd / 1024; |
395 return true; | 406 return true; |
396 } | 407 } |
OLD | NEW |