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) {
}
}
int GetProcStatsFieldAsInt(const std::vector<std::string>& proc_stats,
int64 GetProcStatsFieldAsInt64(const std::vector<std::string>& proc_stats,
ProcStatsFields field_num) {
DCHECK_GE(field_num, VM_PPID);
CHECK_LT(static_cast<size_t>(field_num), proc_stats.size());
int value;
return StringToInt(proc_stats[field_num], &value) ? value : 0;
int64 value;
return StringToInt64(proc_stats[field_num], &value) ? value : 0;
}
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;
}
int ReadProcStatsAndGetFieldAsInt(pid_t pid,
ProcStatsFields field_num) {
int64 ReadProcStatsAndGetFieldAsInt64(pid_t pid, ProcStatsFields field_num) {
std::string stats_data;
if (!ReadProcStats(pid, &stats_data))
return 0;
std::vector<std::string> proc_stats;
if (!ParseProcStats(stats_data, &proc_stats))
return 0;
return GetProcStatsFieldAsInt(proc_stats, field_num);
return GetProcStatsFieldAsInt64(proc_stats, field_num);
}
size_t ReadProcStatsAndGetFieldAsSizeT(pid_t pid,
......
......@@ -63,19 +63,18 @@ enum ProcStatsFields {
// 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
// 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);
// 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,
ProcStatsFields field_num);
// Convenience wrapper around GetProcStatsFieldAsInt(), ParseProcStats() and
// ReadProcStats(). See GetProcStatsFieldAsInt() for details.
int ReadProcStatsAndGetFieldAsInt(pid_t pid,
ProcStatsFields field_num);
// Convenience wrapper around GetProcStatsFieldAsInt64(), ParseProcStats() and
// ReadProcStats(). See GetProcStatsFieldAsInt64() for details.
int64 ReadProcStatsAndGetFieldAsInt64(pid_t pid, 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,
ProcStatsFields field_num);
......
......@@ -11,7 +11,7 @@ namespace base {
ProcessId GetParentProcessId(ProcessHandle process) {
ProcessId pid =
internal::ReadProcStatsAndGetFieldAsInt(process, internal::VM_PPID);
internal::ReadProcStatsAndGetFieldAsInt64(process, internal::VM_PPID);
if (pid)
return pid;
return -1;
......
......@@ -15,8 +15,8 @@ namespace base {
//static
const Time CurrentProcessInfo::CreationTime() {
ProcessHandle pid = GetCurrentProcessHandle();
int start_ticks = internal::ReadProcStatsAndGetFieldAsInt(
pid, internal::VM_STARTTIME);
int64 start_ticks =
internal::ReadProcStatsAndGetFieldAsInt64(pid, internal::VM_STARTTIME);
DCHECK(start_ticks);
TimeDelta start_offset = internal::ClockTicksToTimeDelta(start_ticks);
Time boot_time = internal::GetBootTime();
......
......@@ -121,8 +121,8 @@ bool ProcessIterator::CheckForNextProcess() {
}
entry_.pid_ = pid;
entry_.ppid_ = GetProcStatsFieldAsInt(proc_stats, internal::VM_PPID);
entry_.gid_ = GetProcStatsFieldAsInt(proc_stats, internal::VM_PGRP);
entry_.ppid_ = GetProcStatsFieldAsInt64(proc_stats, internal::VM_PPID);
entry_.gid_ = GetProcStatsFieldAsInt64(proc_stats, internal::VM_PGRP);
entry_.cmd_line_args_.assign(cmd_line_args.begin(), cmd_line_args.end());
entry_.exe_file_ = GetProcessExecutablePath(pid).BaseName().value();
return true;
......
......@@ -391,15 +391,15 @@ int ParseProcStatCPU(const std::string& input) {
if (proc_stats.size() <= internal::VM_STIME)
return -1;
int utime = GetProcStatsFieldAsInt(proc_stats, internal::VM_UTIME);
int stime = GetProcStatsFieldAsInt(proc_stats, internal::VM_STIME);
int utime = GetProcStatsFieldAsInt64(proc_stats, internal::VM_UTIME);
int stime = GetProcStatsFieldAsInt64(proc_stats, internal::VM_STIME);
return utime + stime;
}
const char kProcSelfExe[] = "/proc/self/exe";
int GetNumberOfThreads(ProcessHandle process) {
return internal::ReadProcStatsAndGetFieldAsInt(process,
return internal::ReadProcStatsAndGetFieldAsInt64(process,
internal::VM_NUMTHREADS);
}
......
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