1c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Copyright (c) 2009 The Chromium Authors. All rights reserved. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file. 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/process_info_snapshot.h" 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include <sys/sysctl.h> 872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <sstream> 10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/command_line.h" 12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/logging.h" 133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/string_number_conversions.h" 14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/string_util.h" 1572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "base/sys_info.h" 163f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/threading/thread.h" 17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Default constructor. 19c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochProcessInfoSnapshot::ProcessInfoSnapshot() { } 20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Destructor: just call |Reset()| to release everything. 22c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochProcessInfoSnapshot::~ProcessInfoSnapshot() { 23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Reset(); 24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst size_t ProcessInfoSnapshot::kMaxPidListSize = 1000; 27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenstatic bool GetKInfoForProcessID(pid_t pid, kinfo_proc* kinfo) { 2972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, pid}; 3072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen size_t len = sizeof(*kinfo); 3172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (sysctl(mib, arraysize(mib), kinfo, &len, NULL, 0) != 0) { 3272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen PLOG(ERROR) << "sysctl() for KERN_PROC"; 3372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return false; 3472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (len == 0) { 3772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // If the process isn't found then sysctl returns a length of 0. 3872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return false; 3972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 4072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 4172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return true; 4272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 4372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 4472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenstatic bool GetExecutableNameForProcessID( 4572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen pid_t pid, 4672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen std::string* executable_name) { 4772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!executable_name) { 48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NOTREACHED(); 49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen static int s_arg_max = 0; 5372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (s_arg_max == 0) { 5472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen int mib[] = {CTL_KERN, KERN_ARGMAX}; 5572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen size_t size = sizeof(s_arg_max); 5672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (sysctl(mib, arraysize(mib), &s_arg_max, &size, NULL, 0) != 0) 5772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen PLOG(ERROR) << "sysctl() for KERN_ARGMAX"; 5872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 5972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 6072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (s_arg_max == 0) 6172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return false; 6272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 6372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen int mib[] = {CTL_KERN, KERN_PROCARGS, pid}; 6472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen size_t size = s_arg_max; 6572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen executable_name->resize(s_arg_max + 1); 6672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (sysctl(mib, arraysize(mib), &(*executable_name)[0], 6772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen &size, NULL, 0) != 0) { 6872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Don't log the error since it's normal for this to fail. 6972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return false; 7072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 7172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 7272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // KERN_PROCARGS returns multiple NULL terminated strings. Truncate 7372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // executable_name to just the first string. 7472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen size_t end_pos = executable_name->find('\0'); 7572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (end_pos == std::string::npos) { 7672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return false; 7772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 7872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 7972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen executable_name->resize(end_pos); 8072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return true; 8172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 8272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 8372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Converts a byte unit such as 'K' or 'M' into the scale for the unit. 8472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// The scale can then be used to calculate the number of bytes in a value. 8572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// The units are based on humanize_number(). See: 8672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// http://www.opensource.apple.com/source/libutil/libutil-21/humanize_number.c 8772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenstatic bool ConvertByteUnitToScale(char unit, uint64_t* out_scale) { 8872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen int shift = 0; 8972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen switch (unit) { 9072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen case 'B': 9172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen shift = 0; 9272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen break; 9372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen case 'K': 9472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen case 'k': 9572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen shift = 1; 9672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen break; 9772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen case 'M': 9872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen shift = 2; 9972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen break; 10072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen case 'G': 10172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen shift = 3; 10272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen break; 10372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen case 'T': 10472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen shift = 4; 10572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen break; 10672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen case 'P': 10772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen shift = 5; 10872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen break; 10972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen case 'E': 11072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen shift = 6; 11172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen break; 11272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen default: 11372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return false; 11472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 11572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 11672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen uint64_t scale = 1; 11772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen for (int i = 0; i < shift; i++) 11872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scale *= 1024; 11972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen *out_scale = scale; 12072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 12172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return true; 12272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 12372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 12472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Capture the information by calling '/bin/ps'. 12572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Note: we ignore the "tsiz" (text size) display option of ps because it's 12672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// always zero (tested on 10.5 and 10.6). 12772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenstatic bool GetProcessMemoryInfoUsingPS( 12872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const std::vector<base::ProcessId>& pid_list, 12972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen std::map<int,ProcessInfoSnapshot::ProcInfoEntry>& proc_info_entries) { 13072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const char kPsPathName[] = "/bin/ps"; 131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<std::string> argv; 132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch argv.push_back(kPsPathName); 13372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 13472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Get resident set size, virtual memory size. 135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch argv.push_back("-o"); 13672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen argv.push_back("pid=,rss=,vsz="); 137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Only display the specified PIDs. 13872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen for (std::vector<base::ProcessId>::const_iterator it = pid_list.begin(); 139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch it != pid_list.end(); ++it) { 140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch argv.push_back("-p"); 1413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick argv.push_back(base::Int64ToString(static_cast<int64>(*it))); 142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string output; 145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CommandLine command_line(argv); 146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Limit output read to a megabyte for safety. 147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!base::GetAppOutputRestricted(command_line, &output, 1024 * 1024)) { 148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch LOG(ERROR) << "Failure running " << kPsPathName << " to acquire data."; 149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::istringstream in(output, std::istringstream::in); 153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string line; 154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Process lines until done. 156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch while (true) { 157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The format is as specified above to ps (see ps(1)): 15872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // "-o pid=,rss=,vsz=". 159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Try to read the PID; if we get it, we should be able to get the rest of 160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // the line. 16172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen pid_t pid; 16272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen in >> pid; 163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (in.eof()) 164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 16572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 16672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ProcessInfoSnapshot::ProcInfoEntry proc_info = proc_info_entries[pid]; 16772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen proc_info.pid = pid; 168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch in >> proc_info.rss; 169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch in >> proc_info.vsize; 17072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen proc_info.rss *= 1024; // Convert from kilobytes to bytes. 17172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen proc_info.vsize *= 1024; 172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch in.ignore(1, ' '); // Eat the space. 173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::getline(in, proc_info.command); // Get the rest of the line. 174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!in.good()) { 175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch LOG(ERROR) << "Error parsing output from " << kPsPathName << "."; 176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!proc_info.pid || ! proc_info.vsize) { 180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch LOG(WARNING) << "Invalid data from " << kPsPathName << "."; 181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Record the process information. 18572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen proc_info_entries[proc_info.pid] = proc_info; 18672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 18772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 18872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return true; 18972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 19072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 19172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenstatic bool GetProcessMemoryInfoUsingTop( 19272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen std::map<int,ProcessInfoSnapshot::ProcInfoEntry>& proc_info_entries) { 19372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const char kTopPathName[] = "/usr/bin/top"; 19472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen std::vector<std::string> argv; 19572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen argv.push_back(kTopPathName); 19672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 19772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // -stats tells top to print just the given fields as ordered. 19872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen argv.push_back("-stats"); 19972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen argv.push_back("pid," // Process ID 20072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen "rsize," // Resident memory 20172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen "rshrd," // Resident shared memory 20272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen "rprvt," // Resident private memory 20372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen "vsize"); // Total virtual memory 20472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Run top in logging (non-interactive) mode. 20572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen argv.push_back("-l"); 20672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen argv.push_back("1"); 20772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Set the delay between updates to 0. 20872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen argv.push_back("-s"); 20972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen argv.push_back("0"); 21072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 21172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen std::string output; 21272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen CommandLine command_line(argv); 21372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Limit output read to a megabyte for safety. 21472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!base::GetAppOutputRestricted(command_line, &output, 1024 * 1024)) { 21572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen LOG(ERROR) << "Failure running " << kTopPathName << " to acquire data."; 21672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return false; 21772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 21872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 21972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Process lines until done. Lines should look something like this: 22072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // PID RSIZE RSHRD RPRVT VSIZE 22172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // 58539 1276K+ 336K+ 740K+ 2378M+ 22272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // 58485 1888K+ 592K+ 1332K+ 2383M+ 22372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen std::istringstream top_in(output, std::istringstream::in); 22472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen std::string line; 22572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen while (std::getline(top_in, line)) { 22672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen std::istringstream in(line, std::istringstream::in); 22772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 22872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Try to read the PID. 22972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen pid_t pid; 23072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen in >> pid; 23172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (in.fail()) 23272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen continue; 23372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 23472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Make sure that caller is interested in this process. 23572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (proc_info_entries.find(pid) == proc_info_entries.end()) 23672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen continue; 23772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 23872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Skip the - or + sign that top puts after the pid. 23972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen in.get(); 24072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 24172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen uint64_t values[4]; 24272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen size_t i; 24372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen for (i = 0; i < arraysize(values); i++) { 24472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen in >> values[i]; 24572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (in.fail()) 24672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen break; 24772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen std::string unit; 24872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen in >> unit; 24972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (in.fail()) 25072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen break; 25172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 252dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (unit.empty()) 25372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen break; 25472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 25572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen uint64_t scale; 25672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!ConvertByteUnitToScale(unit[0], &scale)) 25772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen break; 25872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen values[i] *= scale; 25972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 26072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (i != arraysize(values)) 26172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen continue; 26272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 26372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ProcessInfoSnapshot::ProcInfoEntry proc_info = proc_info_entries[pid]; 26472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen proc_info.rss = values[0]; 26572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen proc_info.rshrd = values[1]; 26672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen proc_info.rprvt = values[2]; 26772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen proc_info.vsize = values[3]; 26872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Record the process information. 26972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen proc_info_entries[proc_info.pid] = proc_info; 270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 27572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenstatic bool GetProcessMemoryInfoUsingTop_10_5( 27672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen std::map<int,ProcessInfoSnapshot::ProcInfoEntry>& proc_info_entries) { 27772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const char kTopPathName[] = "/usr/bin/top"; 27872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen std::vector<std::string> argv; 27972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen argv.push_back(kTopPathName); 28072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 28172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // -p tells top to print just the given fields as ordered. 28272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen argv.push_back("-p"); 28372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen argv.push_back("^aaaaaaaaaaaaaaaaaaaa " // Process ID (PID) 28472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen "^jjjjjjjjjjjjjjjjjjjj " // Resident memory (RSIZE) 28572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen "^iiiiiiiiiiiiiiiiiiii " // Resident shared memory (RSHRD) 28672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen "^hhhhhhhhhhhhhhhhhhhh " // Resident private memory (RPRVT) 28772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen "^llllllllllllllllllll"); // Total virtual memory (VSIZE) 28872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Run top in logging (non-interactive) mode. 28972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen argv.push_back("-l"); 29072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen argv.push_back("1"); 29172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Set the delay between updates to 0. 29272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen argv.push_back("-s"); 29372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen argv.push_back("0"); 29472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 29572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen std::string output; 29672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen CommandLine command_line(argv); 29772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Limit output read to a megabyte for safety. 29872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!base::GetAppOutputRestricted(command_line, &output, 1024 * 1024)) { 29972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen LOG(ERROR) << "Failure running " << kTopPathName << " to acquire data."; 30072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return false; 30172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 30272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 30372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Process lines until done. Lines should look something like this: 30472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // PID RSIZE RSHRD RPRVT VSIZE 30572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // 16943 815104 262144 290816 18489344 30672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // 16922 954368 720896 278528 18976768 30772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen std::istringstream top_in(output, std::istringstream::in); 30872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen std::string line; 30972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen while (std::getline(top_in, line)) { 31072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen std::istringstream in(line, std::istringstream::in); 31172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 31272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Try to read the PID. 31372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen pid_t pid; 31472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen in >> pid; 31572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (in.fail()) 31672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen continue; 31772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 31872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Make sure that caller is interested in this process. 31972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (proc_info_entries.find(pid) == proc_info_entries.end()) 32072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen continue; 32172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 32272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen uint64_t values[4]; 32372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen size_t i; 32472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen for (i = 0; i < arraysize(values); i++) { 32572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen in >> values[i]; 32672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (in.fail()) 32772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen break; 32872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 32972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (i != arraysize(values)) 33072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen continue; 33172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 33272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ProcessInfoSnapshot::ProcInfoEntry proc_info = proc_info_entries[pid]; 33372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen proc_info.rss = values[0]; 33472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen proc_info.rshrd = values[1]; 33572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen proc_info.rprvt = values[2]; 33672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen proc_info.vsize = values[3]; 33772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Record the process information. 33872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen proc_info_entries[proc_info.pid] = proc_info; 33972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 34072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 34172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return true; 34272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 34372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 34472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 34572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenbool ProcessInfoSnapshot::Sample(std::vector<base::ProcessId> pid_list) { 34672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen Reset(); 34772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 34872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Nothing to do if no PIDs given. 349dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (pid_list.empty()) 35072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return true; 35172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (pid_list.size() > kMaxPidListSize) { 35272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // The spec says |pid_list| *must* not have more than this many entries. 35372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen NOTREACHED(); 35472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return false; 35572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 35672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 35772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Get basic process info from KERN_PROC. 35872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen for (std::vector<base::ProcessId>::iterator it = pid_list.begin(); 35972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen it != pid_list.end(); ++it) { 36072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ProcInfoEntry proc_info; 36172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen proc_info.pid = *it; 36272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 36372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen kinfo_proc kinfo; 36472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!GetKInfoForProcessID(*it, &kinfo)) 36572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return false; 36672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 36772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen proc_info.ppid = kinfo.kp_eproc.e_ppid; 36872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen proc_info.uid = kinfo.kp_eproc.e_pcred.p_ruid; 36972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen proc_info.euid = kinfo.kp_eproc.e_ucred.cr_uid; 37072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Note, p_comm is truncated to 16 characters. 37172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen proc_info.command = kinfo.kp_proc.p_comm; 37272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen proc_info_entries_[*it] = proc_info; 37372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 37472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 37572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Use KERN_PROCARGS to get the full executable name. This may fail if this 37672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // process doesn't have privileges to inspect the target process. 37772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen for (std::vector<base::ProcessId>::iterator it = pid_list.begin(); 37872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen it != pid_list.end(); ++it) { 37972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen std::string exectuable_name; 38072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (GetExecutableNameForProcessID(*it, &exectuable_name)) { 38172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ProcInfoEntry proc_info = proc_info_entries_[*it]; 38272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen proc_info.command = exectuable_name; 38372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 38472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 38572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 38672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Get memory information using top. 38772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen bool memory_info_success = false; 38872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen int32 major, minor, bugfix; 38972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen base::SysInfo::OperatingSystemVersionNumbers(&major, &minor, &bugfix); 39072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (major == 10 && minor == 5) 39172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen memory_info_success = GetProcessMemoryInfoUsingTop_10_5(proc_info_entries_); 39272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen else if ((major == 10 && minor >= 6) || major > 10) 39372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen memory_info_success = GetProcessMemoryInfoUsingTop(proc_info_entries_); 39472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 39572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // If top didn't work then fall back to ps. 39672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!memory_info_success) { 39772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen memory_info_success = GetProcessMemoryInfoUsingPS(pid_list, 39872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen proc_info_entries_); 39972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 40072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 40172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return memory_info_success; 40272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 40372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Clear all the stored information. 405c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ProcessInfoSnapshot::Reset() { 406c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch proc_info_entries_.clear(); 407c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 409c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool ProcessInfoSnapshot::GetProcInfo(int pid, 410c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ProcInfoEntry* proc_info) const { 411c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::map<int,ProcInfoEntry>::const_iterator it = proc_info_entries_.find(pid); 412c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (it == proc_info_entries_.end()) 413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 414c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 415c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *proc_info = it->second; 416c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 417c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 418c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 419c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool ProcessInfoSnapshot::GetCommittedKBytesOfPID( 420c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int pid, 421c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base::CommittedKBytes* usage) const { 422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Try to avoid crashing on a bug; stats aren't usually so crucial. 423c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!usage) { 424c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NOTREACHED(); 425c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 426c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 427c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 428c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Failure of |GetProcInfo()| is "normal", due to racing. 429c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ProcInfoEntry proc_info; 430c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!GetProcInfo(pid, &proc_info)) { 431c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch usage->priv = 0; 432c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch usage->mapped = 0; 433c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch usage->image = 0; 434c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 435c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 436c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 43772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen usage->priv = proc_info.vsize / 1024; 438c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch usage->mapped = 0; 439c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch usage->image = 0; 440c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 441c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 442c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 443c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool ProcessInfoSnapshot::GetWorkingSetKBytesOfPID( 444c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int pid, 445c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base::WorkingSetKBytes* ws_usage) const { 446c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Try to avoid crashing on a bug; stats aren't usually so crucial. 447c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!ws_usage) { 448c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NOTREACHED(); 449c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 450c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 451c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 452c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Failure of |GetProcInfo()| is "normal", due to racing. 453c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ProcInfoEntry proc_info; 454c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!GetProcInfo(pid, &proc_info)) { 455c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ws_usage->priv = 0; 456c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ws_usage->shareable = 0; 457c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ws_usage->shared = 0; 458c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 459c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 460c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 46172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ws_usage->priv = proc_info.rprvt / 1024; 46272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ws_usage->shareable = proc_info.rss / 1024; 46372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ws_usage->shared = proc_info.rshrd / 1024; 464c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 465c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 466