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

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

Issue 1372183002: win: Add memory map range intersection helper (Closed) Base URL: https://chromium.googlesource.com/crashpad/crashpad@master
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
« no previous file with comments | « util/win/process_info.h ('k') | util/win/process_info_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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,
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 <algorithm>
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 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
97 PLOG(ERROR) << "ReadProcessMemory " << __FUNCSIG__; 99 PLOG(ERROR) << "ReadProcessMemory " << __FUNCSIG__;
98 return false; 100 return false;
99 } 101 }
100 if (bytes_read != sizeof(T)) { 102 if (bytes_read != sizeof(T)) {
101 LOG(ERROR) << "ReadProcessMemory " << __FUNCSIG__ << " incorrect size"; 103 LOG(ERROR) << "ReadProcessMemory " << __FUNCSIG__ << " incorrect size";
102 return false; 104 return false;
103 } 105 }
104 return true; 106 return true;
105 } 107 }
106 108
109 bool RegionIsInaccessible(const ProcessInfo::MemoryInfo& memory_info) {
110 return memory_info.state == MEM_FREE ||
111 (memory_info.state == MEM_COMMIT &&
112 ((memory_info.protect & PAGE_NOACCESS) ||
113 (memory_info.protect & PAGE_GUARD)));
114 }
115
107 } // namespace 116 } // namespace
108 117
109 template <class Traits> 118 template <class Traits>
110 bool GetProcessBasicInformation(HANDLE process, 119 bool GetProcessBasicInformation(HANDLE process,
111 bool is_wow64, 120 bool is_wow64,
112 ProcessInfo* process_info, 121 ProcessInfo* process_info,
113 WinVMAddress* peb_address, 122 WinVMAddress* peb_address,
114 WinVMSize* peb_size) { 123 WinVMSize* peb_size) {
115 ULONG bytes_returned; 124 ULONG bytes_returned;
116 process_types::PROCESS_BASIC_INFORMATION<Traits> process_basic_information; 125 process_types::PROCESS_BASIC_INFORMATION<Traits> process_basic_information;
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after
408 } 417 }
409 418
410 bool ProcessInfo::Modules(std::vector<Module>* modules) const { 419 bool ProcessInfo::Modules(std::vector<Module>* modules) const {
411 INITIALIZATION_STATE_DCHECK_VALID(initialized_); 420 INITIALIZATION_STATE_DCHECK_VALID(initialized_);
412 *modules = modules_; 421 *modules = modules_;
413 return true; 422 return true;
414 } 423 }
415 424
416 const std::vector<ProcessInfo::MemoryInfo>& ProcessInfo::MemoryInformation() 425 const std::vector<ProcessInfo::MemoryInfo>& ProcessInfo::MemoryInformation()
417 const { 426 const {
427 INITIALIZATION_STATE_DCHECK_VALID(initialized_);
418 return memory_info_; 428 return memory_info_;
419 } 429 }
420 430
431 std::vector<CheckedRange<WinVMAddress, WinVMSize>>
432 ProcessInfo::GetReadableRanges(
433 const CheckedRange<WinVMAddress, WinVMSize>& range) const {
434 return GetReadableRangesOfMemoryMap(range, MemoryInformation());
435 }
436
437 std::vector<CheckedRange<WinVMAddress, WinVMSize>> GetReadableRangesOfMemoryMap(
438 const CheckedRange<WinVMAddress, WinVMSize>& range,
439 const std::vector<ProcessInfo::MemoryInfo>& memory_info) {
440 using Range = CheckedRange<WinVMAddress, WinVMSize>;
441
442 // Find all the ranges that overlap the target range, maintaining their order.
443 std::vector<ProcessInfo::MemoryInfo> overlapping;
444 for (const auto& mi : memory_info) {
445 if (range.OverlapsRange(Range(mi.base_address, mi.region_size)))
446 overlapping.push_back(mi);
447 }
448 if (overlapping.empty())
449 return std::vector<Range>();
450
451 // For the first and last, trim to the boundary of the incoming range.
452 ProcessInfo::MemoryInfo& front = overlapping.front();
453 WinVMAddress original_front_base_address = front.base_address;
454 front.base_address = std::max(front.base_address, range.base());
455 front.region_size =
456 (original_front_base_address + front.region_size) - front.base_address;
457
458 ProcessInfo::MemoryInfo& back = overlapping.back();
459 WinVMAddress back_end = back.base_address + back.region_size;
460 back.region_size = std::min(range.end(), back_end) - back.base_address;
461
462 // Discard all non-accessible.
463 overlapping.erase(std::remove_if(overlapping.begin(),
464 overlapping.end(),
465 [](const ProcessInfo::MemoryInfo& mi) {
466 return RegionIsInaccessible(mi);
467 }),
468 overlapping.end());
469 if (overlapping.empty())
470 return std::vector<Range>();
471
472 // Convert to return type.
473 std::vector<Range> as_ranges;
474 for (const auto& mi : overlapping) {
475 as_ranges.push_back(Range(mi.base_address, mi.region_size));
476 DCHECK(as_ranges.back().IsValid());
477 }
478
479 // Coalesce remaining regions.
480 std::vector<Range> result;
481 result.push_back(as_ranges[0]);
482 for (size_t i = 1; i < as_ranges.size(); ++i) {
483 if (result.back().end() == as_ranges[i].base()) {
484 result.back().SetRange(result.back().base(),
485 result.back().size() + as_ranges[i].size());
486 } else {
487 result.push_back(as_ranges[i]);
488 }
489 DCHECK(result.back().IsValid());
490 }
491
492 return result;
493 }
494
421 } // namespace crashpad 495 } // namespace crashpad
OLDNEW
« no previous file with comments | « util/win/process_info.h ('k') | util/win/process_info_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698