Commit a9808479 authored by sheu@chromium.org's avatar sheu@chromium.org

Parse /proc/<pid>/stats fields as int64

Some entries are 64 bits wide, and will overflow on occasion.  In particular,
VM_STARTTIME will overflow a 32-bit int on long-running systems.

BUG=332491
TEST=local build, run on desktop Linux

Review URL: https://codereview.chromium.org/129353002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@243733 0039d316-1c4b-4281-b951-d872f2087c98
parent 435fdb33
...@@ -115,13 +115,13 @@ void ParseProcStat(const std::string& contents, ProcStatMap* output) { ...@@ -115,13 +115,13 @@ void ParseProcStat(const std::string& contents, ProcStatMap* output) {
} }
} }
int GetProcStatsFieldAsInt(const std::vector<std::string>& proc_stats, int64 GetProcStatsFieldAsInt64(const std::vector<std::string>& proc_stats,
ProcStatsFields field_num) { ProcStatsFields field_num) {
DCHECK_GE(field_num, VM_PPID); DCHECK_GE(field_num, VM_PPID);
CHECK_LT(static_cast<size_t>(field_num), proc_stats.size()); CHECK_LT(static_cast<size_t>(field_num), proc_stats.size());
int value; int64 value;
return StringToInt(proc_stats[field_num], &value) ? value : 0; return StringToInt64(proc_stats[field_num], &value) ? value : 0;
} }
size_t GetProcStatsFieldAsSizeT(const std::vector<std::string>& proc_stats, size_t GetProcStatsFieldAsSizeT(const std::vector<std::string>& proc_stats,
...@@ -133,15 +133,14 @@ size_t GetProcStatsFieldAsSizeT(const std::vector<std::string>& proc_stats, ...@@ -133,15 +133,14 @@ size_t GetProcStatsFieldAsSizeT(const std::vector<std::string>& proc_stats,
return StringToSizeT(proc_stats[field_num], &value) ? value : 0; return StringToSizeT(proc_stats[field_num], &value) ? value : 0;
} }
int ReadProcStatsAndGetFieldAsInt(pid_t pid, int64 ReadProcStatsAndGetFieldAsInt64(pid_t pid, ProcStatsFields field_num) {
ProcStatsFields field_num) {
std::string stats_data; std::string stats_data;
if (!ReadProcStats(pid, &stats_data)) if (!ReadProcStats(pid, &stats_data))
return 0; return 0;
std::vector<std::string> proc_stats; std::vector<std::string> proc_stats;
if (!ParseProcStats(stats_data, &proc_stats)) if (!ParseProcStats(stats_data, &proc_stats))
return 0; return 0;
return GetProcStatsFieldAsInt(proc_stats, field_num); return GetProcStatsFieldAsInt64(proc_stats, field_num);
} }
size_t ReadProcStatsAndGetFieldAsSizeT(pid_t pid, size_t ReadProcStatsAndGetFieldAsSizeT(pid_t pid,
......
...@@ -63,19 +63,18 @@ enum ProcStatsFields { ...@@ -63,19 +63,18 @@ enum ProcStatsFields {
// Reads the |field_num|th field from |proc_stats|. Returns 0 on failure. // Reads the |field_num|th field from |proc_stats|. Returns 0 on failure.
// This version does not handle the first 3 values, since the first value is // This version does not handle the first 3 values, since the first value is
// simply |pid|, and the next two values are strings. // simply |pid|, and the next two values are strings.
int GetProcStatsFieldAsInt(const std::vector<std::string>& proc_stats, int64 GetProcStatsFieldAsInt64(const std::vector<std::string>& proc_stats,
ProcStatsFields field_num); ProcStatsFields field_num);
// Same as GetProcStatsFieldAsInt(), but for size_t values. // Same as GetProcStatsFieldAsInt64(), but for size_t values.
size_t GetProcStatsFieldAsSizeT(const std::vector<std::string>& proc_stats, size_t GetProcStatsFieldAsSizeT(const std::vector<std::string>& proc_stats,
ProcStatsFields field_num); ProcStatsFields field_num);
// Convenience wrapper around GetProcStatsFieldAsInt(), ParseProcStats() and // Convenience wrapper around GetProcStatsFieldAsInt64(), ParseProcStats() and
// ReadProcStats(). See GetProcStatsFieldAsInt() for details. // ReadProcStats(). See GetProcStatsFieldAsInt64() for details.
int ReadProcStatsAndGetFieldAsInt(pid_t pid, int64 ReadProcStatsAndGetFieldAsInt64(pid_t pid, ProcStatsFields field_num);
ProcStatsFields field_num);
// Same as ReadProcStatsAndGetFieldAsInt() but for size_t values. // Same as ReadProcStatsAndGetFieldAsInt64() but for size_t values.
size_t ReadProcStatsAndGetFieldAsSizeT(pid_t pid, size_t ReadProcStatsAndGetFieldAsSizeT(pid_t pid,
ProcStatsFields field_num); ProcStatsFields field_num);
......
...@@ -11,7 +11,7 @@ namespace base { ...@@ -11,7 +11,7 @@ namespace base {
ProcessId GetParentProcessId(ProcessHandle process) { ProcessId GetParentProcessId(ProcessHandle process) {
ProcessId pid = ProcessId pid =
internal::ReadProcStatsAndGetFieldAsInt(process, internal::VM_PPID); internal::ReadProcStatsAndGetFieldAsInt64(process, internal::VM_PPID);
if (pid) if (pid)
return pid; return pid;
return -1; return -1;
......
...@@ -15,8 +15,8 @@ namespace base { ...@@ -15,8 +15,8 @@ namespace base {
//static //static
const Time CurrentProcessInfo::CreationTime() { const Time CurrentProcessInfo::CreationTime() {
ProcessHandle pid = GetCurrentProcessHandle(); ProcessHandle pid = GetCurrentProcessHandle();
int start_ticks = internal::ReadProcStatsAndGetFieldAsInt( int64 start_ticks =
pid, internal::VM_STARTTIME); internal::ReadProcStatsAndGetFieldAsInt64(pid, internal::VM_STARTTIME);
DCHECK(start_ticks); DCHECK(start_ticks);
TimeDelta start_offset = internal::ClockTicksToTimeDelta(start_ticks); TimeDelta start_offset = internal::ClockTicksToTimeDelta(start_ticks);
Time boot_time = internal::GetBootTime(); Time boot_time = internal::GetBootTime();
......
...@@ -121,8 +121,8 @@ bool ProcessIterator::CheckForNextProcess() { ...@@ -121,8 +121,8 @@ bool ProcessIterator::CheckForNextProcess() {
} }
entry_.pid_ = pid; entry_.pid_ = pid;
entry_.ppid_ = GetProcStatsFieldAsInt(proc_stats, internal::VM_PPID); entry_.ppid_ = GetProcStatsFieldAsInt64(proc_stats, internal::VM_PPID);
entry_.gid_ = GetProcStatsFieldAsInt(proc_stats, internal::VM_PGRP); entry_.gid_ = GetProcStatsFieldAsInt64(proc_stats, internal::VM_PGRP);
entry_.cmd_line_args_.assign(cmd_line_args.begin(), cmd_line_args.end()); entry_.cmd_line_args_.assign(cmd_line_args.begin(), cmd_line_args.end());
entry_.exe_file_ = GetProcessExecutablePath(pid).BaseName().value(); entry_.exe_file_ = GetProcessExecutablePath(pid).BaseName().value();
return true; return true;
......
...@@ -391,16 +391,16 @@ int ParseProcStatCPU(const std::string& input) { ...@@ -391,16 +391,16 @@ int ParseProcStatCPU(const std::string& input) {
if (proc_stats.size() <= internal::VM_STIME) if (proc_stats.size() <= internal::VM_STIME)
return -1; return -1;
int utime = GetProcStatsFieldAsInt(proc_stats, internal::VM_UTIME); int utime = GetProcStatsFieldAsInt64(proc_stats, internal::VM_UTIME);
int stime = GetProcStatsFieldAsInt(proc_stats, internal::VM_STIME); int stime = GetProcStatsFieldAsInt64(proc_stats, internal::VM_STIME);
return utime + stime; return utime + stime;
} }
const char kProcSelfExe[] = "/proc/self/exe"; const char kProcSelfExe[] = "/proc/self/exe";
int GetNumberOfThreads(ProcessHandle process) { int GetNumberOfThreads(ProcessHandle process) {
return internal::ReadProcStatsAndGetFieldAsInt(process, return internal::ReadProcStatsAndGetFieldAsInt64(process,
internal::VM_NUMTHREADS); internal::VM_NUMTHREADS);
} }
namespace { namespace {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment