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 <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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |