Loading debuggerd/libdebuggerd/test/tombstone_test.cpp +0 −464 Original line number Diff line number Diff line Loading @@ -359,467 +359,3 @@ TEST_F(TombstoneTest, dump_timestamp) { dump_timestamp(&log_, 0); ASSERT_STREQ("Timestamp: 1970-01-01 00:00:00+0000\n", amfd_data_.c_str()); } class MemoryPattern : public unwindstack::Memory { public: MemoryPattern() = default; virtual ~MemoryPattern() = default; size_t Read(uint64_t, void* dst, size_t size) override { uint8_t* data = reinterpret_cast<uint8_t*>(dst); for (size_t i = 0; i < size; i++) { data[i] = (i % 0xff); } return size; } }; TEST_F(TombstoneTest, dump_stack_single_frame) { std::vector<unwindstack::FrameData> frames; unwindstack::Maps maps; MemoryPattern memory; frames.push_back( unwindstack::FrameData{.num = 0, .rel_pc = 0x1000, .pc = 0x301000, .sp = 0x2000}); dump_stack(&log_, frames, &maps, &memory); std::string contents; ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0); ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &contents)); std::string expected = #if defined(__LP64__) " 0000000000001f80 0706050403020100\n" " 0000000000001f88 0f0e0d0c0b0a0908\n" " 0000000000001f90 1716151413121110\n" " 0000000000001f98 1f1e1d1c1b1a1918\n" " 0000000000001fa0 2726252423222120\n" " 0000000000001fa8 2f2e2d2c2b2a2928\n" " 0000000000001fb0 3736353433323130\n" " 0000000000001fb8 3f3e3d3c3b3a3938\n" " 0000000000001fc0 4746454443424140\n" " 0000000000001fc8 4f4e4d4c4b4a4948\n" " 0000000000001fd0 5756555453525150\n" " 0000000000001fd8 5f5e5d5c5b5a5958\n" " 0000000000001fe0 6766656463626160\n" " 0000000000001fe8 6f6e6d6c6b6a6968\n" " 0000000000001ff0 7776757473727170\n" " 0000000000001ff8 7f7e7d7c7b7a7978\n" " #00 0000000000002000 0706050403020100\n" " 0000000000002008 0f0e0d0c0b0a0908\n" " 0000000000002010 1716151413121110\n" " 0000000000002018 1f1e1d1c1b1a1918\n" " 0000000000002020 2726252423222120\n" " 0000000000002028 2f2e2d2c2b2a2928\n" " 0000000000002030 3736353433323130\n" " 0000000000002038 3f3e3d3c3b3a3938\n" " 0000000000002040 4746454443424140\n" " 0000000000002048 4f4e4d4c4b4a4948\n" " 0000000000002050 5756555453525150\n" " 0000000000002058 5f5e5d5c5b5a5958\n" " 0000000000002060 6766656463626160\n" " 0000000000002068 6f6e6d6c6b6a6968\n" " 0000000000002070 7776757473727170\n" " 0000000000002078 7f7e7d7c7b7a7978\n"; #else " 00001fc0 03020100\n" " 00001fc4 07060504\n" " 00001fc8 0b0a0908\n" " 00001fcc 0f0e0d0c\n" " 00001fd0 13121110\n" " 00001fd4 17161514\n" " 00001fd8 1b1a1918\n" " 00001fdc 1f1e1d1c\n" " 00001fe0 23222120\n" " 00001fe4 27262524\n" " 00001fe8 2b2a2928\n" " 00001fec 2f2e2d2c\n" " 00001ff0 33323130\n" " 00001ff4 37363534\n" " 00001ff8 3b3a3938\n" " 00001ffc 3f3e3d3c\n" " #00 00002000 03020100\n" " 00002004 07060504\n" " 00002008 0b0a0908\n" " 0000200c 0f0e0d0c\n" " 00002010 13121110\n" " 00002014 17161514\n" " 00002018 1b1a1918\n" " 0000201c 1f1e1d1c\n" " 00002020 23222120\n" " 00002024 27262524\n" " 00002028 2b2a2928\n" " 0000202c 2f2e2d2c\n" " 00002030 33323130\n" " 00002034 37363534\n" " 00002038 3b3a3938\n" " 0000203c 3f3e3d3c\n"; #endif EXPECT_EQ(expected, contents); } TEST_F(TombstoneTest, dump_stack_multiple_frames_same_sp) { std::vector<unwindstack::FrameData> frames; unwindstack::Maps maps; MemoryPattern memory; frames.push_back( unwindstack::FrameData{.num = 0, .rel_pc = 0x1000, .pc = 0x301000, .sp = 0x2000}); frames.push_back( unwindstack::FrameData{.num = 0, .rel_pc = 0x1400, .pc = 0x301400, .sp = 0x2000}); dump_stack(&log_, frames, &maps, &memory); std::string contents; ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0); ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &contents)); std::string expected = #if defined(__LP64__) " 0000000000001f80 0706050403020100\n" " 0000000000001f88 0f0e0d0c0b0a0908\n" " 0000000000001f90 1716151413121110\n" " 0000000000001f98 1f1e1d1c1b1a1918\n" " 0000000000001fa0 2726252423222120\n" " 0000000000001fa8 2f2e2d2c2b2a2928\n" " 0000000000001fb0 3736353433323130\n" " 0000000000001fb8 3f3e3d3c3b3a3938\n" " 0000000000001fc0 4746454443424140\n" " 0000000000001fc8 4f4e4d4c4b4a4948\n" " 0000000000001fd0 5756555453525150\n" " 0000000000001fd8 5f5e5d5c5b5a5958\n" " 0000000000001fe0 6766656463626160\n" " 0000000000001fe8 6f6e6d6c6b6a6968\n" " 0000000000001ff0 7776757473727170\n" " 0000000000001ff8 7f7e7d7c7b7a7978\n" " #00 0000000000002000 0706050403020100\n" " ................ ................\n" " #01 0000000000002000 0706050403020100\n" " 0000000000002008 0f0e0d0c0b0a0908\n" " 0000000000002010 1716151413121110\n" " 0000000000002018 1f1e1d1c1b1a1918\n" " 0000000000002020 2726252423222120\n" " 0000000000002028 2f2e2d2c2b2a2928\n" " 0000000000002030 3736353433323130\n" " 0000000000002038 3f3e3d3c3b3a3938\n" " 0000000000002040 4746454443424140\n" " 0000000000002048 4f4e4d4c4b4a4948\n" " 0000000000002050 5756555453525150\n" " 0000000000002058 5f5e5d5c5b5a5958\n" " 0000000000002060 6766656463626160\n" " 0000000000002068 6f6e6d6c6b6a6968\n" " 0000000000002070 7776757473727170\n" " 0000000000002078 7f7e7d7c7b7a7978\n"; #else " 00001fc0 03020100\n" " 00001fc4 07060504\n" " 00001fc8 0b0a0908\n" " 00001fcc 0f0e0d0c\n" " 00001fd0 13121110\n" " 00001fd4 17161514\n" " 00001fd8 1b1a1918\n" " 00001fdc 1f1e1d1c\n" " 00001fe0 23222120\n" " 00001fe4 27262524\n" " 00001fe8 2b2a2928\n" " 00001fec 2f2e2d2c\n" " 00001ff0 33323130\n" " 00001ff4 37363534\n" " 00001ff8 3b3a3938\n" " 00001ffc 3f3e3d3c\n" " #00 00002000 03020100\n" " ........ ........\n" " #01 00002000 03020100\n" " 00002004 07060504\n" " 00002008 0b0a0908\n" " 0000200c 0f0e0d0c\n" " 00002010 13121110\n" " 00002014 17161514\n" " 00002018 1b1a1918\n" " 0000201c 1f1e1d1c\n" " 00002020 23222120\n" " 00002024 27262524\n" " 00002028 2b2a2928\n" " 0000202c 2f2e2d2c\n" " 00002030 33323130\n" " 00002034 37363534\n" " 00002038 3b3a3938\n" " 0000203c 3f3e3d3c\n"; #endif EXPECT_EQ(expected, contents); } TEST_F(TombstoneTest, dump_stack_multiple_frames) { std::vector<unwindstack::FrameData> frames; unwindstack::Maps maps; MemoryPattern memory; frames.push_back( unwindstack::FrameData{.num = 0, .rel_pc = 0x1000, .pc = 0x301000, .sp = 0x2000}); frames.push_back( unwindstack::FrameData{.num = 0, .rel_pc = 0x1400, .pc = 0x301400, .sp = 0x2010}); frames.push_back( unwindstack::FrameData{.num = 0, .rel_pc = 0x1400, .pc = 0x301400, .sp = 0x2100}); dump_stack(&log_, frames, &maps, &memory); std::string contents; ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0); ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &contents)); std::string expected = #if defined(__LP64__) " 0000000000001f80 0706050403020100\n" " 0000000000001f88 0f0e0d0c0b0a0908\n" " 0000000000001f90 1716151413121110\n" " 0000000000001f98 1f1e1d1c1b1a1918\n" " 0000000000001fa0 2726252423222120\n" " 0000000000001fa8 2f2e2d2c2b2a2928\n" " 0000000000001fb0 3736353433323130\n" " 0000000000001fb8 3f3e3d3c3b3a3938\n" " 0000000000001fc0 4746454443424140\n" " 0000000000001fc8 4f4e4d4c4b4a4948\n" " 0000000000001fd0 5756555453525150\n" " 0000000000001fd8 5f5e5d5c5b5a5958\n" " 0000000000001fe0 6766656463626160\n" " 0000000000001fe8 6f6e6d6c6b6a6968\n" " 0000000000001ff0 7776757473727170\n" " 0000000000001ff8 7f7e7d7c7b7a7978\n" " #00 0000000000002000 0706050403020100\n" " 0000000000002008 0f0e0d0c0b0a0908\n" " #01 0000000000002010 0706050403020100\n" " 0000000000002018 0f0e0d0c0b0a0908\n" " 0000000000002020 1716151413121110\n" " 0000000000002028 1f1e1d1c1b1a1918\n" " 0000000000002030 2726252423222120\n" " 0000000000002038 2f2e2d2c2b2a2928\n" " 0000000000002040 3736353433323130\n" " 0000000000002048 3f3e3d3c3b3a3938\n" " 0000000000002050 4746454443424140\n" " 0000000000002058 4f4e4d4c4b4a4948\n" " 0000000000002060 5756555453525150\n" " 0000000000002068 5f5e5d5c5b5a5958\n" " 0000000000002070 6766656463626160\n" " 0000000000002078 6f6e6d6c6b6a6968\n" " 0000000000002080 7776757473727170\n" " 0000000000002088 7f7e7d7c7b7a7978\n" " ................ ................\n" " #02 0000000000002100 0706050403020100\n" " 0000000000002108 0f0e0d0c0b0a0908\n" " 0000000000002110 1716151413121110\n" " 0000000000002118 1f1e1d1c1b1a1918\n" " 0000000000002120 2726252423222120\n" " 0000000000002128 2f2e2d2c2b2a2928\n" " 0000000000002130 3736353433323130\n" " 0000000000002138 3f3e3d3c3b3a3938\n" " 0000000000002140 4746454443424140\n" " 0000000000002148 4f4e4d4c4b4a4948\n" " 0000000000002150 5756555453525150\n" " 0000000000002158 5f5e5d5c5b5a5958\n" " 0000000000002160 6766656463626160\n" " 0000000000002168 6f6e6d6c6b6a6968\n" " 0000000000002170 7776757473727170\n" " 0000000000002178 7f7e7d7c7b7a7978\n"; #else " 00001fc0 03020100\n" " 00001fc4 07060504\n" " 00001fc8 0b0a0908\n" " 00001fcc 0f0e0d0c\n" " 00001fd0 13121110\n" " 00001fd4 17161514\n" " 00001fd8 1b1a1918\n" " 00001fdc 1f1e1d1c\n" " 00001fe0 23222120\n" " 00001fe4 27262524\n" " 00001fe8 2b2a2928\n" " 00001fec 2f2e2d2c\n" " 00001ff0 33323130\n" " 00001ff4 37363534\n" " 00001ff8 3b3a3938\n" " 00001ffc 3f3e3d3c\n" " #00 00002000 03020100\n" " 00002004 07060504\n" " 00002008 0b0a0908\n" " 0000200c 0f0e0d0c\n" " #01 00002010 03020100\n" " 00002014 07060504\n" " 00002018 0b0a0908\n" " 0000201c 0f0e0d0c\n" " 00002020 13121110\n" " 00002024 17161514\n" " 00002028 1b1a1918\n" " 0000202c 1f1e1d1c\n" " 00002030 23222120\n" " 00002034 27262524\n" " 00002038 2b2a2928\n" " 0000203c 2f2e2d2c\n" " 00002040 33323130\n" " 00002044 37363534\n" " 00002048 3b3a3938\n" " 0000204c 3f3e3d3c\n" " ........ ........\n" " #02 00002100 03020100\n" " 00002104 07060504\n" " 00002108 0b0a0908\n" " 0000210c 0f0e0d0c\n" " 00002110 13121110\n" " 00002114 17161514\n" " 00002118 1b1a1918\n" " 0000211c 1f1e1d1c\n" " 00002120 23222120\n" " 00002124 27262524\n" " 00002128 2b2a2928\n" " 0000212c 2f2e2d2c\n" " 00002130 33323130\n" " 00002134 37363534\n" " 00002138 3b3a3938\n" " 0000213c 3f3e3d3c\n"; #endif EXPECT_EQ(expected, contents); } TEST_F(TombstoneTest, dump_stack_multiple_frames_disjoint_frames) { std::vector<unwindstack::FrameData> frames; unwindstack::Maps maps; MemoryPattern memory; frames.push_back( unwindstack::FrameData{.num = 0, .rel_pc = 0x1000, .pc = 0x301000, .sp = 0x2000}); frames.push_back( unwindstack::FrameData{.num = 0, .rel_pc = 0x1400, .pc = 0x301400, .sp = 0x2010}); frames.push_back( unwindstack::FrameData{.num = 0, .rel_pc = 0x1400, .pc = 0x301400, .sp = 0x1000}); frames.push_back( unwindstack::FrameData{.num = 0, .rel_pc = 0x1400, .pc = 0x301400, .sp = 0x1030}); dump_stack(&log_, frames, &maps, &memory); std::string contents; ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0); ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &contents)); std::string expected = #if defined(__LP64__) " 0000000000001f80 0706050403020100\n" " 0000000000001f88 0f0e0d0c0b0a0908\n" " 0000000000001f90 1716151413121110\n" " 0000000000001f98 1f1e1d1c1b1a1918\n" " 0000000000001fa0 2726252423222120\n" " 0000000000001fa8 2f2e2d2c2b2a2928\n" " 0000000000001fb0 3736353433323130\n" " 0000000000001fb8 3f3e3d3c3b3a3938\n" " 0000000000001fc0 4746454443424140\n" " 0000000000001fc8 4f4e4d4c4b4a4948\n" " 0000000000001fd0 5756555453525150\n" " 0000000000001fd8 5f5e5d5c5b5a5958\n" " 0000000000001fe0 6766656463626160\n" " 0000000000001fe8 6f6e6d6c6b6a6968\n" " 0000000000001ff0 7776757473727170\n" " 0000000000001ff8 7f7e7d7c7b7a7978\n" " #00 0000000000002000 0706050403020100\n" " 0000000000002008 0f0e0d0c0b0a0908\n" " #01 0000000000002010 0706050403020100\n" " 0000000000002018 0f0e0d0c0b0a0908\n" " 0000000000002020 1716151413121110\n" " 0000000000002028 1f1e1d1c1b1a1918\n" " 0000000000002030 2726252423222120\n" " 0000000000002038 2f2e2d2c2b2a2928\n" " 0000000000002040 3736353433323130\n" " 0000000000002048 3f3e3d3c3b3a3938\n" " 0000000000002050 4746454443424140\n" " 0000000000002058 4f4e4d4c4b4a4948\n" " 0000000000002060 5756555453525150\n" " 0000000000002068 5f5e5d5c5b5a5958\n" " 0000000000002070 6766656463626160\n" " 0000000000002078 6f6e6d6c6b6a6968\n" " 0000000000002080 7776757473727170\n" " 0000000000002088 7f7e7d7c7b7a7978\n" " ................ ................\n" " #02 0000000000001000 0706050403020100\n" " 0000000000001008 0f0e0d0c0b0a0908\n" " 0000000000001010 1716151413121110\n" " 0000000000001018 1f1e1d1c1b1a1918\n" " 0000000000001020 2726252423222120\n" " 0000000000001028 2f2e2d2c2b2a2928\n" " #03 0000000000001030 0706050403020100\n" " 0000000000001038 0f0e0d0c0b0a0908\n" " 0000000000001040 1716151413121110\n" " 0000000000001048 1f1e1d1c1b1a1918\n" " 0000000000001050 2726252423222120\n" " 0000000000001058 2f2e2d2c2b2a2928\n" " 0000000000001060 3736353433323130\n" " 0000000000001068 3f3e3d3c3b3a3938\n" " 0000000000001070 4746454443424140\n" " 0000000000001078 4f4e4d4c4b4a4948\n" " 0000000000001080 5756555453525150\n" " 0000000000001088 5f5e5d5c5b5a5958\n" " 0000000000001090 6766656463626160\n" " 0000000000001098 6f6e6d6c6b6a6968\n" " 00000000000010a0 7776757473727170\n" " 00000000000010a8 7f7e7d7c7b7a7978\n"; #else " 00001fc0 03020100\n" " 00001fc4 07060504\n" " 00001fc8 0b0a0908\n" " 00001fcc 0f0e0d0c\n" " 00001fd0 13121110\n" " 00001fd4 17161514\n" " 00001fd8 1b1a1918\n" " 00001fdc 1f1e1d1c\n" " 00001fe0 23222120\n" " 00001fe4 27262524\n" " 00001fe8 2b2a2928\n" " 00001fec 2f2e2d2c\n" " 00001ff0 33323130\n" " 00001ff4 37363534\n" " 00001ff8 3b3a3938\n" " 00001ffc 3f3e3d3c\n" " #00 00002000 03020100\n" " 00002004 07060504\n" " 00002008 0b0a0908\n" " 0000200c 0f0e0d0c\n" " #01 00002010 03020100\n" " 00002014 07060504\n" " 00002018 0b0a0908\n" " 0000201c 0f0e0d0c\n" " 00002020 13121110\n" " 00002024 17161514\n" " 00002028 1b1a1918\n" " 0000202c 1f1e1d1c\n" " 00002030 23222120\n" " 00002034 27262524\n" " 00002038 2b2a2928\n" " 0000203c 2f2e2d2c\n" " 00002040 33323130\n" " 00002044 37363534\n" " 00002048 3b3a3938\n" " 0000204c 3f3e3d3c\n" " ........ ........\n" " #02 00001000 03020100\n" " 00001004 07060504\n" " 00001008 0b0a0908\n" " 0000100c 0f0e0d0c\n" " 00001010 13121110\n" " 00001014 17161514\n" " 00001018 1b1a1918\n" " 0000101c 1f1e1d1c\n" " 00001020 23222120\n" " 00001024 27262524\n" " 00001028 2b2a2928\n" " 0000102c 2f2e2d2c\n" " #03 00001030 03020100\n" " 00001034 07060504\n" " 00001038 0b0a0908\n" " 0000103c 0f0e0d0c\n" " 00001040 13121110\n" " 00001044 17161514\n" " 00001048 1b1a1918\n" " 0000104c 1f1e1d1c\n" " 00001050 23222120\n" " 00001054 27262524\n" " 00001058 2b2a2928\n" " 0000105c 2f2e2d2c\n" " 00001060 33323130\n" " 00001064 37363534\n" " 00001068 3b3a3938\n" " 0000106c 3f3e3d3c\n"; #endif EXPECT_EQ(expected, contents); } debuggerd/libdebuggerd/tombstone.cpp +0 −103 Original line number Diff line number Diff line Loading @@ -188,106 +188,6 @@ static void dump_thread_info(log_t* log, const ThreadInfo& thread_info) { _LOG(log, logtype::HEADER, "uid: %d\n", thread_info.uid); } static void dump_stack_segment(log_t* log, unwindstack::Maps* maps, unwindstack::Memory* memory, uint64_t* sp, size_t words, int label) { // Read the data all at once. word_t stack_data[words]; // TODO: Do we need to word align this for crashes caused by a misaligned sp? // The process_vm_readv implementation of Memory should handle this appropriately? size_t bytes_read = memory->Read(*sp, stack_data, sizeof(word_t) * words); words = bytes_read / sizeof(word_t); std::string line; for (size_t i = 0; i < words; i++) { line = " "; if (i == 0 && label >= 0) { // Print the label once. line += StringPrintf("#%02d ", label); } else { line += " "; } line += StringPrintf("%" PRIPTR " %" PRIPTR, *sp, static_cast<uint64_t>(stack_data[i])); unwindstack::MapInfo* map_info = maps->Find(stack_data[i]); if (map_info != nullptr && !map_info->name.empty()) { line += " " + map_info->name; std::string func_name; uint64_t func_offset = 0; if (map_info->GetFunctionName(stack_data[i], &func_name, &func_offset)) { line += " (" + func_name; if (func_offset) { line += StringPrintf("+%" PRIu64, func_offset); } line += ')'; } } _LOG(log, logtype::STACK, "%s\n", line.c_str()); *sp += sizeof(word_t); } } static void dump_stack(log_t* log, const std::vector<unwindstack::FrameData>& frames, unwindstack::Maps* maps, unwindstack::Memory* memory) { size_t first = 0, last; for (size_t i = 0; i < frames.size(); i++) { if (frames[i].sp) { if (!first) { first = i+1; } last = i; } } if (!first) { return; } first--; // Dump a few words before the first frame. uint64_t sp = frames[first].sp - STACK_WORDS * sizeof(word_t); dump_stack_segment(log, maps, memory, &sp, STACK_WORDS, -1); #if defined(__LP64__) static constexpr const char delimiter[] = " ................ ................\n"; #else static constexpr const char delimiter[] = " ........ ........\n"; #endif // Dump a few words from all successive frames. for (size_t i = first; i <= last; i++) { auto* frame = &frames[i]; if (sp != frame->sp) { _LOG(log, logtype::STACK, delimiter); sp = frame->sp; } if (i != last) { // Print stack data up to the stack from the next frame. size_t words; uint64_t next_sp = frames[i + 1].sp; if (next_sp < sp) { // The next frame is probably using a completely different stack, // so dump the max from this stack. words = STACK_WORDS; } else { words = (next_sp - sp) / sizeof(word_t); if (words == 0) { // The sp is the same as the next frame, print at least // one line for this frame. words = 1; } else if (words > STACK_WORDS) { words = STACK_WORDS; } } dump_stack_segment(log, maps, memory, &sp, words, i); } else { // Print some number of words past the last stack frame since we // don't know how large the stack is. dump_stack_segment(log, maps, memory, &sp, STACK_WORDS, i); } } } static std::string get_addr_string(uint64_t addr) { std::string addr_str; #if defined(__LP64__) Loading Loading @@ -499,9 +399,6 @@ static bool dump_thread(log_t* log, unwindstack::Unwinder* unwinder, const Threa } else { _LOG(log, logtype::BACKTRACE, "\nbacktrace:\n"); log_backtrace(log, unwinder, " "); _LOG(log, logtype::STACK, "\nstack:\n"); dump_stack(log, unwinder->frames(), unwinder->GetMaps(), unwinder->GetProcessMemory().get()); } if (primary_thread) { Loading Loading
debuggerd/libdebuggerd/test/tombstone_test.cpp +0 −464 Original line number Diff line number Diff line Loading @@ -359,467 +359,3 @@ TEST_F(TombstoneTest, dump_timestamp) { dump_timestamp(&log_, 0); ASSERT_STREQ("Timestamp: 1970-01-01 00:00:00+0000\n", amfd_data_.c_str()); } class MemoryPattern : public unwindstack::Memory { public: MemoryPattern() = default; virtual ~MemoryPattern() = default; size_t Read(uint64_t, void* dst, size_t size) override { uint8_t* data = reinterpret_cast<uint8_t*>(dst); for (size_t i = 0; i < size; i++) { data[i] = (i % 0xff); } return size; } }; TEST_F(TombstoneTest, dump_stack_single_frame) { std::vector<unwindstack::FrameData> frames; unwindstack::Maps maps; MemoryPattern memory; frames.push_back( unwindstack::FrameData{.num = 0, .rel_pc = 0x1000, .pc = 0x301000, .sp = 0x2000}); dump_stack(&log_, frames, &maps, &memory); std::string contents; ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0); ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &contents)); std::string expected = #if defined(__LP64__) " 0000000000001f80 0706050403020100\n" " 0000000000001f88 0f0e0d0c0b0a0908\n" " 0000000000001f90 1716151413121110\n" " 0000000000001f98 1f1e1d1c1b1a1918\n" " 0000000000001fa0 2726252423222120\n" " 0000000000001fa8 2f2e2d2c2b2a2928\n" " 0000000000001fb0 3736353433323130\n" " 0000000000001fb8 3f3e3d3c3b3a3938\n" " 0000000000001fc0 4746454443424140\n" " 0000000000001fc8 4f4e4d4c4b4a4948\n" " 0000000000001fd0 5756555453525150\n" " 0000000000001fd8 5f5e5d5c5b5a5958\n" " 0000000000001fe0 6766656463626160\n" " 0000000000001fe8 6f6e6d6c6b6a6968\n" " 0000000000001ff0 7776757473727170\n" " 0000000000001ff8 7f7e7d7c7b7a7978\n" " #00 0000000000002000 0706050403020100\n" " 0000000000002008 0f0e0d0c0b0a0908\n" " 0000000000002010 1716151413121110\n" " 0000000000002018 1f1e1d1c1b1a1918\n" " 0000000000002020 2726252423222120\n" " 0000000000002028 2f2e2d2c2b2a2928\n" " 0000000000002030 3736353433323130\n" " 0000000000002038 3f3e3d3c3b3a3938\n" " 0000000000002040 4746454443424140\n" " 0000000000002048 4f4e4d4c4b4a4948\n" " 0000000000002050 5756555453525150\n" " 0000000000002058 5f5e5d5c5b5a5958\n" " 0000000000002060 6766656463626160\n" " 0000000000002068 6f6e6d6c6b6a6968\n" " 0000000000002070 7776757473727170\n" " 0000000000002078 7f7e7d7c7b7a7978\n"; #else " 00001fc0 03020100\n" " 00001fc4 07060504\n" " 00001fc8 0b0a0908\n" " 00001fcc 0f0e0d0c\n" " 00001fd0 13121110\n" " 00001fd4 17161514\n" " 00001fd8 1b1a1918\n" " 00001fdc 1f1e1d1c\n" " 00001fe0 23222120\n" " 00001fe4 27262524\n" " 00001fe8 2b2a2928\n" " 00001fec 2f2e2d2c\n" " 00001ff0 33323130\n" " 00001ff4 37363534\n" " 00001ff8 3b3a3938\n" " 00001ffc 3f3e3d3c\n" " #00 00002000 03020100\n" " 00002004 07060504\n" " 00002008 0b0a0908\n" " 0000200c 0f0e0d0c\n" " 00002010 13121110\n" " 00002014 17161514\n" " 00002018 1b1a1918\n" " 0000201c 1f1e1d1c\n" " 00002020 23222120\n" " 00002024 27262524\n" " 00002028 2b2a2928\n" " 0000202c 2f2e2d2c\n" " 00002030 33323130\n" " 00002034 37363534\n" " 00002038 3b3a3938\n" " 0000203c 3f3e3d3c\n"; #endif EXPECT_EQ(expected, contents); } TEST_F(TombstoneTest, dump_stack_multiple_frames_same_sp) { std::vector<unwindstack::FrameData> frames; unwindstack::Maps maps; MemoryPattern memory; frames.push_back( unwindstack::FrameData{.num = 0, .rel_pc = 0x1000, .pc = 0x301000, .sp = 0x2000}); frames.push_back( unwindstack::FrameData{.num = 0, .rel_pc = 0x1400, .pc = 0x301400, .sp = 0x2000}); dump_stack(&log_, frames, &maps, &memory); std::string contents; ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0); ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &contents)); std::string expected = #if defined(__LP64__) " 0000000000001f80 0706050403020100\n" " 0000000000001f88 0f0e0d0c0b0a0908\n" " 0000000000001f90 1716151413121110\n" " 0000000000001f98 1f1e1d1c1b1a1918\n" " 0000000000001fa0 2726252423222120\n" " 0000000000001fa8 2f2e2d2c2b2a2928\n" " 0000000000001fb0 3736353433323130\n" " 0000000000001fb8 3f3e3d3c3b3a3938\n" " 0000000000001fc0 4746454443424140\n" " 0000000000001fc8 4f4e4d4c4b4a4948\n" " 0000000000001fd0 5756555453525150\n" " 0000000000001fd8 5f5e5d5c5b5a5958\n" " 0000000000001fe0 6766656463626160\n" " 0000000000001fe8 6f6e6d6c6b6a6968\n" " 0000000000001ff0 7776757473727170\n" " 0000000000001ff8 7f7e7d7c7b7a7978\n" " #00 0000000000002000 0706050403020100\n" " ................ ................\n" " #01 0000000000002000 0706050403020100\n" " 0000000000002008 0f0e0d0c0b0a0908\n" " 0000000000002010 1716151413121110\n" " 0000000000002018 1f1e1d1c1b1a1918\n" " 0000000000002020 2726252423222120\n" " 0000000000002028 2f2e2d2c2b2a2928\n" " 0000000000002030 3736353433323130\n" " 0000000000002038 3f3e3d3c3b3a3938\n" " 0000000000002040 4746454443424140\n" " 0000000000002048 4f4e4d4c4b4a4948\n" " 0000000000002050 5756555453525150\n" " 0000000000002058 5f5e5d5c5b5a5958\n" " 0000000000002060 6766656463626160\n" " 0000000000002068 6f6e6d6c6b6a6968\n" " 0000000000002070 7776757473727170\n" " 0000000000002078 7f7e7d7c7b7a7978\n"; #else " 00001fc0 03020100\n" " 00001fc4 07060504\n" " 00001fc8 0b0a0908\n" " 00001fcc 0f0e0d0c\n" " 00001fd0 13121110\n" " 00001fd4 17161514\n" " 00001fd8 1b1a1918\n" " 00001fdc 1f1e1d1c\n" " 00001fe0 23222120\n" " 00001fe4 27262524\n" " 00001fe8 2b2a2928\n" " 00001fec 2f2e2d2c\n" " 00001ff0 33323130\n" " 00001ff4 37363534\n" " 00001ff8 3b3a3938\n" " 00001ffc 3f3e3d3c\n" " #00 00002000 03020100\n" " ........ ........\n" " #01 00002000 03020100\n" " 00002004 07060504\n" " 00002008 0b0a0908\n" " 0000200c 0f0e0d0c\n" " 00002010 13121110\n" " 00002014 17161514\n" " 00002018 1b1a1918\n" " 0000201c 1f1e1d1c\n" " 00002020 23222120\n" " 00002024 27262524\n" " 00002028 2b2a2928\n" " 0000202c 2f2e2d2c\n" " 00002030 33323130\n" " 00002034 37363534\n" " 00002038 3b3a3938\n" " 0000203c 3f3e3d3c\n"; #endif EXPECT_EQ(expected, contents); } TEST_F(TombstoneTest, dump_stack_multiple_frames) { std::vector<unwindstack::FrameData> frames; unwindstack::Maps maps; MemoryPattern memory; frames.push_back( unwindstack::FrameData{.num = 0, .rel_pc = 0x1000, .pc = 0x301000, .sp = 0x2000}); frames.push_back( unwindstack::FrameData{.num = 0, .rel_pc = 0x1400, .pc = 0x301400, .sp = 0x2010}); frames.push_back( unwindstack::FrameData{.num = 0, .rel_pc = 0x1400, .pc = 0x301400, .sp = 0x2100}); dump_stack(&log_, frames, &maps, &memory); std::string contents; ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0); ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &contents)); std::string expected = #if defined(__LP64__) " 0000000000001f80 0706050403020100\n" " 0000000000001f88 0f0e0d0c0b0a0908\n" " 0000000000001f90 1716151413121110\n" " 0000000000001f98 1f1e1d1c1b1a1918\n" " 0000000000001fa0 2726252423222120\n" " 0000000000001fa8 2f2e2d2c2b2a2928\n" " 0000000000001fb0 3736353433323130\n" " 0000000000001fb8 3f3e3d3c3b3a3938\n" " 0000000000001fc0 4746454443424140\n" " 0000000000001fc8 4f4e4d4c4b4a4948\n" " 0000000000001fd0 5756555453525150\n" " 0000000000001fd8 5f5e5d5c5b5a5958\n" " 0000000000001fe0 6766656463626160\n" " 0000000000001fe8 6f6e6d6c6b6a6968\n" " 0000000000001ff0 7776757473727170\n" " 0000000000001ff8 7f7e7d7c7b7a7978\n" " #00 0000000000002000 0706050403020100\n" " 0000000000002008 0f0e0d0c0b0a0908\n" " #01 0000000000002010 0706050403020100\n" " 0000000000002018 0f0e0d0c0b0a0908\n" " 0000000000002020 1716151413121110\n" " 0000000000002028 1f1e1d1c1b1a1918\n" " 0000000000002030 2726252423222120\n" " 0000000000002038 2f2e2d2c2b2a2928\n" " 0000000000002040 3736353433323130\n" " 0000000000002048 3f3e3d3c3b3a3938\n" " 0000000000002050 4746454443424140\n" " 0000000000002058 4f4e4d4c4b4a4948\n" " 0000000000002060 5756555453525150\n" " 0000000000002068 5f5e5d5c5b5a5958\n" " 0000000000002070 6766656463626160\n" " 0000000000002078 6f6e6d6c6b6a6968\n" " 0000000000002080 7776757473727170\n" " 0000000000002088 7f7e7d7c7b7a7978\n" " ................ ................\n" " #02 0000000000002100 0706050403020100\n" " 0000000000002108 0f0e0d0c0b0a0908\n" " 0000000000002110 1716151413121110\n" " 0000000000002118 1f1e1d1c1b1a1918\n" " 0000000000002120 2726252423222120\n" " 0000000000002128 2f2e2d2c2b2a2928\n" " 0000000000002130 3736353433323130\n" " 0000000000002138 3f3e3d3c3b3a3938\n" " 0000000000002140 4746454443424140\n" " 0000000000002148 4f4e4d4c4b4a4948\n" " 0000000000002150 5756555453525150\n" " 0000000000002158 5f5e5d5c5b5a5958\n" " 0000000000002160 6766656463626160\n" " 0000000000002168 6f6e6d6c6b6a6968\n" " 0000000000002170 7776757473727170\n" " 0000000000002178 7f7e7d7c7b7a7978\n"; #else " 00001fc0 03020100\n" " 00001fc4 07060504\n" " 00001fc8 0b0a0908\n" " 00001fcc 0f0e0d0c\n" " 00001fd0 13121110\n" " 00001fd4 17161514\n" " 00001fd8 1b1a1918\n" " 00001fdc 1f1e1d1c\n" " 00001fe0 23222120\n" " 00001fe4 27262524\n" " 00001fe8 2b2a2928\n" " 00001fec 2f2e2d2c\n" " 00001ff0 33323130\n" " 00001ff4 37363534\n" " 00001ff8 3b3a3938\n" " 00001ffc 3f3e3d3c\n" " #00 00002000 03020100\n" " 00002004 07060504\n" " 00002008 0b0a0908\n" " 0000200c 0f0e0d0c\n" " #01 00002010 03020100\n" " 00002014 07060504\n" " 00002018 0b0a0908\n" " 0000201c 0f0e0d0c\n" " 00002020 13121110\n" " 00002024 17161514\n" " 00002028 1b1a1918\n" " 0000202c 1f1e1d1c\n" " 00002030 23222120\n" " 00002034 27262524\n" " 00002038 2b2a2928\n" " 0000203c 2f2e2d2c\n" " 00002040 33323130\n" " 00002044 37363534\n" " 00002048 3b3a3938\n" " 0000204c 3f3e3d3c\n" " ........ ........\n" " #02 00002100 03020100\n" " 00002104 07060504\n" " 00002108 0b0a0908\n" " 0000210c 0f0e0d0c\n" " 00002110 13121110\n" " 00002114 17161514\n" " 00002118 1b1a1918\n" " 0000211c 1f1e1d1c\n" " 00002120 23222120\n" " 00002124 27262524\n" " 00002128 2b2a2928\n" " 0000212c 2f2e2d2c\n" " 00002130 33323130\n" " 00002134 37363534\n" " 00002138 3b3a3938\n" " 0000213c 3f3e3d3c\n"; #endif EXPECT_EQ(expected, contents); } TEST_F(TombstoneTest, dump_stack_multiple_frames_disjoint_frames) { std::vector<unwindstack::FrameData> frames; unwindstack::Maps maps; MemoryPattern memory; frames.push_back( unwindstack::FrameData{.num = 0, .rel_pc = 0x1000, .pc = 0x301000, .sp = 0x2000}); frames.push_back( unwindstack::FrameData{.num = 0, .rel_pc = 0x1400, .pc = 0x301400, .sp = 0x2010}); frames.push_back( unwindstack::FrameData{.num = 0, .rel_pc = 0x1400, .pc = 0x301400, .sp = 0x1000}); frames.push_back( unwindstack::FrameData{.num = 0, .rel_pc = 0x1400, .pc = 0x301400, .sp = 0x1030}); dump_stack(&log_, frames, &maps, &memory); std::string contents; ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0); ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &contents)); std::string expected = #if defined(__LP64__) " 0000000000001f80 0706050403020100\n" " 0000000000001f88 0f0e0d0c0b0a0908\n" " 0000000000001f90 1716151413121110\n" " 0000000000001f98 1f1e1d1c1b1a1918\n" " 0000000000001fa0 2726252423222120\n" " 0000000000001fa8 2f2e2d2c2b2a2928\n" " 0000000000001fb0 3736353433323130\n" " 0000000000001fb8 3f3e3d3c3b3a3938\n" " 0000000000001fc0 4746454443424140\n" " 0000000000001fc8 4f4e4d4c4b4a4948\n" " 0000000000001fd0 5756555453525150\n" " 0000000000001fd8 5f5e5d5c5b5a5958\n" " 0000000000001fe0 6766656463626160\n" " 0000000000001fe8 6f6e6d6c6b6a6968\n" " 0000000000001ff0 7776757473727170\n" " 0000000000001ff8 7f7e7d7c7b7a7978\n" " #00 0000000000002000 0706050403020100\n" " 0000000000002008 0f0e0d0c0b0a0908\n" " #01 0000000000002010 0706050403020100\n" " 0000000000002018 0f0e0d0c0b0a0908\n" " 0000000000002020 1716151413121110\n" " 0000000000002028 1f1e1d1c1b1a1918\n" " 0000000000002030 2726252423222120\n" " 0000000000002038 2f2e2d2c2b2a2928\n" " 0000000000002040 3736353433323130\n" " 0000000000002048 3f3e3d3c3b3a3938\n" " 0000000000002050 4746454443424140\n" " 0000000000002058 4f4e4d4c4b4a4948\n" " 0000000000002060 5756555453525150\n" " 0000000000002068 5f5e5d5c5b5a5958\n" " 0000000000002070 6766656463626160\n" " 0000000000002078 6f6e6d6c6b6a6968\n" " 0000000000002080 7776757473727170\n" " 0000000000002088 7f7e7d7c7b7a7978\n" " ................ ................\n" " #02 0000000000001000 0706050403020100\n" " 0000000000001008 0f0e0d0c0b0a0908\n" " 0000000000001010 1716151413121110\n" " 0000000000001018 1f1e1d1c1b1a1918\n" " 0000000000001020 2726252423222120\n" " 0000000000001028 2f2e2d2c2b2a2928\n" " #03 0000000000001030 0706050403020100\n" " 0000000000001038 0f0e0d0c0b0a0908\n" " 0000000000001040 1716151413121110\n" " 0000000000001048 1f1e1d1c1b1a1918\n" " 0000000000001050 2726252423222120\n" " 0000000000001058 2f2e2d2c2b2a2928\n" " 0000000000001060 3736353433323130\n" " 0000000000001068 3f3e3d3c3b3a3938\n" " 0000000000001070 4746454443424140\n" " 0000000000001078 4f4e4d4c4b4a4948\n" " 0000000000001080 5756555453525150\n" " 0000000000001088 5f5e5d5c5b5a5958\n" " 0000000000001090 6766656463626160\n" " 0000000000001098 6f6e6d6c6b6a6968\n" " 00000000000010a0 7776757473727170\n" " 00000000000010a8 7f7e7d7c7b7a7978\n"; #else " 00001fc0 03020100\n" " 00001fc4 07060504\n" " 00001fc8 0b0a0908\n" " 00001fcc 0f0e0d0c\n" " 00001fd0 13121110\n" " 00001fd4 17161514\n" " 00001fd8 1b1a1918\n" " 00001fdc 1f1e1d1c\n" " 00001fe0 23222120\n" " 00001fe4 27262524\n" " 00001fe8 2b2a2928\n" " 00001fec 2f2e2d2c\n" " 00001ff0 33323130\n" " 00001ff4 37363534\n" " 00001ff8 3b3a3938\n" " 00001ffc 3f3e3d3c\n" " #00 00002000 03020100\n" " 00002004 07060504\n" " 00002008 0b0a0908\n" " 0000200c 0f0e0d0c\n" " #01 00002010 03020100\n" " 00002014 07060504\n" " 00002018 0b0a0908\n" " 0000201c 0f0e0d0c\n" " 00002020 13121110\n" " 00002024 17161514\n" " 00002028 1b1a1918\n" " 0000202c 1f1e1d1c\n" " 00002030 23222120\n" " 00002034 27262524\n" " 00002038 2b2a2928\n" " 0000203c 2f2e2d2c\n" " 00002040 33323130\n" " 00002044 37363534\n" " 00002048 3b3a3938\n" " 0000204c 3f3e3d3c\n" " ........ ........\n" " #02 00001000 03020100\n" " 00001004 07060504\n" " 00001008 0b0a0908\n" " 0000100c 0f0e0d0c\n" " 00001010 13121110\n" " 00001014 17161514\n" " 00001018 1b1a1918\n" " 0000101c 1f1e1d1c\n" " 00001020 23222120\n" " 00001024 27262524\n" " 00001028 2b2a2928\n" " 0000102c 2f2e2d2c\n" " #03 00001030 03020100\n" " 00001034 07060504\n" " 00001038 0b0a0908\n" " 0000103c 0f0e0d0c\n" " 00001040 13121110\n" " 00001044 17161514\n" " 00001048 1b1a1918\n" " 0000104c 1f1e1d1c\n" " 00001050 23222120\n" " 00001054 27262524\n" " 00001058 2b2a2928\n" " 0000105c 2f2e2d2c\n" " 00001060 33323130\n" " 00001064 37363534\n" " 00001068 3b3a3938\n" " 0000106c 3f3e3d3c\n"; #endif EXPECT_EQ(expected, contents); }
debuggerd/libdebuggerd/tombstone.cpp +0 −103 Original line number Diff line number Diff line Loading @@ -188,106 +188,6 @@ static void dump_thread_info(log_t* log, const ThreadInfo& thread_info) { _LOG(log, logtype::HEADER, "uid: %d\n", thread_info.uid); } static void dump_stack_segment(log_t* log, unwindstack::Maps* maps, unwindstack::Memory* memory, uint64_t* sp, size_t words, int label) { // Read the data all at once. word_t stack_data[words]; // TODO: Do we need to word align this for crashes caused by a misaligned sp? // The process_vm_readv implementation of Memory should handle this appropriately? size_t bytes_read = memory->Read(*sp, stack_data, sizeof(word_t) * words); words = bytes_read / sizeof(word_t); std::string line; for (size_t i = 0; i < words; i++) { line = " "; if (i == 0 && label >= 0) { // Print the label once. line += StringPrintf("#%02d ", label); } else { line += " "; } line += StringPrintf("%" PRIPTR " %" PRIPTR, *sp, static_cast<uint64_t>(stack_data[i])); unwindstack::MapInfo* map_info = maps->Find(stack_data[i]); if (map_info != nullptr && !map_info->name.empty()) { line += " " + map_info->name; std::string func_name; uint64_t func_offset = 0; if (map_info->GetFunctionName(stack_data[i], &func_name, &func_offset)) { line += " (" + func_name; if (func_offset) { line += StringPrintf("+%" PRIu64, func_offset); } line += ')'; } } _LOG(log, logtype::STACK, "%s\n", line.c_str()); *sp += sizeof(word_t); } } static void dump_stack(log_t* log, const std::vector<unwindstack::FrameData>& frames, unwindstack::Maps* maps, unwindstack::Memory* memory) { size_t first = 0, last; for (size_t i = 0; i < frames.size(); i++) { if (frames[i].sp) { if (!first) { first = i+1; } last = i; } } if (!first) { return; } first--; // Dump a few words before the first frame. uint64_t sp = frames[first].sp - STACK_WORDS * sizeof(word_t); dump_stack_segment(log, maps, memory, &sp, STACK_WORDS, -1); #if defined(__LP64__) static constexpr const char delimiter[] = " ................ ................\n"; #else static constexpr const char delimiter[] = " ........ ........\n"; #endif // Dump a few words from all successive frames. for (size_t i = first; i <= last; i++) { auto* frame = &frames[i]; if (sp != frame->sp) { _LOG(log, logtype::STACK, delimiter); sp = frame->sp; } if (i != last) { // Print stack data up to the stack from the next frame. size_t words; uint64_t next_sp = frames[i + 1].sp; if (next_sp < sp) { // The next frame is probably using a completely different stack, // so dump the max from this stack. words = STACK_WORDS; } else { words = (next_sp - sp) / sizeof(word_t); if (words == 0) { // The sp is the same as the next frame, print at least // one line for this frame. words = 1; } else if (words > STACK_WORDS) { words = STACK_WORDS; } } dump_stack_segment(log, maps, memory, &sp, words, i); } else { // Print some number of words past the last stack frame since we // don't know how large the stack is. dump_stack_segment(log, maps, memory, &sp, STACK_WORDS, i); } } } static std::string get_addr_string(uint64_t addr) { std::string addr_str; #if defined(__LP64__) Loading Loading @@ -499,9 +399,6 @@ static bool dump_thread(log_t* log, unwindstack::Unwinder* unwinder, const Threa } else { _LOG(log, logtype::BACKTRACE, "\nbacktrace:\n"); log_backtrace(log, unwinder, " "); _LOG(log, logtype::STACK, "\nstack:\n"); dump_stack(log, unwinder->frames(), unwinder->GetMaps(), unwinder->GetProcessMemory().get()); } if (primary_thread) { Loading