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

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
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 256 matching lines...) Expand 10 before | Expand all | Expand 10 after
285 287
286 return true; 288 return true;
287 } 289 }
288 290
289 ProcessInfo::Module::Module() : name(), dll_base(0), size(0), timestamp() { 291 ProcessInfo::Module::Module() : name(), dll_base(0), size(0), timestamp() {
290 } 292 }
291 293
292 ProcessInfo::Module::~Module() { 294 ProcessInfo::Module::~Module() {
293 } 295 }
294 296
297 ProcessInfo::MemoryInfo::MemoryInfo()
298 : base_address(0),
299 region_size(0),
300 allocation_base(0),
301 state(0),
302 allocation_protect(0),
303 protect(0),
304 type(0) {
305 }
306
295 ProcessInfo::MemoryInfo::MemoryInfo(const MEMORY_BASIC_INFORMATION& mbi) 307 ProcessInfo::MemoryInfo::MemoryInfo(const MEMORY_BASIC_INFORMATION& mbi)
296 : base_address(reinterpret_cast<WinVMAddress>(mbi.BaseAddress)), 308 : base_address(reinterpret_cast<WinVMAddress>(mbi.BaseAddress)),
297 region_size(mbi.RegionSize), 309 region_size(mbi.RegionSize),
298 allocation_base(reinterpret_cast<WinVMAddress>(mbi.AllocationBase)), 310 allocation_base(reinterpret_cast<WinVMAddress>(mbi.AllocationBase)),
299 state(mbi.State), 311 state(mbi.State),
300 allocation_protect(mbi.AllocationProtect), 312 allocation_protect(mbi.AllocationProtect),
301 protect(mbi.Protect), 313 protect(mbi.Protect),
302 type(mbi.Type) { 314 type(mbi.Type) {
303 } 315 }
304 316
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
408 } 420 }
409 421
410 bool ProcessInfo::Modules(std::vector<Module>* modules) const { 422 bool ProcessInfo::Modules(std::vector<Module>* modules) const {
411 INITIALIZATION_STATE_DCHECK_VALID(initialized_); 423 INITIALIZATION_STATE_DCHECK_VALID(initialized_);
412 *modules = modules_; 424 *modules = modules_;
413 return true; 425 return true;
414 } 426 }
415 427
416 const std::vector<ProcessInfo::MemoryInfo>& ProcessInfo::MemoryInformation() 428 const std::vector<ProcessInfo::MemoryInfo>& ProcessInfo::MemoryInformation()
417 const { 429 const {
430 INITIALIZATION_STATE_DCHECK_VALID(initialized_);
418 return memory_info_; 431 return memory_info_;
419 } 432 }
420 433
434 std::vector<CheckedRange<WinVMAddress, WinVMSize>>
435 GetAccessibleRangesInMemoryMap(
436 WinVMAddress address,
437 WinVMSize size,
438 const std::vector<ProcessInfo::MemoryInfo>& memory_info) {
439 std::vector<ProcessInfo::MemoryInfo> overlapping;
440
441 using Range = CheckedRange<WinVMAddress, WinVMSize>;
442
443 // Find all the ranges that overlap the target range, maintaining their order.
444 for (const auto& mi : memory_info) {
445 if (mi.base_address + mi.region_size <= address)
Mark Mentovai 2015/09/29 21:35:50 Optional, but since you’re using CheckedRange in h
scottmg 2015/09/30 17:40:26 Done. (Sadly std::copy_if is more unwieldy than a
446 continue;
447 if (mi.base_address >= address + size)
448 continue;
449 overlapping.push_back(mi);
450 }
451
452 if (overlapping.empty())
453 return std::vector<Range>();
454
455 // For the first and last, trim to the boundary of the incoming range.
456 ProcessInfo::MemoryInfo& front = overlapping.front();
457 if (front.base_address < address) {
Mark Mentovai 2015/09/29 21:35:50 Everything should be valid without this if, and wi
scottmg 2015/09/30 17:40:26 Done.
458 WinVMAddress original_base = front.base_address;
459 front.base_address = address;
460 front.region_size = (original_base + front.region_size) - address;
461 }
462
463 ProcessInfo::MemoryInfo& back = overlapping.back();
464 if (back.base_address + back.region_size >= address + size) {
465 back.region_size = (address + size) - back.base_address;
466 }
467
468 // Discard all non-accessible.
469 overlapping.erase(std::remove_if(overlapping.begin(),
Mark Mentovai 2015/09/29 21:35:50 I like seeing the standard library being used so n
470 overlapping.end(),
471 [](const ProcessInfo::MemoryInfo& mi) {
472 return mi.state == MEM_FREE;
473 }),
474 overlapping.end());
475
476 if (overlapping.empty())
477 return std::vector<Range>();
478
479 // Convert to return type.
480 std::vector<Range> as_ranges;
481 for (const auto& mi : overlapping) {
482 as_ranges.push_back(Range(mi.base_address, mi.region_size));
Mark Mentovai 2015/09/29 21:35:50 You’re not actually using any of the checking feat
scottmg 2015/09/30 17:40:25 Yeah, it was just a handy representation of a rang
483 }
484
485 // Coalesce remaining regions.
486 std::vector<Range> result;
487 result.push_back(as_ranges[0]);
488 for (size_t i = 1; i < as_ranges.size(); ++i) {
489 if (result.back().end() == as_ranges[i].base()) {
490 result.back().SetRange(result.back().base(),
491 result.back().size() + as_ranges[i].size());
492 } else {
493 result.push_back(as_ranges[i]);
494 }
495 }
496
497 return result;
498 }
499
421 } // namespace crashpad 500 } // namespace crashpad
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698