Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(205)

Unified Diff: util/win/process_info.cc

Issue 1336823002: win x86: Grab bag of restructuring to get tests working on x86-on-x86 (Closed) Base URL: https://chromium.googlesource.com/crashpad/crashpad@master
Patch Set: fixes2 Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: util/win/process_info.cc
diff --git a/util/win/process_info.cc b/util/win/process_info.cc
index ca8277ed0308736ad257a3b5c9ef46deee356cb7..f7d1c5de839fe94c52dfa3a970e81e44f37dfd00 100644
--- a/util/win/process_info.cc
+++ b/util/win/process_info.cc
@@ -17,7 +17,10 @@
#include <winternl.h>
#include "base/logging.h"
+#include "base/strings/stringprintf.h"
+#include "build/build_config.h"
#include "util/numeric/safe_assignment.h"
+#include "util/win/ntstatus_logging.h"
#include "util/win/process_structs.h"
namespace crashpad {
@@ -80,7 +83,8 @@ bool ReadUnicodeString(HANDLE process,
return true;
}
-template <class T> bool ReadStruct(HANDLE process, WinVMAddress at, T* into) {
+template <class T>
+bool ReadStruct(HANDLE process, WinVMAddress at, T* into) {
SIZE_T bytes_read;
if (!ReadProcessMemory(process,
reinterpret_cast<const void*>(at),
@@ -102,13 +106,71 @@ template <class T> bool ReadStruct(HANDLE process, WinVMAddress at, T* into) {
} // namespace
template <class Traits>
+bool GetProcessBasicInformation(HANDLE process,
+ bool is_wow64,
+ ProcessInfo* process_info,
+ WinVMAddress* peb_address) {
+ ULONG bytes_returned;
+ process_types::PROCESS_BASIC_INFORMATION<Traits> process_basic_information;
+ NTSTATUS status =
+ crashpad::NtQueryInformationProcess(process,
+ ProcessBasicInformation,
+ &process_basic_information,
+ sizeof(process_basic_information),
+ &bytes_returned);
+ if (!NT_SUCCESS(status)) {
+ NTSTATUS_LOG(ERROR, status) << "NtQueryInformationProcess";
+ return false;
+ }
+ if (bytes_returned != sizeof(process_basic_information)) {
+ LOG(ERROR) << "NtQueryInformationProcess incorrect size";
+ return false;
+ }
+
+ // See https://msdn.microsoft.com/en-us/library/windows/desktop/aa384203 on
+ // 32 bit being the correct size for HANDLEs for proceses, even on Windows
+ // x64. API functions (e.g. OpenProcess) take only a DWORD, so there's no
+ // sense in maintaining the top bits.
+ process_info->process_id_ =
+ static_cast<DWORD>(process_basic_information.UniqueProcessId);
+ process_info->inherited_from_process_id_ = static_cast<DWORD>(
+ process_basic_information.InheritedFromUniqueProcessId);
+
+ // We now want to read the PEB to gather the rest of our information. The
+ // PebBaseAddress as returned above is what we want for 64-on-64 and 32-on-32,
+ // but for Wow64, we want to read the 32 bit PEB (a Wow64 process has both).
+ // The address of this is found by a second call to NtQueryInformationProcess.
+ if (!is_wow64) {
+ *peb_address = process_basic_information.PebBaseAddress;
+ } else {
+ ULONG_PTR wow64_peb_address;
+ status = crashpad::NtQueryInformationProcess(process,
+ ProcessWow64Information,
+ &wow64_peb_address,
+ sizeof(wow64_peb_address),
+ &bytes_returned);
+ if (!NT_SUCCESS(status)) {
+ NTSTATUS_LOG(ERROR, status), "NtQueryInformationProcess";
+ return false;
+ }
+ if (bytes_returned != sizeof(wow64_peb_address)) {
+ LOG(ERROR) << "NtQueryInformationProcess incorrect size";
+ return false;
+ }
+ *peb_address = wow64_peb_address;
+ }
+
+ return true;
+}
+
+template <class Traits>
bool ReadProcessData(HANDLE process,
WinVMAddress peb_address_vmaddr,
ProcessInfo* process_info) {
Traits::Pointer peb_address;
if (!AssignIfInRange(&peb_address, peb_address_vmaddr)) {
- LOG(ERROR) << "peb_address_vmaddr " << peb_address_vmaddr
- << " out of range";
+ LOG(ERROR) << base::StringPrintf("peb address 0x%x out of range",
+ peb_address_vmaddr);
return false;
}
@@ -232,73 +294,28 @@ bool ProcessInfo::Initialize(HANDLE process) {
}
#endif
- ULONG bytes_returned;
- // We assume this process is not running on Wow64. The
- // PROCESS_BASIC_INFORMATION uses the OS size (that is, even Wow64 has a 64
- // bit one.)
- // TODO(scottmg): Either support running as Wow64, or check/resolve this at a
- // higher level.
-#if ARCH_CPU_32_BITS
- process_types::PROCESS_BASIC_INFORMATION<process_types::internal::Traits32>
- process_basic_information;
+ WinVMAddress peb_address;
+#if ARCH_CPU_64_BITS
+ bool result = GetProcessBasicInformation<process_types::internal::Traits64>(
+ process, is_wow64_, this, &peb_address);
#else
- process_types::PROCESS_BASIC_INFORMATION<process_types::internal::Traits64>
- process_basic_information;
-#endif
- NTSTATUS status =
- crashpad::NtQueryInformationProcess(process,
- ProcessBasicInformation,
- &process_basic_information,
- sizeof(process_basic_information),
- &bytes_returned);
- if (status < 0) {
- LOG(ERROR) << "NtQueryInformationProcess: status=" << status;
- return false;
- }
- if (bytes_returned != sizeof(process_basic_information)) {
- LOG(ERROR) << "NtQueryInformationProcess incorrect size";
- return false;
- }
+ bool result = GetProcessBasicInformation<process_types::internal::Traits32>(
+ process, false, this, &peb_address);
+#endif // ARCH_CPU_64_BITS
- // See https://msdn.microsoft.com/en-us/library/windows/desktop/aa384203 on
- // 32 bit being the correct size for HANDLEs for proceses, even on Windows
- // x64. API functions (e.g. OpenProcess) take only a DWORD, so there's no
- // sense in maintaining the top bits.
- process_id_ = static_cast<DWORD>(process_basic_information.UniqueProcessId);
- inherited_from_process_id_ = static_cast<DWORD>(
- process_basic_information.InheritedFromUniqueProcessId);
-
- // We now want to read the PEB to gather the rest of our information. The
- // PebBaseAddress as returned above is what we want for 64-on-64 and 32-on-32,
- // but for Wow64, we want to read the 32 bit PEB (a Wow64 process has both).
- // The address of this is found by a second call to NtQueryInformationProcess.
- WinVMAddress peb_address = process_basic_information.PebBaseAddress;
- if (is_wow64_) {
- ULONG_PTR wow64_peb_address;
- status =
- crashpad::NtQueryInformationProcess(process,
- ProcessWow64Information,
- &wow64_peb_address,
- sizeof(wow64_peb_address),
- &bytes_returned);
- if (status < 0) {
- LOG(ERROR) << "NtQueryInformationProcess: status=" << status;
- return false;
- }
- if (bytes_returned != sizeof(wow64_peb_address)) {
- LOG(ERROR) << "NtQueryInformationProcess incorrect size";
- return false;
- }
- peb_address = wow64_peb_address;
+ if (!result) {
+ LOG(ERROR) << "GetProcessBasicInformation failed";
+ return false;
}
- // Read the PEB data using the correct word size.
- bool result = is_64_bit_ ? ReadProcessData<process_types::internal::Traits64>(
+ result = is_64_bit_ ? ReadProcessData<process_types::internal::Traits64>(
process, peb_address, this)
: ReadProcessData<process_types::internal::Traits32>(
process, peb_address, this);
- if (!result)
+ if (!result) {
+ LOG(ERROR) << "ReadProcessData failed";
return false;
+ }
INITIALIZATION_STATE_SET_VALID(initialized_);
return true;

Powered by Google App Engine
This is Rietveld 408576698