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

Side by Side Diff: util/win/process_info.cc

Issue 1375313005: Use MEMORY_BASIC_INFORMATION64 rather than a custom MemoryInfo (Closed) Base URL: https://chromium.googlesource.com/crashpad/crashpad@save-peb-more-2
Patch Set: . Created 5 years, 2 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 unified diff | Download patch
OLDNEW
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,
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
100 PLOG(ERROR) << "ReadProcessMemory " << __FUNCSIG__; 100 PLOG(ERROR) << "ReadProcessMemory " << __FUNCSIG__;
101 return false; 101 return false;
102 } 102 }
103 if (bytes_read != sizeof(T)) { 103 if (bytes_read != sizeof(T)) {
104 LOG(ERROR) << "ReadProcessMemory " << __FUNCSIG__ << " incorrect size"; 104 LOG(ERROR) << "ReadProcessMemory " << __FUNCSIG__ << " incorrect size";
105 return false; 105 return false;
106 } 106 }
107 return true; 107 return true;
108 } 108 }
109 109
110 bool RegionIsAccessible(const ProcessInfo::MemoryInfo& memory_info) { 110 bool RegionIsAccessible(const MEMORY_BASIC_INFORMATION64& memory_info) {
111 return memory_info.state == MEM_COMMIT && 111 return memory_info.State == MEM_COMMIT &&
112 (memory_info.protect & PAGE_NOACCESS) == 0 && 112 (memory_info.Protect & PAGE_NOACCESS) == 0 &&
113 (memory_info.protect & PAGE_GUARD) == 0; 113 (memory_info.Protect & PAGE_GUARD) == 0;
114 }
115
116 MEMORY_BASIC_INFORMATION64 MemoryBasicInformationToMemoryBasicInformation64(
117 const MEMORY_BASIC_INFORMATION& mbi) {
118 MEMORY_BASIC_INFORMATION64 mbi64 = {0};
119 mbi64.BaseAddress = reinterpret_cast<ULONGLONG>(mbi.BaseAddress);
120 mbi64.AllocationBase = reinterpret_cast<ULONGLONG>(mbi.AllocationBase);
121 mbi64.AllocationProtect = mbi.AllocationProtect;
122 mbi64.RegionSize = mbi.RegionSize;
123 mbi64.State = mbi.State;
124 mbi64.Protect = mbi.Protect;
125 mbi64.Type = mbi.Type;
126 return mbi64;
114 } 127 }
115 128
116 } // namespace 129 } // namespace
117 130
118 template <class Traits> 131 template <class Traits>
119 bool GetProcessBasicInformation(HANDLE process, 132 bool GetProcessBasicInformation(HANDLE process,
120 bool is_wow64, 133 bool is_wow64,
121 ProcessInfo* process_info, 134 ProcessInfo* process_info,
122 WinVMAddress* peb_address, 135 WinVMAddress* peb_address,
123 WinVMSize* peb_size) { 136 WinVMSize* peb_size) {
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
281 &memory_basic_information, 294 &memory_basic_information,
282 sizeof(memory_basic_information)); 295 sizeof(memory_basic_information));
283 if (result == 0) { 296 if (result == 0) {
284 if (GetLastError() == ERROR_INVALID_PARAMETER) 297 if (GetLastError() == ERROR_INVALID_PARAMETER)
285 break; 298 break;
286 PLOG(ERROR) << "VirtualQueryEx"; 299 PLOG(ERROR) << "VirtualQueryEx";
287 return false; 300 return false;
288 } 301 }
289 302
290 process_info->memory_info_.push_back( 303 process_info->memory_info_.push_back(
291 ProcessInfo::MemoryInfo(memory_basic_information)); 304 MemoryBasicInformationToMemoryBasicInformation64(
305 memory_basic_information));
292 306
293 if (memory_basic_information.RegionSize == 0) { 307 if (memory_basic_information.RegionSize == 0) {
294 LOG(ERROR) << "RegionSize == 0"; 308 LOG(ERROR) << "RegionSize == 0";
295 return false; 309 return false;
296 } 310 }
297 } 311 }
298 312
299 return true; 313 return true;
300 } 314 }
301 315
302 ProcessInfo::Module::Module() : name(), dll_base(0), size(0), timestamp() { 316 ProcessInfo::Module::Module() : name(), dll_base(0), size(0), timestamp() {
303 } 317 }
304 318
305 ProcessInfo::Module::~Module() { 319 ProcessInfo::Module::~Module() {
306 } 320 }
307 321
308 ProcessInfo::MemoryInfo::MemoryInfo(const MEMORY_BASIC_INFORMATION& mbi)
309 : base_address(reinterpret_cast<WinVMAddress>(mbi.BaseAddress)),
310 region_size(mbi.RegionSize),
311 allocation_base(reinterpret_cast<WinVMAddress>(mbi.AllocationBase)),
312 state(mbi.State),
313 allocation_protect(mbi.AllocationProtect),
314 protect(mbi.Protect),
315 type(mbi.Type) {
316 }
317
318 ProcessInfo::MemoryInfo::~MemoryInfo() {
319 }
320
321 ProcessInfo::ProcessInfo() 322 ProcessInfo::ProcessInfo()
322 : process_id_(), 323 : process_id_(),
323 inherited_from_process_id_(), 324 inherited_from_process_id_(),
324 command_line_(), 325 command_line_(),
325 peb_address_(0), 326 peb_address_(0),
326 peb_size_(0), 327 peb_size_(0),
327 modules_(), 328 modules_(),
328 memory_info_(), 329 memory_info_(),
329 is_64_bit_(false), 330 is_64_bit_(false),
330 is_wow64_(false), 331 is_wow64_(false),
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
419 *peb_address = peb_address_; 420 *peb_address = peb_address_;
420 *peb_size = peb_size_; 421 *peb_size = peb_size_;
421 } 422 }
422 423
423 bool ProcessInfo::Modules(std::vector<Module>* modules) const { 424 bool ProcessInfo::Modules(std::vector<Module>* modules) const {
424 INITIALIZATION_STATE_DCHECK_VALID(initialized_); 425 INITIALIZATION_STATE_DCHECK_VALID(initialized_);
425 *modules = modules_; 426 *modules = modules_;
426 return true; 427 return true;
427 } 428 }
428 429
429 const std::vector<ProcessInfo::MemoryInfo>& ProcessInfo::MemoryInformation() 430 const std::vector<MEMORY_BASIC_INFORMATION64>& ProcessInfo::MemoryInfo() const {
430 const {
431 INITIALIZATION_STATE_DCHECK_VALID(initialized_); 431 INITIALIZATION_STATE_DCHECK_VALID(initialized_);
432 return memory_info_; 432 return memory_info_;
433 } 433 }
434 434
435 std::vector<CheckedRange<WinVMAddress, WinVMSize>> 435 std::vector<CheckedRange<WinVMAddress, WinVMSize>>
436 ProcessInfo::GetReadableRanges( 436 ProcessInfo::GetReadableRanges(
437 const CheckedRange<WinVMAddress, WinVMSize>& range) const { 437 const CheckedRange<WinVMAddress, WinVMSize>& range) const {
438 return GetReadableRangesOfMemoryMap(range, MemoryInformation()); 438 return GetReadableRangesOfMemoryMap(range, MemoryInfo());
439 } 439 }
440 440
441 std::vector<CheckedRange<WinVMAddress, WinVMSize>> GetReadableRangesOfMemoryMap( 441 std::vector<CheckedRange<WinVMAddress, WinVMSize>> GetReadableRangesOfMemoryMap(
442 const CheckedRange<WinVMAddress, WinVMSize>& range, 442 const CheckedRange<WinVMAddress, WinVMSize>& range,
443 const std::vector<ProcessInfo::MemoryInfo>& memory_info) { 443 const std::vector<MEMORY_BASIC_INFORMATION64>& memory_info) {
444 using Range = CheckedRange<WinVMAddress, WinVMSize>; 444 using Range = CheckedRange<WinVMAddress, WinVMSize>;
445 445
446 // Find all the ranges that overlap the target range, maintaining their order. 446 // Find all the ranges that overlap the target range, maintaining their order.
447 std::vector<ProcessInfo::MemoryInfo> overlapping; 447 std::vector<MEMORY_BASIC_INFORMATION64> overlapping;
448 for (const auto& mi : memory_info) { 448 for (const auto& mi : memory_info) {
449 if (range.OverlapsRange(Range(mi.base_address, mi.region_size))) 449 if (range.OverlapsRange(Range(mi.BaseAddress, mi.RegionSize)))
Mark Mentovai 2015/10/07 01:17:24 Since these types are now not WinVMAddress in name
scottmg 2015/10/07 18:19:17 Done.
450 overlapping.push_back(mi); 450 overlapping.push_back(mi);
451 } 451 }
452 if (overlapping.empty()) 452 if (overlapping.empty())
453 return std::vector<Range>(); 453 return std::vector<Range>();
454 454
455 // For the first and last, trim to the boundary of the incoming range. 455 // For the first and last, trim to the boundary of the incoming range.
456 ProcessInfo::MemoryInfo& front = overlapping.front(); 456 MEMORY_BASIC_INFORMATION64& front = overlapping.front();
457 WinVMAddress original_front_base_address = front.base_address; 457 WinVMAddress original_front_base_address = front.BaseAddress;
458 front.base_address = std::max(front.base_address, range.base()); 458 front.BaseAddress = std::max(front.BaseAddress, range.base());
459 front.region_size = 459 front.RegionSize =
460 (original_front_base_address + front.region_size) - front.base_address; 460 (original_front_base_address + front.RegionSize) - front.BaseAddress;
461 461
462 ProcessInfo::MemoryInfo& back = overlapping.back(); 462 MEMORY_BASIC_INFORMATION64& back = overlapping.back();
463 WinVMAddress back_end = back.base_address + back.region_size; 463 WinVMAddress back_end = back.BaseAddress + back.RegionSize;
464 back.region_size = std::min(range.end(), back_end) - back.base_address; 464 back.RegionSize = std::min(range.end(), back_end) - back.BaseAddress;
465 465
466 // Discard all non-accessible. 466 // Discard all non-accessible.
467 overlapping.erase(std::remove_if(overlapping.begin(), 467 overlapping.erase(std::remove_if(overlapping.begin(),
468 overlapping.end(), 468 overlapping.end(),
469 [](const ProcessInfo::MemoryInfo& mi) { 469 [](const MEMORY_BASIC_INFORMATION64& mbi) {
470 return !RegionIsAccessible(mi); 470 return !RegionIsAccessible(mbi);
471 }), 471 }),
472 overlapping.end()); 472 overlapping.end());
473 if (overlapping.empty()) 473 if (overlapping.empty())
474 return std::vector<Range>(); 474 return std::vector<Range>();
475 475
476 // Convert to return type. 476 // Convert to return type.
477 std::vector<Range> as_ranges; 477 std::vector<Range> as_ranges;
478 for (const auto& mi : overlapping) { 478 for (const auto& mi : overlapping) {
479 as_ranges.push_back(Range(mi.base_address, mi.region_size)); 479 as_ranges.push_back(Range(mi.BaseAddress, mi.RegionSize));
480 DCHECK(as_ranges.back().IsValid()); 480 DCHECK(as_ranges.back().IsValid());
481 } 481 }
482 482
483 // Coalesce remaining regions. 483 // Coalesce remaining regions.
484 std::vector<Range> result; 484 std::vector<Range> result;
485 result.push_back(as_ranges[0]); 485 result.push_back(as_ranges[0]);
486 for (size_t i = 1; i < as_ranges.size(); ++i) { 486 for (size_t i = 1; i < as_ranges.size(); ++i) {
487 if (result.back().end() == as_ranges[i].base()) { 487 if (result.back().end() == as_ranges[i].base()) {
488 result.back().SetRange(result.back().base(), 488 result.back().SetRange(result.back().base(),
489 result.back().size() + as_ranges[i].size()); 489 result.back().size() + as_ranges[i].size());
490 } else { 490 } else {
491 result.push_back(as_ranges[i]); 491 result.push_back(as_ranges[i]);
492 } 492 }
493 DCHECK(result.back().IsValid()); 493 DCHECK(result.back().IsValid());
494 } 494 }
495 495
496 return result; 496 return result;
497 } 497 }
498 498
499 } // namespace crashpad 499 } // namespace crashpad
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698