mirror of
https://github.com/chromium/crashpad.git
synced 2025-03-20 02:23:47 +00:00
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:
parent
a521447214
commit
78bf924fa6
@ -236,7 +236,7 @@ bool ProcessReaderLinux::CPUTimes(timeval* user_time,
|
|||||||
|
|
||||||
for (const Thread& thread : threads_) {
|
for (const Thread& thread : threads_) {
|
||||||
ProcStatReader stat;
|
ProcStatReader stat;
|
||||||
if (!stat.Initialize(thread.tid)) {
|
if (!stat.Initialize(connection_, thread.tid)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,9 +43,12 @@ ProcStatReader::ProcStatReader()
|
|||||||
|
|
||||||
ProcStatReader::~ProcStatReader() {}
|
ProcStatReader::~ProcStatReader() {}
|
||||||
|
|
||||||
bool ProcStatReader::Initialize(pid_t tid) {
|
bool ProcStatReader::Initialize(PtraceConnection* connection, pid_t tid) {
|
||||||
INITIALIZATION_STATE_SET_INITIALIZING(initialized_);
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,15 +113,6 @@ bool ProcStatReader::StartTime(timeval* start_time) const {
|
|||||||
return true;
|
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 {
|
bool ProcStatReader::FindColumn(int col_index, const char** column) const {
|
||||||
size_t position = third_column_position_;
|
size_t position = third_column_position_;
|
||||||
for (int index = 2; index < col_index; ++index) {
|
for (int index = 2; index < col_index; ++index) {
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "base/macros.h"
|
#include "base/macros.h"
|
||||||
|
#include "util/linux/ptrace_connection.h"
|
||||||
#include "util/misc/initialization_state_dcheck.h"
|
#include "util/misc/initialization_state_dcheck.h"
|
||||||
|
|
||||||
namespace crashpad {
|
namespace crashpad {
|
||||||
@ -36,8 +37,10 @@ class ProcStatReader {
|
|||||||
//!
|
//!
|
||||||
//! This method must be successfully called before calling any other.
|
//! 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.
|
//! \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.
|
//! \brief Determines the time the thread has spent executing in user mode.
|
||||||
//!
|
//!
|
||||||
@ -64,7 +67,6 @@ class ProcStatReader {
|
|||||||
bool StartTime(timeval* start_time) const;
|
bool StartTime(timeval* start_time) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool ReadFile(pid_t tid);
|
|
||||||
bool FindColumn(int index, const char** column) const;
|
bool FindColumn(int index, const char** column) const;
|
||||||
bool ReadTimeAtIndex(int index, timeval* time_val) const;
|
bool ReadTimeAtIndex(int index, timeval* time_val) const;
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
#include "base/logging.h"
|
#include "base/logging.h"
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
|
#include "test/linux/fake_ptrace_connection.h"
|
||||||
#include "util/thread/thread.h"
|
#include "util/thread/thread.h"
|
||||||
|
|
||||||
namespace crashpad {
|
namespace crashpad {
|
||||||
@ -27,8 +28,11 @@ namespace test {
|
|||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
TEST(ProcStatReader, Basic) {
|
TEST(ProcStatReader, Basic) {
|
||||||
|
FakePtraceConnection connection;
|
||||||
|
ASSERT_TRUE(connection.Initialize(getpid()));
|
||||||
|
|
||||||
ProcStatReader stat;
|
ProcStatReader stat;
|
||||||
ASSERT_TRUE(stat.Initialize(getpid()));
|
ASSERT_TRUE(stat.Initialize(&connection, getpid()));
|
||||||
|
|
||||||
timeval start_time;
|
timeval start_time;
|
||||||
ASSERT_TRUE(stat.StartTime(&start_time));
|
ASSERT_TRUE(stat.StartTime(&start_time));
|
||||||
@ -53,8 +57,11 @@ pid_t gettid() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GetStartTime(timeval* start_time) {
|
void GetStartTime(timeval* start_time) {
|
||||||
|
FakePtraceConnection connection;
|
||||||
|
ASSERT_TRUE(connection.Initialize(getpid()));
|
||||||
|
|
||||||
ProcStatReader stat;
|
ProcStatReader stat;
|
||||||
ASSERT_TRUE(stat.Initialize(gettid()));
|
ASSERT_TRUE(stat.Initialize(&connection, gettid()));
|
||||||
ASSERT_TRUE(stat.StartTime(start_time));
|
ASSERT_TRUE(stat.StartTime(start_time));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,6 +174,7 @@ class ProcessInfo {
|
|||||||
// multiple successive calls will always produce the same return value and out
|
// multiple successive calls will always produce the same return value and out
|
||||||
// parameters. This is necessary for intergration with the Snapshot interface.
|
// parameters. This is necessary for intergration with the Snapshot interface.
|
||||||
// See https://crashpad.chromium.org/bug/9.
|
// See https://crashpad.chromium.org/bug/9.
|
||||||
|
PtraceConnection* connection_;
|
||||||
std::set<gid_t> supplementary_groups_;
|
std::set<gid_t> supplementary_groups_;
|
||||||
mutable timeval start_time_;
|
mutable timeval start_time_;
|
||||||
pid_t pid_;
|
pid_t pid_;
|
||||||
|
@ -20,13 +20,15 @@
|
|||||||
#include "base/logging.h"
|
#include "base/logging.h"
|
||||||
#include "util/file/delimited_file_reader.h"
|
#include "util/file/delimited_file_reader.h"
|
||||||
#include "util/file/file_reader.h"
|
#include "util/file/file_reader.h"
|
||||||
|
#include "util/file/string_file.h"
|
||||||
#include "util/linux/proc_stat_reader.h"
|
#include "util/linux/proc_stat_reader.h"
|
||||||
#include "util/misc/lexing.h"
|
#include "util/misc/lexing.h"
|
||||||
|
|
||||||
namespace crashpad {
|
namespace crashpad {
|
||||||
|
|
||||||
ProcessInfo::ProcessInfo()
|
ProcessInfo::ProcessInfo()
|
||||||
: supplementary_groups_(),
|
: connection_(),
|
||||||
|
supplementary_groups_(),
|
||||||
start_time_(),
|
start_time_(),
|
||||||
pid_(-1),
|
pid_(-1),
|
||||||
ppid_(-1),
|
ppid_(-1),
|
||||||
@ -45,16 +47,19 @@ bool ProcessInfo::InitializeWithPtrace(PtraceConnection* connection) {
|
|||||||
INITIALIZATION_STATE_SET_INITIALIZING(initialized_);
|
INITIALIZATION_STATE_SET_INITIALIZING(initialized_);
|
||||||
DCHECK(connection);
|
DCHECK(connection);
|
||||||
|
|
||||||
|
connection_ = connection;
|
||||||
pid_ = connection->GetProcessID();
|
pid_ = connection->GetProcessID();
|
||||||
is_64_bit_ = connection->Is64Bit();
|
is_64_bit_ = connection->Is64Bit();
|
||||||
|
|
||||||
{
|
{
|
||||||
char path[32];
|
char path[32];
|
||||||
snprintf(path, sizeof(path), "/proc/%d/status", pid_);
|
snprintf(path, sizeof(path), "/proc/%d/status", pid_);
|
||||||
FileReader status_file;
|
std::string contents;
|
||||||
if (!status_file.Open(base::FilePath(path))) {
|
if (!connection->ReadFileContents(base::FilePath(path), &contents)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
StringFile status_file;
|
||||||
|
status_file.SetString(contents);
|
||||||
|
|
||||||
DelimitedFileReader status_file_line_reader(&status_file);
|
DelimitedFileReader status_file_line_reader(&status_file);
|
||||||
|
|
||||||
@ -230,7 +235,7 @@ bool ProcessInfo::StartTime(timeval* start_time) const {
|
|||||||
if (start_time_initialized_.is_uninitialized()) {
|
if (start_time_initialized_.is_uninitialized()) {
|
||||||
start_time_initialized_.set_invalid();
|
start_time_initialized_.set_invalid();
|
||||||
ProcStatReader reader;
|
ProcStatReader reader;
|
||||||
if (!reader.Initialize(pid_)) {
|
if (!reader.Initialize(connection_, pid_)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!reader.StartTime(&start_time_)) {
|
if (!reader.StartTime(&start_time_)) {
|
||||||
@ -252,10 +257,12 @@ bool ProcessInfo::Arguments(std::vector<std::string>* argv) const {
|
|||||||
|
|
||||||
char path[32];
|
char path[32];
|
||||||
snprintf(path, sizeof(path), "/proc/%d/cmdline", pid_);
|
snprintf(path, sizeof(path), "/proc/%d/cmdline", pid_);
|
||||||
FileReader cmdline_file;
|
std::string contents;
|
||||||
if (!cmdline_file.Open(base::FilePath(path))) {
|
if (!connection_->ReadFileContents(base::FilePath(path), &contents)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
StringFile cmdline_file;
|
||||||
|
cmdline_file.SetString(contents);
|
||||||
|
|
||||||
DelimitedFileReader cmdline_file_field_reader(&cmdline_file);
|
DelimitedFileReader cmdline_file_field_reader(&cmdline_file);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user