| Index: util/win/process_info_test.cc
|
| diff --git a/util/win/process_info_test.cc b/util/win/process_info_test.cc
|
| index d3d674dd875ad10131145d151731abde57776915..71269a5989b1ed52f587cc4e7f3a4914d5095147 100644
|
| --- a/util/win/process_info_test.cc
|
| +++ b/util/win/process_info_test.cc
|
| @@ -19,6 +19,7 @@
|
| #include <wchar.h>
|
|
|
| #include "base/files/file_path.h"
|
| +#include "base/memory/scoped_ptr.h"
|
| #include "build/build_config.h"
|
| #include "gtest/gtest.h"
|
| #include "test/paths.h"
|
| @@ -228,7 +229,7 @@ TEST(ProcessInfo, AccessibleRangesOneInside) {
|
| GetReadableRangesOfMemoryMap(CheckedRange<WinVMAddress, WinVMSize>(2, 4),
|
| memory_info);
|
|
|
| - ASSERT_EQ(result.size(), 1u);
|
| + ASSERT_EQ(1u, result.size());
|
| EXPECT_EQ(2, result[0].base());
|
| EXPECT_EQ(4, result[0].size());
|
| }
|
| @@ -251,7 +252,7 @@ TEST(ProcessInfo, AccessibleRangesOneTruncatedSize) {
|
| GetReadableRangesOfMemoryMap(CheckedRange<WinVMAddress, WinVMSize>(5, 10),
|
| memory_info);
|
|
|
| - ASSERT_EQ(result.size(), 1u);
|
| + ASSERT_EQ(1u, result.size());
|
| EXPECT_EQ(5, result[0].base());
|
| EXPECT_EQ(5, result[0].size());
|
| }
|
| @@ -274,7 +275,80 @@ TEST(ProcessInfo, AccessibleRangesOneMovedStart) {
|
| GetReadableRangesOfMemoryMap(CheckedRange<WinVMAddress, WinVMSize>(5, 10),
|
| memory_info);
|
|
|
| - ASSERT_EQ(result.size(), 1u);
|
| + ASSERT_EQ(1u, result.size());
|
| + EXPECT_EQ(10, result[0].base());
|
| + EXPECT_EQ(5, result[0].size());
|
| +}
|
| +
|
| +TEST(ProcessInfo, ReserveIsInaccessible) {
|
| + std::vector<ProcessInfo::MemoryInfo> memory_info;
|
| + MEMORY_BASIC_INFORMATION mbi = {0};
|
| +
|
| + mbi.BaseAddress = 0;
|
| + mbi.RegionSize = 10;
|
| + mbi.State = MEM_RESERVE;
|
| + memory_info.push_back(ProcessInfo::MemoryInfo(mbi));
|
| +
|
| + mbi.BaseAddress = reinterpret_cast<void*>(10);
|
| + mbi.RegionSize = 20;
|
| + mbi.State = MEM_COMMIT;
|
| + memory_info.push_back(ProcessInfo::MemoryInfo(mbi));
|
| +
|
| + std::vector<CheckedRange<WinVMAddress, WinVMSize>> result =
|
| + GetReadableRangesOfMemoryMap(CheckedRange<WinVMAddress, WinVMSize>(5, 10),
|
| + memory_info);
|
| +
|
| + ASSERT_EQ(1u, result.size());
|
| + EXPECT_EQ(10, result[0].base());
|
| + EXPECT_EQ(5, result[0].size());
|
| +}
|
| +
|
| +TEST(ProcessInfo, PageGuardIsInaccessible) {
|
| + std::vector<ProcessInfo::MemoryInfo> memory_info;
|
| + MEMORY_BASIC_INFORMATION mbi = {0};
|
| +
|
| + mbi.BaseAddress = 0;
|
| + mbi.RegionSize = 10;
|
| + mbi.State = MEM_COMMIT;
|
| + mbi.Protect = PAGE_GUARD;
|
| + memory_info.push_back(ProcessInfo::MemoryInfo(mbi));
|
| +
|
| + mbi.BaseAddress = reinterpret_cast<void*>(10);
|
| + mbi.RegionSize = 20;
|
| + mbi.State = MEM_COMMIT;
|
| + mbi.Protect = 0;
|
| + memory_info.push_back(ProcessInfo::MemoryInfo(mbi));
|
| +
|
| + std::vector<CheckedRange<WinVMAddress, WinVMSize>> result =
|
| + GetReadableRangesOfMemoryMap(CheckedRange<WinVMAddress, WinVMSize>(5, 10),
|
| + memory_info);
|
| +
|
| + ASSERT_EQ(1u, result.size());
|
| + EXPECT_EQ(10, result[0].base());
|
| + EXPECT_EQ(5, result[0].size());
|
| +}
|
| +
|
| +TEST(ProcessInfo, PageNoAccessIsInaccessible) {
|
| + std::vector<ProcessInfo::MemoryInfo> memory_info;
|
| + MEMORY_BASIC_INFORMATION mbi = {0};
|
| +
|
| + mbi.BaseAddress = 0;
|
| + mbi.RegionSize = 10;
|
| + mbi.State = MEM_COMMIT;
|
| + mbi.Protect = PAGE_NOACCESS;
|
| + memory_info.push_back(ProcessInfo::MemoryInfo(mbi));
|
| +
|
| + mbi.BaseAddress = reinterpret_cast<void*>(10);
|
| + mbi.RegionSize = 20;
|
| + mbi.State = MEM_COMMIT;
|
| + mbi.Protect = 0;
|
| + memory_info.push_back(ProcessInfo::MemoryInfo(mbi));
|
| +
|
| + std::vector<CheckedRange<WinVMAddress, WinVMSize>> result =
|
| + GetReadableRangesOfMemoryMap(CheckedRange<WinVMAddress, WinVMSize>(5, 10),
|
| + memory_info);
|
| +
|
| + ASSERT_EQ(1u, result.size());
|
| EXPECT_EQ(10, result[0].base());
|
| EXPECT_EQ(5, result[0].size());
|
| }
|
| @@ -295,14 +369,14 @@ TEST(ProcessInfo, AccessibleRangesCoalesced) {
|
|
|
| mbi.BaseAddress = reinterpret_cast<void*>(12);
|
| mbi.RegionSize = 5;
|
| - mbi.State = MEM_RESERVE;
|
| + mbi.State = MEM_COMMIT;
|
| memory_info.push_back(ProcessInfo::MemoryInfo(mbi));
|
|
|
| std::vector<CheckedRange<WinVMAddress, WinVMSize>> result =
|
| GetReadableRangesOfMemoryMap(CheckedRange<WinVMAddress, WinVMSize>(11, 4),
|
| memory_info);
|
|
|
| - ASSERT_EQ(result.size(), 1u);
|
| + ASSERT_EQ(1u, result.size());
|
| EXPECT_EQ(11, result[0].base());
|
| EXPECT_EQ(4, result[0].size());
|
| }
|
| @@ -330,7 +404,7 @@ TEST(ProcessInfo, AccessibleRangesMiddleUnavailable) {
|
| GetReadableRangesOfMemoryMap(CheckedRange<WinVMAddress, WinVMSize>(5, 45),
|
| memory_info);
|
|
|
| - ASSERT_EQ(result.size(), 2u);
|
| + ASSERT_EQ(2u, result.size());
|
| EXPECT_EQ(5, result[0].base());
|
| EXPECT_EQ(5, result[0].size());
|
| EXPECT_EQ(15, result[1].base());
|
| @@ -350,7 +424,7 @@ TEST(ProcessInfo, RequestedBeforeMap) {
|
| GetReadableRangesOfMemoryMap(CheckedRange<WinVMAddress, WinVMSize>(5, 10),
|
| memory_info);
|
|
|
| - ASSERT_EQ(result.size(), 1u);
|
| + ASSERT_EQ(1u, result.size());
|
| EXPECT_EQ(10, result[0].base());
|
| EXPECT_EQ(5, result[0].size());
|
| }
|
| @@ -368,11 +442,83 @@ TEST(ProcessInfo, RequestedAfterMap) {
|
| GetReadableRangesOfMemoryMap(
|
| CheckedRange<WinVMAddress, WinVMSize>(15, 100), memory_info);
|
|
|
| - ASSERT_EQ(result.size(), 1u);
|
| + ASSERT_EQ(1u, result.size());
|
| EXPECT_EQ(15, result[0].base());
|
| EXPECT_EQ(5, result[0].size());
|
| }
|
|
|
| +TEST(ProcessInfo, ReadableRanges) {
|
| + SYSTEM_INFO system_info;
|
| + GetSystemInfo(&system_info);
|
| +
|
| + const size_t kBlockSize = system_info.dwPageSize;
|
| +
|
| + // Allocate 6 pages, and then commit the second, fourth, and fifth, and mark
|
| + // two as committed, but PAGE_NOACCESS, so we have a setup like this:
|
| + // 0 1 2 3 4 5
|
| + // +-----------------------------------------------+
|
| + // | ????? | | xxxxx | | | ????? |
|
| + // +-----------------------------------------------+
|
| + void* reserve_region =
|
| + VirtualAlloc(nullptr, kBlockSize * 6, MEM_RESERVE, PAGE_READWRITE);
|
| + ASSERT_TRUE(reserve_region);
|
| + uintptr_t reserved_as_int = reinterpret_cast<uintptr_t>(reserve_region);
|
| + void* readable1 =
|
| + VirtualAlloc(reinterpret_cast<void*>(reserved_as_int + kBlockSize),
|
| + kBlockSize,
|
| + MEM_COMMIT,
|
| + PAGE_READWRITE);
|
| + ASSERT_TRUE(readable1);
|
| + void* readable2 =
|
| + VirtualAlloc(reinterpret_cast<void*>(reserved_as_int + (kBlockSize * 3)),
|
| + kBlockSize * 2,
|
| + MEM_COMMIT,
|
| + PAGE_READWRITE);
|
| + ASSERT_TRUE(readable2);
|
| +
|
| + void* no_access =
|
| + VirtualAlloc(reinterpret_cast<void*>(reserved_as_int + (kBlockSize * 2)),
|
| + kBlockSize,
|
| + MEM_COMMIT,
|
| + PAGE_NOACCESS);
|
| + ASSERT_TRUE(no_access);
|
| +
|
| + HANDLE current_process = GetCurrentProcess();
|
| + ProcessInfo info;
|
| + info.Initialize(current_process);
|
| + auto ranges = info.GetReadableRanges(
|
| + CheckedRange<WinVMAddress, WinVMSize>(reserved_as_int, kBlockSize * 6));
|
| +
|
| + ASSERT_EQ(2u, ranges.size());
|
| + EXPECT_EQ(reserved_as_int + kBlockSize, ranges[0].base());
|
| + EXPECT_EQ(kBlockSize, ranges[0].size());
|
| + EXPECT_EQ(reserved_as_int + (kBlockSize * 3), ranges[1].base());
|
| + EXPECT_EQ(kBlockSize * 2, ranges[1].size());
|
| +
|
| + // Also make sure what we think we can read corresponds with what we can
|
| + // actually read.
|
| + scoped_ptr<unsigned char[]> into(new unsigned char[kBlockSize * 6]);
|
| + SIZE_T bytes_read;
|
| +
|
| + EXPECT_TRUE(ReadProcessMemory(
|
| + current_process, readable1, into.get(), kBlockSize, &bytes_read));
|
| + EXPECT_EQ(kBlockSize, bytes_read);
|
| +
|
| + EXPECT_TRUE(ReadProcessMemory(
|
| + current_process, readable2, into.get(), kBlockSize * 2, &bytes_read));
|
| + EXPECT_EQ(kBlockSize * 2, bytes_read);
|
| +
|
| + EXPECT_FALSE(ReadProcessMemory(
|
| + current_process, no_access, into.get(), kBlockSize, &bytes_read));
|
| + EXPECT_FALSE(ReadProcessMemory(
|
| + current_process, reserve_region, into.get(), kBlockSize, &bytes_read));
|
| + EXPECT_FALSE(ReadProcessMemory(current_process,
|
| + reserve_region,
|
| + into.get(),
|
| + kBlockSize * 6,
|
| + &bytes_read));
|
| +}
|
| +
|
| } // namespace
|
| } // namespace test
|
| } // namespace crashpad
|
|
|