Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f8c0350e authored by Elliott Hughes's avatar Elliott Hughes Committed by Gerrit Code Review
Browse files

Merge "debuggerd: remove the raw stack dump."

parents 2148b252 627928e0
Loading
Loading
Loading
Loading
+0 −464
Original line number Diff line number Diff line
@@ -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);
}
+0 −103
Original line number Diff line number Diff line
@@ -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__)
@@ -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) {