diff options
Diffstat (limited to 'libunwindstack/tests/MemoryRemoteTest.cpp')
-rw-r--r-- | libunwindstack/tests/MemoryRemoteTest.cpp | 94 |
1 files changed, 84 insertions, 10 deletions
diff --git a/libunwindstack/tests/MemoryRemoteTest.cpp b/libunwindstack/tests/MemoryRemoteTest.cpp index a66d0c550..8aa4c3f1b 100644 --- a/libunwindstack/tests/MemoryRemoteTest.cpp +++ b/libunwindstack/tests/MemoryRemoteTest.cpp @@ -71,7 +71,7 @@ TEST_F(MemoryRemoteTest, read) { MemoryRemote remote(pid); std::vector<uint8_t> dst(1024); - ASSERT_TRUE(remote.Read(reinterpret_cast<uint64_t>(src.data()), dst.data(), 1024)); + ASSERT_TRUE(remote.ReadFully(reinterpret_cast<uint64_t>(src.data()), dst.data(), 1024)); for (size_t i = 0; i < 1024; i++) { ASSERT_EQ(0x4cU, dst[i]) << "Failed at byte " << i; } @@ -79,6 +79,39 @@ TEST_F(MemoryRemoteTest, read) { ASSERT_TRUE(Detach(pid)); } +TEST_F(MemoryRemoteTest, Read) { + char* mapping = static_cast<char*>( + mmap(nullptr, 2 * getpagesize(), PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)); + + ASSERT_NE(MAP_FAILED, mapping); + + mprotect(mapping + getpagesize(), getpagesize(), PROT_NONE); + memset(mapping + getpagesize() - 1024, 0x4c, 1024); + + pid_t pid; + if ((pid = fork()) == 0) { + while (true) + ; + exit(1); + } + ASSERT_LT(0, pid); + TestScopedPidReaper reap(pid); + + ASSERT_TRUE(Attach(pid)); + + MemoryRemote remote(pid); + + std::vector<uint8_t> dst(4096); + ASSERT_EQ(1024U, remote.Read(reinterpret_cast<uint64_t>(mapping + getpagesize() - 1024), + dst.data(), 4096)); + for (size_t i = 0; i < 1024; i++) { + ASSERT_EQ(0x4cU, dst[i]) << "Failed at byte " << i; + } + + ASSERT_TRUE(Detach(pid)); + ASSERT_EQ(0, munmap(mapping, 2 * getpagesize())); +} + TEST_F(MemoryRemoteTest, read_fail) { int pagesize = getpagesize(); void* src = mmap(nullptr, pagesize * 2, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE,-1, 0); @@ -101,17 +134,17 @@ TEST_F(MemoryRemoteTest, read_fail) { MemoryRemote remote(pid); std::vector<uint8_t> dst(pagesize); - ASSERT_TRUE(remote.Read(reinterpret_cast<uint64_t>(src), dst.data(), pagesize)); + ASSERT_TRUE(remote.ReadFully(reinterpret_cast<uint64_t>(src), dst.data(), pagesize)); for (size_t i = 0; i < 1024; i++) { ASSERT_EQ(0x4cU, dst[i]) << "Failed at byte " << i; } - ASSERT_FALSE(remote.Read(reinterpret_cast<uint64_t>(src) + pagesize, dst.data(), 1)); - ASSERT_TRUE(remote.Read(reinterpret_cast<uint64_t>(src) + pagesize - 1, dst.data(), 1)); - ASSERT_FALSE(remote.Read(reinterpret_cast<uint64_t>(src) + pagesize - 4, dst.data(), 8)); + ASSERT_FALSE(remote.ReadFully(reinterpret_cast<uint64_t>(src) + pagesize, dst.data(), 1)); + ASSERT_TRUE(remote.ReadFully(reinterpret_cast<uint64_t>(src) + pagesize - 1, dst.data(), 1)); + ASSERT_FALSE(remote.ReadFully(reinterpret_cast<uint64_t>(src) + pagesize - 4, dst.data(), 8)); // Check overflow condition is caught properly. - ASSERT_FALSE(remote.Read(UINT64_MAX - 100, dst.data(), 200)); + ASSERT_FALSE(remote.ReadFully(UINT64_MAX - 100, dst.data(), 200)); ASSERT_EQ(0, munmap(src, pagesize)); @@ -119,11 +152,24 @@ TEST_F(MemoryRemoteTest, read_fail) { } TEST_F(MemoryRemoteTest, read_overflow) { - MemoryFakeRemote remote; + pid_t pid; + if ((pid = fork()) == 0) { + while (true) + ; + exit(1); + } + ASSERT_LT(0, pid); + TestScopedPidReaper reap(pid); + + ASSERT_TRUE(Attach(pid)); + + MemoryRemote remote(pid); // Check overflow condition is caught properly. std::vector<uint8_t> dst(200); - ASSERT_FALSE(remote.Read(UINT64_MAX - 100, dst.data(), 200)); + ASSERT_FALSE(remote.ReadFully(UINT64_MAX - 100, dst.data(), 200)); + + ASSERT_TRUE(Detach(pid)); } TEST_F(MemoryRemoteTest, read_illegal) { @@ -140,10 +186,38 @@ TEST_F(MemoryRemoteTest, read_illegal) { MemoryRemote remote(pid); std::vector<uint8_t> dst(100); - ASSERT_FALSE(remote.Read(0, dst.data(), 1)); - ASSERT_FALSE(remote.Read(0, dst.data(), 100)); + ASSERT_FALSE(remote.ReadFully(0, dst.data(), 1)); + ASSERT_FALSE(remote.ReadFully(0, dst.data(), 100)); ASSERT_TRUE(Detach(pid)); } +TEST_F(MemoryRemoteTest, read_hole) { + void* mapping = + mmap(nullptr, 3 * 4096, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); + ASSERT_NE(MAP_FAILED, mapping); + memset(mapping, 0xFF, 3 * 4096); + mprotect(static_cast<char*>(mapping) + 4096, 4096, PROT_NONE); + + pid_t pid; + if ((pid = fork()) == 0) { + while (true); + exit(1); + } + ASSERT_LT(0, pid); + TestScopedPidReaper reap(pid); + + ASSERT_TRUE(Attach(pid)); + + MemoryRemote remote(pid); + std::vector<uint8_t> dst(4096 * 3, 0xCC); + ASSERT_EQ(4096U, remote.Read(reinterpret_cast<uintptr_t>(mapping), dst.data(), 4096 * 3)); + for (size_t i = 0; i < 4096; ++i) { + ASSERT_EQ(0xFF, dst[i]); + } + for (size_t i = 4096; i < 4096 * 3; ++i) { + ASSERT_EQ(0xCC, dst[i]); + } +} + } // namespace unwindstack |