mirror of
https://github.com/chromium/crashpad.git
synced 2025-03-09 14:06:33 +00:00
Make ProcessReaderModule and ProcessReaderThread nested classes.
This change is being made in response to the suggestion at https://codereview.chromium.org/539263003/diff/20001/util/mac/mach_o_image_symbol_table_reader.h#newcode45 TEST=util_test ProcessReader.* R=rsesek@chromium.org Review URL: https://codereview.chromium.org/543193002
This commit is contained in:
parent
9dd0ac943a
commit
3d4eeae864
@ -69,7 +69,7 @@ kern_return_t MachVMRegionRecurseDeepest(mach_port_t task,
|
||||
|
||||
namespace crashpad {
|
||||
|
||||
ProcessReaderThread::ProcessReaderThread()
|
||||
ProcessReader::Thread::Thread()
|
||||
: thread_context(),
|
||||
float_context(),
|
||||
debug_context(),
|
||||
@ -82,10 +82,10 @@ ProcessReaderThread::ProcessReaderThread()
|
||||
priority(0) {
|
||||
}
|
||||
|
||||
ProcessReaderModule::ProcessReaderModule() : name(), address(0), timestamp(0) {
|
||||
ProcessReader::Module::Module() : name(), address(0), timestamp(0) {
|
||||
}
|
||||
|
||||
ProcessReaderModule::~ProcessReaderModule() {
|
||||
ProcessReader::Module::~Module() {
|
||||
}
|
||||
|
||||
ProcessReader::ProcessReader()
|
||||
@ -101,7 +101,7 @@ ProcessReader::ProcessReader()
|
||||
}
|
||||
|
||||
ProcessReader::~ProcessReader() {
|
||||
for (const ProcessReaderThread& thread : threads_) {
|
||||
for (const Thread& thread : threads_) {
|
||||
kern_return_t kr = mach_port_deallocate(mach_task_self(), thread.port);
|
||||
MACH_LOG_IF(ERROR, kr != KERN_SUCCESS, kr) << "mach_port_deallocate";
|
||||
}
|
||||
@ -186,7 +186,7 @@ bool ProcessReader::CPUTimes(timeval* user_time, timeval* system_time) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
const std::vector<ProcessReaderThread>& ProcessReader::Threads() {
|
||||
const std::vector<ProcessReader::Thread>& ProcessReader::Threads() {
|
||||
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
||||
|
||||
if (!initialized_threads_) {
|
||||
@ -196,7 +196,7 @@ const std::vector<ProcessReaderThread>& ProcessReader::Threads() {
|
||||
return threads_;
|
||||
}
|
||||
|
||||
const std::vector<ProcessReaderModule>& ProcessReader::Modules() {
|
||||
const std::vector<ProcessReader::Module>& ProcessReader::Modules() {
|
||||
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
||||
|
||||
if (!initialized_modules_) {
|
||||
@ -231,7 +231,7 @@ void ProcessReader::InitializeThreads() {
|
||||
mach_vm_round_page(thread_count * sizeof(*threads)));
|
||||
|
||||
for (size_t index = 0; index < thread_count; ++index) {
|
||||
ProcessReaderThread thread;
|
||||
Thread thread;
|
||||
thread.port = threads[index];
|
||||
|
||||
#if defined(ARCH_CPU_X86_FAMILY)
|
||||
@ -410,7 +410,7 @@ void ProcessReader::InitializeModules() {
|
||||
|
||||
bool found_dyld = false;
|
||||
for (const process_types::dyld_image_info& image_info : image_info_vector) {
|
||||
ProcessReaderModule module;
|
||||
Module module;
|
||||
module.address = image_info.imageLoadAddress;
|
||||
module.timestamp = image_info.imageFileModDate;
|
||||
if (!task_memory_->ReadCString(image_info.imageFilePath, &module.name)) {
|
||||
@ -443,7 +443,7 @@ void ProcessReader::InitializeModules() {
|
||||
// in its LC_LOAD_DYLINKER command.
|
||||
if (!found_dyld && all_image_infos.version >= 2 &&
|
||||
all_image_infos.dyldImageLoadAddress) {
|
||||
ProcessReaderModule module;
|
||||
Module module;
|
||||
module.address = all_image_infos.dyldImageLoadAddress;
|
||||
module.timestamp = 0;
|
||||
|
||||
|
@ -32,62 +32,63 @@
|
||||
|
||||
namespace crashpad {
|
||||
|
||||
//! \brief Contains information about a thread that belongs to a task (process).
|
||||
struct ProcessReaderThread {
|
||||
#if defined(ARCH_CPU_X86_FAMILY)
|
||||
union ThreadContext {
|
||||
x86_thread_state64_t t64;
|
||||
x86_thread_state32_t t32;
|
||||
};
|
||||
union FloatContext {
|
||||
x86_float_state64_t f64;
|
||||
x86_float_state32_t f32;
|
||||
};
|
||||
union DebugContext {
|
||||
x86_debug_state64_t d64;
|
||||
x86_debug_state32_t d32;
|
||||
};
|
||||
#endif
|
||||
|
||||
ProcessReaderThread();
|
||||
~ProcessReaderThread() {}
|
||||
|
||||
ThreadContext thread_context;
|
||||
FloatContext float_context;
|
||||
DebugContext debug_context;
|
||||
uint64_t id;
|
||||
mach_vm_address_t stack_region_address;
|
||||
mach_vm_size_t stack_region_size;
|
||||
mach_vm_address_t thread_specific_data_address;
|
||||
mach_port_t port;
|
||||
int suspend_count;
|
||||
int priority;
|
||||
};
|
||||
|
||||
//! \brief Contains information about a module loaded into a process.
|
||||
struct ProcessReaderModule {
|
||||
ProcessReaderModule();
|
||||
~ProcessReaderModule();
|
||||
|
||||
//! \brief The pathname used to load the module from disk.
|
||||
std::string name;
|
||||
|
||||
//! \brief The address where the base of the module is loaded in the remote
|
||||
//! process.
|
||||
mach_vm_address_t address;
|
||||
|
||||
//! \brief The module’s timestamp.
|
||||
//!
|
||||
//! This field will be `0` if its value cannot be determined. It can only be
|
||||
//! determined for images that are loaded by dyld, so it will be `0` for the
|
||||
//! main executable and for dyld itself.
|
||||
time_t timestamp;
|
||||
};
|
||||
|
||||
//! \brief Accesses information about another process, identified by a Mach
|
||||
//! task.
|
||||
class ProcessReader {
|
||||
public:
|
||||
//! \brief Contains information about a thread that belongs to a task
|
||||
//! (process).
|
||||
struct Thread {
|
||||
#if defined(ARCH_CPU_X86_FAMILY)
|
||||
union ThreadContext {
|
||||
x86_thread_state64_t t64;
|
||||
x86_thread_state32_t t32;
|
||||
};
|
||||
union FloatContext {
|
||||
x86_float_state64_t f64;
|
||||
x86_float_state32_t f32;
|
||||
};
|
||||
union DebugContext {
|
||||
x86_debug_state64_t d64;
|
||||
x86_debug_state32_t d32;
|
||||
};
|
||||
#endif
|
||||
|
||||
Thread();
|
||||
~Thread() {}
|
||||
|
||||
ThreadContext thread_context;
|
||||
FloatContext float_context;
|
||||
DebugContext debug_context;
|
||||
uint64_t id;
|
||||
mach_vm_address_t stack_region_address;
|
||||
mach_vm_size_t stack_region_size;
|
||||
mach_vm_address_t thread_specific_data_address;
|
||||
mach_port_t port;
|
||||
int suspend_count;
|
||||
int priority;
|
||||
};
|
||||
|
||||
//! \brief Contains information about a module loaded into a process.
|
||||
struct Module {
|
||||
Module();
|
||||
~Module();
|
||||
|
||||
//! \brief The pathname used to load the module from disk.
|
||||
std::string name;
|
||||
|
||||
//! \brief The address where the base of the module is loaded in the remote
|
||||
//! process.
|
||||
mach_vm_address_t address;
|
||||
|
||||
//! \brief The module’s timestamp.
|
||||
//!
|
||||
//! This field will be `0` if its value cannot be determined. It can only be
|
||||
//! determined for images that are loaded by dyld, so it will be `0` for the
|
||||
//! main executable and for dyld itself.
|
||||
time_t timestamp;
|
||||
};
|
||||
|
||||
ProcessReader();
|
||||
~ProcessReader();
|
||||
|
||||
@ -129,12 +130,12 @@ class ProcessReader {
|
||||
|
||||
//! \return The threads that are in the task (process). The first element (at
|
||||
//! index `0`) corresponds to the main thread.
|
||||
const std::vector<ProcessReaderThread>& Threads();
|
||||
const std::vector<Thread>& Threads();
|
||||
|
||||
//! \return The modules loaded in the process. The first element (at index
|
||||
//! `0`) corresponds to the main executable, and the final element
|
||||
//! corresponds to the dynamic loader, dyld.
|
||||
const std::vector<ProcessReaderModule>& Modules();
|
||||
const std::vector<Module>& Modules();
|
||||
|
||||
private:
|
||||
//! Performs lazy initialization of the \a threads_ vector on behalf of
|
||||
@ -201,8 +202,8 @@ class ProcessReader {
|
||||
unsigned int user_tag);
|
||||
|
||||
kinfo_proc kern_proc_info_;
|
||||
std::vector<ProcessReaderThread> threads_; // owns send rights
|
||||
std::vector<ProcessReaderModule> modules_;
|
||||
std::vector<Thread> threads_; // owns send rights
|
||||
std::vector<Module> modules_;
|
||||
scoped_ptr<TaskMemory> task_memory_;
|
||||
mach_port_t task_; // weak
|
||||
InitializationStateDcheck initialized_;
|
||||
|
@ -144,7 +144,7 @@ TEST(ProcessReader, SelfOneThread) {
|
||||
ProcessReader process_reader;
|
||||
ASSERT_TRUE(process_reader.Initialize(mach_task_self()));
|
||||
|
||||
const std::vector<ProcessReaderThread>& threads = process_reader.Threads();
|
||||
const std::vector<ProcessReader::Thread>& threads = process_reader.Threads();
|
||||
|
||||
// If other tests ran in this process previously, threads may have been
|
||||
// created and may still be running. This check must look for at least one
|
||||
@ -315,7 +315,7 @@ typedef std::map<uint64_t, TestThreadPool::ThreadExpectation> ThreadMap;
|
||||
// the test’s control (such as system libraries) may start threads, or may have
|
||||
// started threads prior to a test’s execution.
|
||||
void ExpectSeveralThreads(ThreadMap* thread_map,
|
||||
const std::vector<ProcessReaderThread>& threads,
|
||||
const std::vector<ProcessReader::Thread>& threads,
|
||||
const bool tolerate_extra_threads) {
|
||||
if (tolerate_extra_threads) {
|
||||
ASSERT_GE(threads.size(), thread_map->size());
|
||||
@ -324,7 +324,7 @@ void ExpectSeveralThreads(ThreadMap* thread_map,
|
||||
}
|
||||
|
||||
for (size_t thread_index = 0; thread_index < threads.size(); ++thread_index) {
|
||||
const ProcessReaderThread& thread = threads[thread_index];
|
||||
const ProcessReader::Thread& thread = threads[thread_index];
|
||||
mach_vm_address_t thread_stack_region_end =
|
||||
thread.stack_region_address + thread.stack_region_size;
|
||||
|
||||
@ -357,7 +357,7 @@ void ExpectSeveralThreads(ThreadMap* thread_map,
|
||||
continue;
|
||||
}
|
||||
|
||||
const ProcessReaderThread& other_thread = threads[other_thread_index];
|
||||
const ProcessReader::Thread& other_thread = threads[other_thread_index];
|
||||
|
||||
EXPECT_NE(thread.id, other_thread.id);
|
||||
EXPECT_NE(thread.port, other_thread.port);
|
||||
@ -409,7 +409,7 @@ TEST(ProcessReader, SelfSeveralThreads) {
|
||||
thread_map[thread_id] = expectation;
|
||||
}
|
||||
|
||||
const std::vector<ProcessReaderThread>& threads = process_reader.Threads();
|
||||
const std::vector<ProcessReader::Thread>& threads = process_reader.Threads();
|
||||
|
||||
// Other tests that have run previously may have resulted in the creation of
|
||||
// threads that still exist, so pass true for |tolerate_extra_threads|.
|
||||
@ -420,7 +420,7 @@ TEST(ProcessReader, SelfSeveralThreads) {
|
||||
// shows up once.
|
||||
base::mac::ScopedMachSendRight thread_self(mach_thread_self());
|
||||
bool found_thread_self = false;
|
||||
for (const ProcessReaderThread& thread : threads) {
|
||||
for (const ProcessReader::Thread& thread : threads) {
|
||||
if (thread.port == thread_self) {
|
||||
EXPECT_FALSE(found_thread_self);
|
||||
found_thread_self = true;
|
||||
@ -477,7 +477,7 @@ class ProcessReaderThreadedChild final : public MachMultiprocess {
|
||||
thread_map[thread_id] = expectation;
|
||||
}
|
||||
|
||||
const std::vector<ProcessReaderThread>& threads = process_reader.Threads();
|
||||
const std::vector<ProcessReader::Thread>& threads = process_reader.Threads();
|
||||
|
||||
// The child shouldn’t have any threads other than its main thread and the
|
||||
// ones it created in its pool, so pass false for |tolerate_extra_threads|.
|
||||
@ -578,7 +578,7 @@ TEST(ProcessReader, SelfModules) {
|
||||
ASSERT_TRUE(process_reader.Initialize(mach_task_self()));
|
||||
|
||||
uint32_t dyld_image_count = _dyld_image_count();
|
||||
const std::vector<ProcessReaderModule>& modules = process_reader.Modules();
|
||||
const std::vector<ProcessReader::Module>& modules = process_reader.Modules();
|
||||
|
||||
// There needs to be at least an entry for the main executable, for a dylib,
|
||||
// and for dyld.
|
||||
@ -639,7 +639,8 @@ class ProcessReaderModulesChild final : public MachMultiprocess {
|
||||
ProcessReader process_reader;
|
||||
ASSERT_TRUE(process_reader.Initialize(ChildTask()));
|
||||
|
||||
const std::vector<ProcessReaderModule>& modules = process_reader.Modules();
|
||||
const std::vector<ProcessReader::Module>& modules =
|
||||
process_reader.Modules();
|
||||
|
||||
// There needs to be at least an entry for the main executable, for a dylib,
|
||||
// and for dyld.
|
||||
|
Loading…
x
Reference in New Issue
Block a user