| OLD | NEW |
| 1 // Copyright 2015 The Crashpad Authors. All rights reserved. | 1 // Copyright 2015 The Crashpad Authors. All rights reserved. |
| 2 // | 2 // |
| 3 // Licensed under the Apache License, Version 2.0 (the "License"); | 3 // Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 // you may not use this file except in compliance with the License. | 4 // you may not use this file except in compliance with the License. |
| 5 // You may obtain a copy of the License at | 5 // You may obtain a copy of the License at |
| 6 // | 6 // |
| 7 // http://www.apache.org/licenses/LICENSE-2.0 | 7 // http://www.apache.org/licenses/LICENSE-2.0 |
| 8 // | 8 // |
| 9 // Unless required by applicable law or agreed to in writing, software | 9 // Unless required by applicable law or agreed to in writing, software |
| 10 // distributed under the License is distributed on an "AS IS" BASIS, | 10 // distributed under the License is distributed on an "AS IS" BASIS, |
| 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 // See the License for the specific language governing permissions and | 12 // See the License for the specific language governing permissions and |
| 13 // limitations under the License. | 13 // limitations under the License. |
| 14 | 14 |
| 15 #include "util/win/process_info.h" | 15 #include "util/win/process_info.h" |
| 16 | 16 |
| 17 #include <winternl.h> | 17 #include <winternl.h> |
| 18 | 18 |
| 19 #include <limits> |
| 20 |
| 19 #include "base/logging.h" | 21 #include "base/logging.h" |
| 20 #include "base/strings/stringprintf.h" | 22 #include "base/strings/stringprintf.h" |
| 21 #include "build/build_config.h" | 23 #include "build/build_config.h" |
| 22 #include "util/numeric/safe_assignment.h" | 24 #include "util/numeric/safe_assignment.h" |
| 23 #include "util/win/ntstatus_logging.h" | 25 #include "util/win/ntstatus_logging.h" |
| 24 #include "util/win/process_structs.h" | 26 #include "util/win/process_structs.h" |
| 25 | 27 |
| 26 namespace crashpad { | 28 namespace crashpad { |
| 27 | 29 |
| 28 namespace { | 30 namespace { |
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 246 module.size = ldr_data_table_entry.SizeOfImage; | 248 module.size = ldr_data_table_entry.SizeOfImage; |
| 247 module.timestamp = ldr_data_table_entry.TimeDateStamp; | 249 module.timestamp = ldr_data_table_entry.TimeDateStamp; |
| 248 process_info->modules_.push_back(module); | 250 process_info->modules_.push_back(module); |
| 249 if (cur == last) | 251 if (cur == last) |
| 250 break; | 252 break; |
| 251 } | 253 } |
| 252 | 254 |
| 253 return true; | 255 return true; |
| 254 } | 256 } |
| 255 | 257 |
| 256 bool ReadMemoryInfo(HANDLE process, ProcessInfo* process_info) { | 258 bool ReadMemoryInfo(HANDLE process, bool is_64_bit, ProcessInfo* process_info) { |
| 257 DCHECK(process_info->memory_info_.empty()); | 259 DCHECK(process_info->memory_info_.empty()); |
| 258 | 260 |
| 259 SYSTEM_INFO system_info; | 261 const WinVMAddress min_address = 0; |
| 260 GetSystemInfo(&system_info); | 262 // We can't use GetSystemInfo() to get the address space range for another |
| 261 const WinVMAddress min_address = | 263 // process. VirtualQueryEx() will fail with ERROR_INVALID_PARAMETER if the |
| 262 reinterpret_cast<WinVMAddress>(system_info.lpMinimumApplicationAddress); | 264 // address is above the highest memory address accessible to the process, so |
| 263 const WinVMAddress max_address = | 265 // we just probe the entire potential range (2^32 for x86, or 2^64 for x64). |
| 264 reinterpret_cast<WinVMAddress>(system_info.lpMaximumApplicationAddress); | 266 const WinVMAddress max_address = is_64_bit |
| 267 ? std::numeric_limits<uint64_t>::max() |
| 268 : std::numeric_limits<uint32_t>::max(); |
| 265 MEMORY_BASIC_INFORMATION memory_basic_information; | 269 MEMORY_BASIC_INFORMATION memory_basic_information; |
| 266 for (WinVMAddress address = min_address; address <= max_address; | 270 for (WinVMAddress address = min_address; address <= max_address; |
| 267 address += memory_basic_information.RegionSize) { | 271 address += memory_basic_information.RegionSize) { |
| 268 size_t result = VirtualQueryEx(process, | 272 size_t result = VirtualQueryEx(process, |
| 269 reinterpret_cast<void*>(address), | 273 reinterpret_cast<void*>(address), |
| 270 &memory_basic_information, | 274 &memory_basic_information, |
| 271 sizeof(memory_basic_information)); | 275 sizeof(memory_basic_information)); |
| 272 if (result == 0) { | 276 if (result == 0) { |
| 277 if (GetLastError() == ERROR_INVALID_PARAMETER) |
| 278 break; |
| 273 PLOG(ERROR) << "VirtualQueryEx"; | 279 PLOG(ERROR) << "VirtualQueryEx"; |
| 274 return false; | 280 return false; |
| 275 } | 281 } |
| 276 | 282 |
| 277 process_info->memory_info_.push_back( | 283 process_info->memory_info_.push_back( |
| 278 ProcessInfo::MemoryInfo(memory_basic_information)); | 284 ProcessInfo::MemoryInfo(memory_basic_information)); |
| 279 | 285 |
| 280 if (memory_basic_information.RegionSize == 0) { | 286 if (memory_basic_information.RegionSize == 0) { |
| 281 LOG(ERROR) << "RegionSize == 0"; | 287 LOG(ERROR) << "RegionSize == 0"; |
| 282 return false; | 288 return false; |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 360 | 366 |
| 361 result = is_64_bit_ ? ReadProcessData<process_types::internal::Traits64>( | 367 result = is_64_bit_ ? ReadProcessData<process_types::internal::Traits64>( |
| 362 process, peb_address_, this) | 368 process, peb_address_, this) |
| 363 : ReadProcessData<process_types::internal::Traits32>( | 369 : ReadProcessData<process_types::internal::Traits32>( |
| 364 process, peb_address_, this); | 370 process, peb_address_, this); |
| 365 if (!result) { | 371 if (!result) { |
| 366 LOG(ERROR) << "ReadProcessData failed"; | 372 LOG(ERROR) << "ReadProcessData failed"; |
| 367 return false; | 373 return false; |
| 368 } | 374 } |
| 369 | 375 |
| 370 if (!ReadMemoryInfo(process, this)) { | 376 if (!ReadMemoryInfo(process, is_64_bit_, this)) { |
| 371 LOG(ERROR) << "ReadMemoryInfo failed"; | 377 LOG(ERROR) << "ReadMemoryInfo failed"; |
| 372 return false; | 378 return false; |
| 373 } | 379 } |
| 374 | 380 |
| 375 INITIALIZATION_STATE_SET_VALID(initialized_); | 381 INITIALIZATION_STATE_SET_VALID(initialized_); |
| 376 return true; | 382 return true; |
| 377 } | 383 } |
| 378 | 384 |
| 379 bool ProcessInfo::Is64Bit() const { | 385 bool ProcessInfo::Is64Bit() const { |
| 380 INITIALIZATION_STATE_DCHECK_VALID(initialized_); | 386 INITIALIZATION_STATE_DCHECK_VALID(initialized_); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 412 *modules = modules_; | 418 *modules = modules_; |
| 413 return true; | 419 return true; |
| 414 } | 420 } |
| 415 | 421 |
| 416 const std::vector<ProcessInfo::MemoryInfo>& ProcessInfo::MemoryInformation() | 422 const std::vector<ProcessInfo::MemoryInfo>& ProcessInfo::MemoryInformation() |
| 417 const { | 423 const { |
| 418 return memory_info_; | 424 return memory_info_; |
| 419 } | 425 } |
| 420 | 426 |
| 421 } // namespace crashpad | 427 } // namespace crashpad |
| OLD | NEW |