linux: Read /proc/<pid> files via PtraceConnection

Bug: crashpad:250
Change-Id: I93c8944c48a17bd2c2b34cd9b8d81750cf80229c
Reviewed-on: https://chromium-review.googlesource.com/1200311
Commit-Queue: Joshua Peraza <jperaza@chromium.org>
Reviewed-by: Mark Mentovai <mark@chromium.org>
This commit is contained in:
Joshua Peraza 2018-09-10 09:09:21 -07:00 committed by Commit Bot
parent a521447214
commit 78bf924fa6
6 changed files with 33 additions and 22 deletions

View File

@ -236,7 +236,7 @@ bool ProcessReaderLinux::CPUTimes(timeval* user_time,
for (const Thread& thread : threads_) {
ProcStatReader stat;
if (!stat.Initialize(thread.tid)) {
if (!stat.Initialize(connection_, thread.tid)) {
return false;
}

View File

@ -43,9 +43,12 @@ ProcStatReader::ProcStatReader()
ProcStatReader::~ProcStatReader() {}
bool ProcStatReader::Initialize(pid_t tid) {
bool ProcStatReader::Initialize(PtraceConnection* connection, pid_t tid) {
INITIALIZATION_STATE_SET_INITIALIZING(initialized_);
if (!ReadFile(tid)) {
char path[32];
snprintf(path, arraysize(path), "/proc/%d/stat", tid);
if (!connection->ReadFileContents(base::FilePath(path), &contents_)) {
return false;
}
@ -110,15 +113,6 @@ bool ProcStatReader::StartTime(timeval* start_time) const {
return true;
}
bool ProcStatReader::ReadFile(pid_t tid) {
char path[32];
snprintf(path, arraysize(path), "/proc/%d/stat", tid);
if (!LoggingReadEntireFile(base::FilePath(path), &contents_)) {
return false;
}
return true;
}
bool ProcStatReader::FindColumn(int col_index, const char** column) const {
size_t position = third_column_position_;
for (int index = 2; index < col_index; ++index) {

View File

@ -22,6 +22,7 @@
#include <string>
#include "base/macros.h"
#include "util/linux/ptrace_connection.h"
#include "util/misc/initialization_state_dcheck.h"
namespace crashpad {
@ -36,8 +37,10 @@ class ProcStatReader {
//!
//! This method must be successfully called before calling any other.
//!
//! \param[in] connection A connection to the process to which the target
//! thread belongs.
//! \param[in] tid The thread ID to read the stat file for.
bool Initialize(pid_t tid);
bool Initialize(PtraceConnection* connection, pid_t tid);
//! \brief Determines the time the thread has spent executing in user mode.
//!
@ -64,7 +67,6 @@ class ProcStatReader {
bool StartTime(timeval* start_time) const;
private:
bool ReadFile(pid_t tid);
bool FindColumn(int index, const char** column) const;
bool ReadTimeAtIndex(int index, timeval* time_val) const;

View File

@ -20,6 +20,7 @@
#include "base/logging.h"
#include "gtest/gtest.h"
#include "test/linux/fake_ptrace_connection.h"
#include "util/thread/thread.h"
namespace crashpad {
@ -27,8 +28,11 @@ namespace test {
namespace {
TEST(ProcStatReader, Basic) {
FakePtraceConnection connection;
ASSERT_TRUE(connection.Initialize(getpid()));
ProcStatReader stat;
ASSERT_TRUE(stat.Initialize(getpid()));
ASSERT_TRUE(stat.Initialize(&connection, getpid()));
timeval start_time;
ASSERT_TRUE(stat.StartTime(&start_time));
@ -53,8 +57,11 @@ pid_t gettid() {
}
void GetStartTime(timeval* start_time) {
FakePtraceConnection connection;
ASSERT_TRUE(connection.Initialize(getpid()));
ProcStatReader stat;
ASSERT_TRUE(stat.Initialize(gettid()));
ASSERT_TRUE(stat.Initialize(&connection, gettid()));
ASSERT_TRUE(stat.StartTime(start_time));
}

View File

@ -174,6 +174,7 @@ class ProcessInfo {
// multiple successive calls will always produce the same return value and out
// parameters. This is necessary for intergration with the Snapshot interface.
// See https://crashpad.chromium.org/bug/9.
PtraceConnection* connection_;
std::set<gid_t> supplementary_groups_;
mutable timeval start_time_;
pid_t pid_;

View File

@ -20,13 +20,15 @@
#include "base/logging.h"
#include "util/file/delimited_file_reader.h"
#include "util/file/file_reader.h"
#include "util/file/string_file.h"
#include "util/linux/proc_stat_reader.h"
#include "util/misc/lexing.h"
namespace crashpad {
ProcessInfo::ProcessInfo()
: supplementary_groups_(),
: connection_(),
supplementary_groups_(),
start_time_(),
pid_(-1),
ppid_(-1),
@ -45,16 +47,19 @@ bool ProcessInfo::InitializeWithPtrace(PtraceConnection* connection) {
INITIALIZATION_STATE_SET_INITIALIZING(initialized_);
DCHECK(connection);
connection_ = connection;
pid_ = connection->GetProcessID();
is_64_bit_ = connection->Is64Bit();
{
char path[32];
snprintf(path, sizeof(path), "/proc/%d/status", pid_);
FileReader status_file;
if (!status_file.Open(base::FilePath(path))) {
std::string contents;
if (!connection->ReadFileContents(base::FilePath(path), &contents)) {
return false;
}
StringFile status_file;
status_file.SetString(contents);
DelimitedFileReader status_file_line_reader(&status_file);
@ -230,7 +235,7 @@ bool ProcessInfo::StartTime(timeval* start_time) const {
if (start_time_initialized_.is_uninitialized()) {
start_time_initialized_.set_invalid();
ProcStatReader reader;
if (!reader.Initialize(pid_)) {
if (!reader.Initialize(connection_, pid_)) {
return false;
}
if (!reader.StartTime(&start_time_)) {
@ -252,10 +257,12 @@ bool ProcessInfo::Arguments(std::vector<std::string>* argv) const {
char path[32];
snprintf(path, sizeof(path), "/proc/%d/cmdline", pid_);
FileReader cmdline_file;
if (!cmdline_file.Open(base::FilePath(path))) {
std::string contents;
if (!connection_->ReadFileContents(base::FilePath(path), &contents)) {
return false;
}
StringFile cmdline_file;
cmdline_file.SetString(contents);
DelimitedFileReader cmdline_file_field_reader(&cmdline_file);