Index: util/win/process_info.cc |
diff --git a/util/win/process_info.cc b/util/win/process_info.cc |
index ff8689ed5300f48ad122ab5af8b42574f34cd854..082f048c1f267bdede6e28a5ccbb1a6c04a359ba 100644 |
--- a/util/win/process_info.cc |
+++ b/util/win/process_info.cc |
@@ -104,6 +104,20 @@ bool ReadStruct(HANDLE process, WinVMAddress at, T* into) { |
return true; |
} |
+// Map from Traits to an MEMORY_BASIC_INFORMATIIONxx. |
+template <class Traits> |
+struct MemoryBasicInformationForTraits; |
+ |
+template <> |
+struct MemoryBasicInformationForTraits<process_types::internal::Traits32> { |
+ using type = MEMORY_BASIC_INFORMATION32; |
+}; |
+ |
+template <> |
+struct MemoryBasicInformationForTraits<process_types::internal::Traits64> { |
+ using type = MEMORY_BASIC_INFORMATION64; |
+}; |
+ |
} // namespace |
template <class Traits> |
@@ -253,12 +267,68 @@ bool ReadProcessData(HANDLE process, |
return true; |
} |
+template <class Traits> |
+bool ReadMemoryInfo(HANDLE process, ProcessInfo* process_info) { |
+ DCHECK(process_info->memory_info_.empty()); |
+ |
+ SYSTEM_INFO system_info; |
+ GetSystemInfo(&system_info); |
+ uint64_t min_address = |
Mark Mentovai
2015/09/26 02:02:14
const WinVMAddress?
scottmg
2015/09/26 03:12:36
Done.
|
+ reinterpret_cast<uint64_t>(system_info.lpMinimumApplicationAddress); |
+ uint64_t max_address = |
+ reinterpret_cast<uint64_t>(system_info.lpMaximumApplicationAddress); |
Mark Mentovai
2015/09/26 02:02:14
Is this correct for 64-reads-32-on-64?
scottmg
2015/09/26 03:12:36
Hmm, good point, that's tricky. After playing arou
|
+ uint64_t address = min_address; |
+ while (address <= max_address) { |
Mark Mentovai
2015/09/26 02:02:14
for (WinVMAddress address = min_address; address <
scottmg
2015/09/26 03:12:36
Done.
|
+ MemoryBasicInformationForTraits<Traits>::type memory_basic_information; |
+ size_t result = VirtualQueryEx( |
+ process, |
+ reinterpret_cast<void*>(address), |
+ reinterpret_cast<MEMORY_BASIC_INFORMATION*>(&memory_basic_information), |
+ sizeof(memory_basic_information)); |
+ if (result == 0) { |
+ PLOG(ERROR) << "VirtualQueryEx"; |
+ return false; |
+ } |
+ |
+ process_info->memory_info_.push_back( |
+ ProcessInfo::MemoryInfo(memory_basic_information)); |
+ |
+ address += memory_basic_information.RegionSize; |
Mark Mentovai
2015/09/26 02:02:14
DCHECK_GT(RegionSize, 0);
so that a very busted m
scottmg
2015/09/26 03:12:36
Done. (if with LOG rather than DCHECK)
|
+ } |
+ |
+ return true; |
+} |
+ |
ProcessInfo::Module::Module() : name(), dll_base(0), size(0), timestamp() { |
} |
ProcessInfo::Module::~Module() { |
} |
+ProcessInfo::MemoryInfo::MemoryInfo() |
+ : base_address(0), |
+ region_size(0), |
+ allocation_base(0), |
+ state(0), |
+ allocation_protect(0), |
+ protect(0), |
+ type(0) { |
+} |
+ |
+template <class MBI> |
+ProcessInfo::MemoryInfo::MemoryInfo(const MBI& mbi) |
+ : base_address(mbi.BaseAddress), |
+ region_size(mbi.RegionSize), |
+ allocation_base(mbi.AllocationBase), |
+ state(mbi.State), |
+ allocation_protect(mbi.AllocationProtect), |
+ protect(mbi.Protect), |
+ type(mbi.Type) { |
+} |
+ |
+ProcessInfo::MemoryInfo::~MemoryInfo() { |
+} |
+ |
ProcessInfo::ProcessInfo() |
: process_id_(), |
inherited_from_process_id_(), |
@@ -266,6 +336,7 @@ ProcessInfo::ProcessInfo() |
peb_address_(0), |
peb_size_(0), |
modules_(), |
+ memory_info_(), |
is_64_bit_(false), |
is_wow64_(false), |
initialized_() { |
@@ -320,6 +391,15 @@ bool ProcessInfo::Initialize(HANDLE process) { |
return false; |
} |
+ result = |
+ is_64_bit_ |
+ ? ReadMemoryInfo<process_types::internal::Traits64>(process, this) |
+ : ReadMemoryInfo<process_types::internal::Traits32>(process, this); |
+ if (!result) { |
+ LOG(ERROR) << "ReadMemoryInfo failed"; |
+ return false; |
+ } |
+ |
INITIALIZATION_STATE_SET_VALID(initialized_); |
return true; |
} |
@@ -361,4 +441,9 @@ bool ProcessInfo::Modules(std::vector<Module>* modules) const { |
return true; |
} |
+const std::vector<ProcessInfo::MemoryInfo>& ProcessInfo::MemoryInformation() |
+ const { |
+ return memory_info_; |
+} |
+ |
} // namespace crashpad |