diff options
author | Christopher Ferris <cferris@google.com> | 2018-12-13 03:18:58 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2018-12-13 03:18:58 +0000 |
commit | 583ce2deff4caa28fdadd80796cce41e6e7be99a (patch) | |
tree | 80ddb0ae99831f16c5feaaa4d9244fdf60c2dbd1 /libunwindstack | |
parent | 78f94a39f24c2d8b5f988627d12b44a48a8b0bc7 (diff) | |
parent | 01040b10b2393014c2d49265b6ef75a1a2a459a7 (diff) | |
download | system_core-583ce2deff4caa28fdadd80796cce41e6e7be99a.tar.gz system_core-583ce2deff4caa28fdadd80796cce41e6e7be99a.tar.bz2 system_core-583ce2deff4caa28fdadd80796cce41e6e7be99a.zip |
Merge "Fix handling of ro segments for embedded libs."
Diffstat (limited to 'libunwindstack')
23 files changed, 300 insertions, 45 deletions
diff --git a/libunwindstack/Android.bp b/libunwindstack/Android.bp index a5e0dc9f2..4e0470e38 100644 --- a/libunwindstack/Android.bp +++ b/libunwindstack/Android.bp @@ -235,6 +235,8 @@ cc_test { "tests/files/offline/jit_map_arm/*", "tests/files/offline/gnu_debugdata_arm/*", "tests/files/offline/offset_arm/*", + "tests/files/offline/shared_lib_in_apk_arm64/*", + "tests/files/offline/shared_lib_in_apk_memory_only_arm64/*", "tests/files/offline/straddle_arm/*", "tests/files/offline/straddle_arm64/*", ], diff --git a/libunwindstack/MapInfo.cpp b/libunwindstack/MapInfo.cpp index e3b48ca25..44ec5c1d2 100644 --- a/libunwindstack/MapInfo.cpp +++ b/libunwindstack/MapInfo.cpp @@ -29,6 +29,38 @@ namespace unwindstack { +bool MapInfo::InitFileMemoryFromPreviousReadOnlyMap(MemoryFileAtOffset* memory) { + // One last attempt, see if the previous map is read-only with the + // same name and stretches across this map. + for (auto iter = maps_->begin(); iter != maps_->end(); ++iter) { + if (*iter == this) { + if (iter == maps_->begin()) { + return false; + } + --iter; + MapInfo* prev_map = *iter; + // Make sure this is a read-only map. + if (prev_map->flags != PROT_READ) { + return false; + } + uint64_t map_size = end - prev_map->end; + if (!memory->Init(name, prev_map->offset, map_size)) { + return false; + } + uint64_t max_size; + if (!Elf::GetInfo(memory, &max_size) || max_size < map_size) { + return false; + } + if (!memory->Init(name, prev_map->offset, max_size)) { + return false; + } + elf_offset = offset - prev_map->offset; + return true; + } + } + return false; +} + Memory* MapInfo::GetFileMemory() { std::unique_ptr<MemoryFileAtOffset> memory(new MemoryFileAtOffset); if (offset == 0) { @@ -38,8 +70,12 @@ Memory* MapInfo::GetFileMemory() { return nullptr; } - // There are two possibilities when the offset is non-zero. - // - There is an elf file embedded in a file. + // These are the possibilities when the offset is non-zero. + // - There is an elf file embedded in a file, and the offset is the + // the start of the elf in the file. + // - There is an elf file embedded in a file, and the offset is the + // the start of the executable part of the file. The actual start + // of the elf is in the read-only segment preceeding this map. // - The whole file is an elf file, and the offset needs to be saved. // // Map in just the part of the file for the map. If this is not @@ -53,27 +89,41 @@ Memory* MapInfo::GetFileMemory() { return nullptr; } - uint64_t max_size; - if (!Elf::GetInfo(memory.get(), &max_size)) { - // Init as if the whole file is an elf. - if (memory->Init(name, 0)) { - elf_offset = offset; - return memory.release(); + // Check if the start of this map is an embedded elf. + uint64_t max_size = 0; + uint64_t file_offset = offset; + if (Elf::GetInfo(memory.get(), &max_size)) { + if (max_size > map_size) { + if (memory->Init(name, file_offset, max_size)) { + return memory.release(); + } + // Try to reinit using the default map_size. + if (memory->Init(name, file_offset, map_size)) { + return memory.release(); + } + return nullptr; } - return nullptr; + return memory.release(); } - if (max_size > map_size) { - if (memory->Init(name, offset, max_size)) { - return memory.release(); - } - // Try to reinit using the default map_size. - if (memory->Init(name, offset, map_size)) { - return memory.release(); - } - return nullptr; + // No elf at offset, try to init as if the whole file is an elf. + if (memory->Init(name, 0) && Elf::IsValidElf(memory.get())) { + elf_offset = offset; + return memory.release(); } - return memory.release(); + + // See if the map previous to this one contains a read-only map + // that represents the real start of the elf data. + if (InitFileMemoryFromPreviousReadOnlyMap(memory.get())) { + return memory.release(); + } + + // Failed to find elf at start of file or at read-only map, return + // file object from the current map. + if (memory->Init(name, offset, map_size)) { + return memory.release(); + } + return nullptr; } Memory* MapInfo::CreateMemory(const std::shared_ptr<Memory>& process_memory) { @@ -110,29 +160,27 @@ Memory* MapInfo::CreateMemory(const std::shared_ptr<Memory>& process_memory) { return nullptr; } - // Find the read-only map that has the same name and has an offset closest - // to the current offset but less than the offset of the current map. - // For shared libraries, there should be a r-x map that has a non-zero - // offset and then a r-- map that has a zero offset. - // For shared libraries loaded from an apk, there should be a r-x map that - // has a non-zero offset and then a r-- map that has a non-zero offset less - // than the offset from the r-x map. - uint64_t closest_offset = 0; + // Find the read-only map by looking at the previous map. The linker + // doesn't guarantee that this invariant will always be true. However, + // if that changes, there is likely something else that will change and + // break something. MapInfo* ro_map_info = nullptr; - for (auto map_info : *maps_) { - if (map_info->flags == PROT_READ && map_info->name == name && map_info->offset < offset && - map_info->offset >= closest_offset) { - ro_map_info = map_info; - closest_offset = ro_map_info->offset; + for (auto iter = maps_->begin(); iter != maps_->end(); ++iter) { + if (*iter == this) { + if (iter != maps_->begin()) { + --iter; + ro_map_info = *iter; + } + break; } } - if (ro_map_info == nullptr) { + if (ro_map_info == nullptr || ro_map_info->name != name || ro_map_info->offset >= offset) { return nullptr; } // Make sure that relative pc values are corrected properly. - elf_offset = offset - closest_offset; + elf_offset = offset - ro_map_info->offset; MemoryRanges* ranges = new MemoryRanges; ranges->Insert(new MemoryRange(process_memory, ro_map_info->start, diff --git a/libunwindstack/include/unwindstack/MapInfo.h b/libunwindstack/include/unwindstack/MapInfo.h index 9c6b55211..cfdefd0bb 100644 --- a/libunwindstack/include/unwindstack/MapInfo.h +++ b/libunwindstack/include/unwindstack/MapInfo.h @@ -83,6 +83,7 @@ struct MapInfo { void operator=(const MapInfo&) = delete; Memory* GetFileMemory(); + bool InitFileMemoryFromPreviousReadOnlyMap(MemoryFileAtOffset* memory); // Protect the creation of the elf object. std::mutex mutex_; diff --git a/libunwindstack/tests/MapInfoCreateMemoryTest.cpp b/libunwindstack/tests/MapInfoCreateMemoryTest.cpp index 0987bc126..943b3c9dc 100644 --- a/libunwindstack/tests/MapInfoCreateMemoryTest.cpp +++ b/libunwindstack/tests/MapInfoCreateMemoryTest.cpp @@ -59,16 +59,16 @@ class MapInfoCreateMemoryTest : public ::testing::Test { } static void SetUpTestCase() { - std::vector<uint8_t> buffer(1024); - memset(buffer.data(), 0, buffer.size()); + std::vector<uint8_t> buffer(12288, 0); memcpy(buffer.data(), ELFMAG, SELFMAG); buffer[EI_CLASS] = ELFCLASS32; - ASSERT_TRUE(android::base::WriteFully(elf_.fd, buffer.data(), buffer.size())); + ASSERT_TRUE(android::base::WriteFully(elf_.fd, buffer.data(), 1024)); memset(buffer.data(), 0, buffer.size()); - memcpy(&buffer[0x100], ELFMAG, SELFMAG); - buffer[0x100 + EI_CLASS] = ELFCLASS64; - ASSERT_TRUE(android::base::WriteFully(elf_at_100_.fd, buffer.data(), buffer.size())); + memcpy(&buffer[0x1000], ELFMAG, SELFMAG); + buffer[0x1000 + EI_CLASS] = ELFCLASS64; + buffer[0x2000] = 0xff; + ASSERT_TRUE(android::base::WriteFully(elf_at_1000_.fd, buffer.data(), buffer.size())); InitElf<Elf32_Ehdr, Elf32_Shdr>(elf32_at_map_.fd, 0x1000, 0x2000, ELFCLASS32); InitElf<Elf64_Ehdr, Elf64_Shdr>(elf64_at_map_.fd, 0x2000, 0x3000, ELFCLASS64); @@ -84,13 +84,13 @@ class MapInfoCreateMemoryTest : public ::testing::Test { static TemporaryFile elf_; - static TemporaryFile elf_at_100_; + static TemporaryFile elf_at_1000_; static TemporaryFile elf32_at_map_; static TemporaryFile elf64_at_map_; }; TemporaryFile MapInfoCreateMemoryTest::elf_; -TemporaryFile MapInfoCreateMemoryTest::elf_at_100_; +TemporaryFile MapInfoCreateMemoryTest::elf_at_1000_; TemporaryFile MapInfoCreateMemoryTest::elf32_at_map_; TemporaryFile MapInfoCreateMemoryTest::elf64_at_map_; @@ -134,7 +134,7 @@ TEST_F(MapInfoCreateMemoryTest, file_backed_non_zero_offset_full_file) { // Verify that if the offset is non-zero and there is an elf at that // offset, that only part of the file is used. TEST_F(MapInfoCreateMemoryTest, file_backed_non_zero_offset_partial_file) { - MapInfo info(nullptr, 0x100, 0x200, 0x100, 0, elf_at_100_.path); + MapInfo info(nullptr, 0x100, 0x200, 0x1000, 0, elf_at_1000_.path); std::unique_ptr<Memory> memory(info.CreateMemory(process_memory_)); ASSERT_TRUE(memory.get() != nullptr); @@ -312,4 +312,43 @@ TEST_F(MapInfoCreateMemoryTest, valid_rosegment_non_zero_offset) { } } +TEST_F(MapInfoCreateMemoryTest, rosegment_from_file) { + Maps maps; + maps.Add(0x500, 0x600, 0, PROT_READ, "something_else", 0); + maps.Add(0x1000, 0x2000, 0x1000, PROT_READ, elf_at_1000_.path, 0); + maps.Add(0x2000, 0x3000, 0x2000, PROT_READ | PROT_EXEC, elf_at_1000_.path, 0); + + MapInfo* map_info = maps.Find(0x2000); + ASSERT_TRUE(map_info != nullptr); + + // Set up the size + Elf64_Ehdr ehdr; + ASSERT_EQ(0x1000, lseek(elf_at_1000_.fd, 0x1000, SEEK_SET)); + ASSERT_TRUE(android::base::ReadFully(elf_at_1000_.fd, &ehdr, sizeof(ehdr))); + + // Will not give the elf memory, because the read-only entry does not + // extend over the executable segment. + std::unique_ptr<Memory> memory(map_info->CreateMemory(process_memory_)); + ASSERT_TRUE(memory.get() != nullptr); + std::vector<uint8_t> buffer(0x100); + EXPECT_EQ(0x2000U, map_info->offset); + EXPECT_EQ(0U, map_info->elf_offset); + ASSERT_TRUE(memory->ReadFully(0, buffer.data(), 0x100)); + EXPECT_EQ(0xffU, buffer[0]); + + // Now init the elf data enough so that the file memory object will be used. + ehdr.e_shoff = 0x4000; + ehdr.e_shnum = 1; + ehdr.e_shentsize = 0x100; + ASSERT_EQ(0x1000, lseek(elf_at_1000_.fd, 0x1000, SEEK_SET)); + ASSERT_TRUE(android::base::WriteFully(elf_at_1000_.fd, &ehdr, sizeof(ehdr))); + + memory.reset(map_info->CreateMemory(process_memory_)); + EXPECT_EQ(0x2000U, map_info->offset); + EXPECT_EQ(0x1000U, map_info->elf_offset); + Elf64_Ehdr ehdr_mem; + ASSERT_TRUE(memory->ReadFully(0, &ehdr_mem, sizeof(ehdr_mem))); + EXPECT_TRUE(memcmp(&ehdr, &ehdr_mem, sizeof(ehdr)) == 0); +} + } // namespace unwindstack diff --git a/libunwindstack/tests/UnwindOfflineTest.cpp b/libunwindstack/tests/UnwindOfflineTest.cpp index a65c077d7..dc015b4b6 100644 --- a/libunwindstack/tests/UnwindOfflineTest.cpp +++ b/libunwindstack/tests/UnwindOfflineTest.cpp @@ -1239,4 +1239,79 @@ TEST_F(UnwindOfflineTest, debug_frame_load_bias_arm) { EXPECT_EQ(0xffd4a718U, unwinder.frames()[7].sp); } +TEST_F(UnwindOfflineTest, shared_lib_in_apk_arm64) { + ASSERT_NO_FATAL_FAILURE(Init("shared_lib_in_apk_arm64/", ARCH_ARM64)); + + Unwinder unwinder(128, maps_.get(), regs_.get(), process_memory_); + unwinder.Unwind(); + + std::string frame_info(DumpFrames(unwinder)); + ASSERT_EQ(7U, unwinder.NumFrames()) << "Unwind:\n" << frame_info; + EXPECT_EQ( + " #00 pc 000000000014ccbc (offset 0x39000) linker64 (__dl_syscall+28)\n" + " #01 pc 000000000005426c (offset 0x39000) linker64 " + "(__dl__ZL24debuggerd_signal_handleriP7siginfoPv+1128)\n" + " #02 pc 00000000000008bc vdso.so\n" + " #03 pc 00000000000846f4 (offset 0x40000) libc.so (abort+172)\n" + " #04 pc 0000000000084ad4 (offset 0x40000) libc.so (__assert2+36)\n" + " #05 pc 000000000003d5b4 (offset 0x40000) ANGLEPrebuilt.apk (ANGLEGetUtilityAPI+56)\n" + " #06 pc 000000000007fe68 (offset 0x40000) libc.so (__libc_init)\n", + frame_info); + + EXPECT_EQ(0x7e82c4fcbcULL, unwinder.frames()[0].pc); + EXPECT_EQ(0x7df8ca3bf0ULL, unwinder.frames()[0].sp); + EXPECT_EQ(0x7e82b5726cULL, unwinder.frames()[1].pc); + EXPECT_EQ(0x7df8ca3bf0ULL, unwinder.frames()[1].sp); + EXPECT_EQ(0x7e82b018bcULL, unwinder.frames()[2].pc); + EXPECT_EQ(0x7df8ca3da0ULL, unwinder.frames()[2].sp); + EXPECT_EQ(0x7e7eecc6f4ULL, unwinder.frames()[3].pc); + EXPECT_EQ(0x7dabf3db60ULL, unwinder.frames()[3].sp); + EXPECT_EQ(0x7e7eeccad4ULL, unwinder.frames()[4].pc); + EXPECT_EQ(0x7dabf3dc40ULL, unwinder.frames()[4].sp); + EXPECT_EQ(0x7dabc405b4ULL, unwinder.frames()[5].pc); + EXPECT_EQ(0x7dabf3dc50ULL, unwinder.frames()[5].sp); + EXPECT_EQ(0x7e7eec7e68ULL, unwinder.frames()[6].pc); + EXPECT_EQ(0x7dabf3dc70ULL, unwinder.frames()[6].sp); + // Ignore top frame since the test code was modified to end in __libc_init. +} + +TEST_F(UnwindOfflineTest, shared_lib_in_apk_memory_only_arm64) { + ASSERT_NO_FATAL_FAILURE(Init("shared_lib_in_apk_memory_only_arm64/", ARCH_ARM64)); + // Add the memory that represents the shared library. + MemoryOfflineParts* memory = reinterpret_cast<MemoryOfflineParts*>(process_memory_.get()); + AddMemory(dir_ + "lib_mem.data", memory); + + Unwinder unwinder(128, maps_.get(), regs_.get(), process_memory_); + unwinder.Unwind(); + + std::string frame_info(DumpFrames(unwinder)); + ASSERT_EQ(7U, unwinder.NumFrames()) << "Unwind:\n" << frame_info; + EXPECT_EQ( + " #00 pc 000000000014ccbc (offset 0x39000) linker64 (__dl_syscall+28)\n" + " #01 pc 000000000005426c (offset 0x39000) linker64 " + "(__dl__ZL24debuggerd_signal_handleriP7siginfoPv+1128)\n" + " #02 pc 00000000000008bc vdso.so\n" + " #03 pc 00000000000846f4 (offset 0x40000) libc.so (abort+172)\n" + " #04 pc 0000000000084ad4 (offset 0x40000) libc.so (__assert2+36)\n" + " #05 pc 000000000003d5b4 (offset 0x2211000) ANGLEPrebuilt.apk\n" + " #06 pc 000000000007fe68 (offset 0x40000) libc.so (__libc_init)\n", + frame_info); + + EXPECT_EQ(0x7e82c4fcbcULL, unwinder.frames()[0].pc); + EXPECT_EQ(0x7df8ca3bf0ULL, unwinder.frames()[0].sp); + EXPECT_EQ(0x7e82b5726cULL, unwinder.frames()[1].pc); + EXPECT_EQ(0x7df8ca3bf0ULL, unwinder.frames()[1].sp); + EXPECT_EQ(0x7e82b018bcULL, unwinder.frames()[2].pc); + EXPECT_EQ(0x7df8ca3da0ULL, unwinder.frames()[2].sp); + EXPECT_EQ(0x7e7eecc6f4ULL, unwinder.frames()[3].pc); + EXPECT_EQ(0x7dabf3db60ULL, unwinder.frames()[3].sp); + EXPECT_EQ(0x7e7eeccad4ULL, unwinder.frames()[4].pc); + EXPECT_EQ(0x7dabf3dc40ULL, unwinder.frames()[4].sp); + EXPECT_EQ(0x7dabc405b4ULL, unwinder.frames()[5].pc); + EXPECT_EQ(0x7dabf3dc50ULL, unwinder.frames()[5].sp); + EXPECT_EQ(0x7e7eec7e68ULL, unwinder.frames()[6].pc); + EXPECT_EQ(0x7dabf3dc70ULL, unwinder.frames()[6].sp); + // Ignore top frame since the test code was modified to end in __libc_init. +} + } // namespace unwindstack diff --git a/libunwindstack/tests/files/offline/shared_lib_in_apk_arm64/ANGLEPrebuilt.apk b/libunwindstack/tests/files/offline/shared_lib_in_apk_arm64/ANGLEPrebuilt.apk Binary files differnew file mode 100644 index 000000000..02773599b --- /dev/null +++ b/libunwindstack/tests/files/offline/shared_lib_in_apk_arm64/ANGLEPrebuilt.apk diff --git a/libunwindstack/tests/files/offline/shared_lib_in_apk_arm64/libc.so b/libunwindstack/tests/files/offline/shared_lib_in_apk_arm64/libc.so Binary files differnew file mode 100644 index 000000000..20008fd15 --- /dev/null +++ b/libunwindstack/tests/files/offline/shared_lib_in_apk_arm64/libc.so diff --git a/libunwindstack/tests/files/offline/shared_lib_in_apk_arm64/linker64 b/libunwindstack/tests/files/offline/shared_lib_in_apk_arm64/linker64 Binary files differnew file mode 100644 index 000000000..b90933ba6 --- /dev/null +++ b/libunwindstack/tests/files/offline/shared_lib_in_apk_arm64/linker64 diff --git a/libunwindstack/tests/files/offline/shared_lib_in_apk_arm64/maps.txt b/libunwindstack/tests/files/offline/shared_lib_in_apk_arm64/maps.txt new file mode 100644 index 000000000..c4fc06764 --- /dev/null +++ b/libunwindstack/tests/files/offline/shared_lib_in_apk_arm64/maps.txt @@ -0,0 +1,7 @@ +7dabc03000-7dabc3f000 r--p 4000 00:00 0 ANGLEPrebuilt.apk +7dabc3f000-7dabcf0000 r-xp 40000 00:00 0 ANGLEPrebuilt.apk +7e7ee48000-7e7ee88000 r--p 0 00:00 0 libc.so +7e7ee88000-7e7ef32000 r-xp 40000 00:00 0 libc.so +7e82b01000-7e82b03000 r-xp 0 00:00 0 vdso.so +7e82b03000-7e82b3c000 r--p 0 00:00 0 linker64 +7e82b3c000-7e82c77000 r-xp 39000 00:00 0 linker64 diff --git a/libunwindstack/tests/files/offline/shared_lib_in_apk_arm64/regs.txt b/libunwindstack/tests/files/offline/shared_lib_in_apk_arm64/regs.txt new file mode 100644 index 000000000..1e2ea3206 --- /dev/null +++ b/libunwindstack/tests/files/offline/shared_lib_in_apk_arm64/regs.txt @@ -0,0 +1,33 @@ +x0: 7df8ca3c24 +x1: 0 +x2: ffffffff +x3: 0 +x4: 0 +x5: 0 +x6: 0 +x7: 7f7f7f7f7f7f7f7f +x8: 62 +x9: 20dd5829922a93ac +x10: 7e82b57420 +x11: 4100 +x12: 7df8ca3b70 +x13: 7df8ca3b98 +x14: 73d015e5 +x15: 39a36122467299 +x16: 76ac +x17: 0 +x18: 7df8cfc000 +x19: 7dabf3e7a0 +x20: 7df8ca3da0 +x21: 59616d61 +x22: 1 +x23: 7df8ca3c24 +x24: 1894 +x25: 62 +x26: 2 +x27: 0 +x28: 7dabf3e790 +x29: 7df8ca3d90 +sp: 7df8ca3bf0 +lr: 7e82b57270 +pc: 7e82c4fcbc diff --git a/libunwindstack/tests/files/offline/shared_lib_in_apk_arm64/stack0.data b/libunwindstack/tests/files/offline/shared_lib_in_apk_arm64/stack0.data Binary files differnew file mode 100644 index 000000000..ec07e15c5 --- /dev/null +++ b/libunwindstack/tests/files/offline/shared_lib_in_apk_arm64/stack0.data diff --git a/libunwindstack/tests/files/offline/shared_lib_in_apk_arm64/stack1.data b/libunwindstack/tests/files/offline/shared_lib_in_apk_arm64/stack1.data Binary files differnew file mode 100644 index 000000000..825bb1aa5 --- /dev/null +++ b/libunwindstack/tests/files/offline/shared_lib_in_apk_arm64/stack1.data diff --git a/libunwindstack/tests/files/offline/shared_lib_in_apk_arm64/vdso.so b/libunwindstack/tests/files/offline/shared_lib_in_apk_arm64/vdso.so Binary files differnew file mode 100644 index 000000000..205ebd43a --- /dev/null +++ b/libunwindstack/tests/files/offline/shared_lib_in_apk_arm64/vdso.so diff --git a/libunwindstack/tests/files/offline/shared_lib_in_apk_memory_only_arm64/lib_mem.data b/libunwindstack/tests/files/offline/shared_lib_in_apk_memory_only_arm64/lib_mem.data Binary files differnew file mode 100644 index 000000000..f39d127e0 --- /dev/null +++ b/libunwindstack/tests/files/offline/shared_lib_in_apk_memory_only_arm64/lib_mem.data diff --git a/libunwindstack/tests/files/offline/shared_lib_in_apk_memory_only_arm64/libc.so b/libunwindstack/tests/files/offline/shared_lib_in_apk_memory_only_arm64/libc.so Binary files differnew file mode 100644 index 000000000..20008fd15 --- /dev/null +++ b/libunwindstack/tests/files/offline/shared_lib_in_apk_memory_only_arm64/libc.so diff --git a/libunwindstack/tests/files/offline/shared_lib_in_apk_memory_only_arm64/linker64 b/libunwindstack/tests/files/offline/shared_lib_in_apk_memory_only_arm64/linker64 Binary files differnew file mode 100644 index 000000000..b90933ba6 --- /dev/null +++ b/libunwindstack/tests/files/offline/shared_lib_in_apk_memory_only_arm64/linker64 diff --git a/libunwindstack/tests/files/offline/shared_lib_in_apk_memory_only_arm64/maps.txt b/libunwindstack/tests/files/offline/shared_lib_in_apk_memory_only_arm64/maps.txt new file mode 100644 index 000000000..386d57a24 --- /dev/null +++ b/libunwindstack/tests/files/offline/shared_lib_in_apk_memory_only_arm64/maps.txt @@ -0,0 +1,7 @@ +7dabc03000-7dabc3f000 r--p 21d5000 00:00 0 ANGLEPrebuilt.apk +7dabc3f000-7dabcf0000 r-xp 2211000 00:00 0 ANGLEPrebuilt.apk +7e7ee48000-7e7ee88000 r--p 0 00:00 0 libc.so +7e7ee88000-7e7ef32000 r-xp 40000 00:00 0 libc.so +7e82b01000-7e82b03000 r-xp 0 00:00 0 vdso.so +7e82b03000-7e82b3c000 r--p 0 00:00 0 linker64 +7e82b3c000-7e82c77000 r-xp 39000 00:00 0 linker64 diff --git a/libunwindstack/tests/files/offline/shared_lib_in_apk_memory_only_arm64/regs.txt b/libunwindstack/tests/files/offline/shared_lib_in_apk_memory_only_arm64/regs.txt new file mode 100644 index 000000000..1e2ea3206 --- /dev/null +++ b/libunwindstack/tests/files/offline/shared_lib_in_apk_memory_only_arm64/regs.txt @@ -0,0 +1,33 @@ +x0: 7df8ca3c24 +x1: 0 +x2: ffffffff +x3: 0 +x4: 0 +x5: 0 +x6: 0 +x7: 7f7f7f7f7f7f7f7f +x8: 62 +x9: 20dd5829922a93ac +x10: 7e82b57420 +x11: 4100 +x12: 7df8ca3b70 +x13: 7df8ca3b98 +x14: 73d015e5 +x15: 39a36122467299 +x16: 76ac +x17: 0 +x18: 7df8cfc000 +x19: 7dabf3e7a0 +x20: 7df8ca3da0 +x21: 59616d61 +x22: 1 +x23: 7df8ca3c24 +x24: 1894 +x25: 62 +x26: 2 +x27: 0 +x28: 7dabf3e790 +x29: 7df8ca3d90 +sp: 7df8ca3bf0 +lr: 7e82b57270 +pc: 7e82c4fcbc diff --git a/libunwindstack/tests/files/offline/shared_lib_in_apk_memory_only_arm64/stack0.data b/libunwindstack/tests/files/offline/shared_lib_in_apk_memory_only_arm64/stack0.data Binary files differnew file mode 100644 index 000000000..ec07e15c5 --- /dev/null +++ b/libunwindstack/tests/files/offline/shared_lib_in_apk_memory_only_arm64/stack0.data diff --git a/libunwindstack/tests/files/offline/shared_lib_in_apk_memory_only_arm64/stack1.data b/libunwindstack/tests/files/offline/shared_lib_in_apk_memory_only_arm64/stack1.data Binary files differnew file mode 100644 index 000000000..825bb1aa5 --- /dev/null +++ b/libunwindstack/tests/files/offline/shared_lib_in_apk_memory_only_arm64/stack1.data diff --git a/libunwindstack/tests/files/offline/shared_lib_in_apk_memory_only_arm64/vdso.so b/libunwindstack/tests/files/offline/shared_lib_in_apk_memory_only_arm64/vdso.so Binary files differnew file mode 100644 index 000000000..205ebd43a --- /dev/null +++ b/libunwindstack/tests/files/offline/shared_lib_in_apk_memory_only_arm64/vdso.so diff --git a/libunwindstack/tools/unwind.cpp b/libunwindstack/tools/unwind.cpp index 22ca7bf1d..e72945321 100644 --- a/libunwindstack/tools/unwind.cpp +++ b/libunwindstack/tools/unwind.cpp @@ -35,7 +35,12 @@ #include <unwindstack/Unwinder.h> static bool Attach(pid_t pid) { - if (ptrace(PTRACE_ATTACH, pid, 0, 0) == -1) { + if (ptrace(PTRACE_SEIZE, pid, 0, 0) == -1) { + return false; + } + + if (ptrace(PTRACE_INTERRUPT, pid, 0, 0) == -1) { + ptrace(PTRACE_DETACH, pid, 0, 0); return false; } diff --git a/libunwindstack/tools/unwind_for_offline.cpp b/libunwindstack/tools/unwind_for_offline.cpp index c8a8ab55f..652dbd1d3 100644 --- a/libunwindstack/tools/unwind_for_offline.cpp +++ b/libunwindstack/tools/unwind_for_offline.cpp @@ -50,7 +50,12 @@ struct map_info_t { }; static bool Attach(pid_t pid) { - if (ptrace(PTRACE_ATTACH, pid, 0, 0) == -1) { + if (ptrace(PTRACE_SEIZE, pid, 0, 0) == -1) { + return false; + } + + if (ptrace(PTRACE_INTERRUPT, pid, 0, 0) == -1) { + ptrace(PTRACE_DETACH, pid, 0, 0); return false; } |