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

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

Merge "Include the map name when dumping memory around a register."

parents 851803d3 e1415a5c
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -68,7 +68,7 @@ namespace unwindstack {
class Memory;
}

void dump_memory(log_t* log, unwindstack::Memory* backtrace, uint64_t addr, const char* fmt, ...);
void dump_memory(log_t* log, unwindstack::Memory* backtrace, uint64_t addr, const std::string&);

void read_with_default(const char* path, char* buf, size_t len, const char* default_value);

+23 −23
Original line number Diff line number Diff line
@@ -201,7 +201,7 @@ TEST_F(DumpMemoryTest, aligned_addr) {
  }
  memory_mock_->SetReadData(buffer, sizeof(buffer));

  dump_memory(&log_, memory_mock_.get(), 0x12345678, "memory near %.2s:", "r1");
  dump_memory(&log_, memory_mock_.get(), 0x12345678, "memory near r1");

  std::string tombstone_contents;
  ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
@@ -221,7 +221,7 @@ TEST_F(DumpMemoryTest, partial_read) {
  memory_mock_->SetReadData(buffer, sizeof(buffer));
  memory_mock_->SetPartialReadAmount(96);

  dump_memory(&log_, memory_mock_.get(), 0x12345679, "memory near %.2s:", "r1");
  dump_memory(&log_, memory_mock_.get(), 0x12345679, "memory near r1");

  std::string tombstone_contents;
  ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
@@ -240,7 +240,7 @@ TEST_F(DumpMemoryTest, unaligned_addr) {
  }
  memory_mock_->SetReadData(buffer, sizeof(buffer));

  dump_memory(&log_, memory_mock_.get(), 0x12345679, "memory near %.2s:", "r1");
  dump_memory(&log_, memory_mock_.get(), 0x12345679, "memory near r1");

  std::string tombstone_contents;
  ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
@@ -253,7 +253,7 @@ TEST_F(DumpMemoryTest, unaligned_addr) {
}

TEST_F(DumpMemoryTest, memory_unreadable) {
  dump_memory(&log_, memory_mock_.get(), 0xa2345678, "memory near pc:");
  dump_memory(&log_, memory_mock_.get(), 0xa2345678, "memory near pc");

  std::string tombstone_contents;
  ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
@@ -309,7 +309,7 @@ TEST_F(DumpMemoryTest, memory_partially_unreadable) {
  }
  memory_mock_->SetReadData(buffer, sizeof(buffer));

  dump_memory(&log_, memory_mock_.get(), 0x12345600, "memory near pc:");
  dump_memory(&log_, memory_mock_.get(), 0x12345600, "memory near pc");

  std::string tombstone_contents;
  ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
@@ -329,7 +329,7 @@ TEST_F(DumpMemoryTest, memory_partially_unreadable_unaligned_return) {
  memory_mock_->SetReadData(buffer, sizeof(buffer));
  memory_mock_->SetPartialReadAmount(102);

  dump_memory(&log_, memory_mock_.get(), 0x12345600, "memory near pc:");
  dump_memory(&log_, memory_mock_.get(), 0x12345600, "memory near pc");

  std::string tombstone_contents;
  ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
@@ -354,7 +354,7 @@ TEST_F(DumpMemoryTest, memory_partially_unreadable_two_unaligned_reads) {
  memory_mock_->SetReadData(buffer, sizeof(buffer));
  memory_mock_->SetPartialReadAmount(45);

  dump_memory(&log_, memory_mock_.get(), 0x12345600, "memory near pc:");
  dump_memory(&log_, memory_mock_.get(), 0x12345600, "memory near pc");

  std::string tombstone_contents;
  ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
@@ -380,7 +380,7 @@ TEST_F(DumpMemoryTest, address_low_fence) {
  memset(buffer, 0, sizeof(buffer));
  memory_mock_->SetReadData(buffer, sizeof(buffer));

  dump_memory(&log_, memory_mock_.get(), 0x1000, "memory near %.2s:", "r1");
  dump_memory(&log_, memory_mock_.get(), 0x1000, "memory near r1");

  std::string tombstone_contents;
  ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
@@ -434,7 +434,7 @@ TEST_F(DumpMemoryTest, memory_address_too_low) {
  memset(buffer, 0, sizeof(buffer));
  memory_mock_->SetReadData(buffer, sizeof(buffer));

  dump_memory(&log_, memory_mock_.get(), 0, "memory near %.2s:", "r1");
  dump_memory(&log_, memory_mock_.get(), 0, "memory near r1");

  std::string tombstone_contents;
  ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
@@ -452,13 +452,13 @@ TEST_F(DumpMemoryTest, memory_address_too_high) {
  memory_mock_->SetReadData(buffer, sizeof(buffer));

#if defined(__LP64__)
  dump_memory(&log_, memory_mock_.get(), 0x4000000000000000UL, "memory near %.2s:", "r1");
  dump_memory(&log_, memory_mock_.get(), 0x4000000000000000UL - 32, "memory near %.2s:", "r1");
  dump_memory(&log_, memory_mock_.get(), 0x4000000000000000UL - 216, "memory near %.2s:", "r1");
  dump_memory(&log_, memory_mock_.get(), 0x4000000000000000UL, "memory near r1");
  dump_memory(&log_, memory_mock_.get(), 0x4000000000000000UL - 32, "memory near r1");
  dump_memory(&log_, memory_mock_.get(), 0x4000000000000000UL - 216, "memory near r1");
#else
  dump_memory(&log_, memory_mock_.get(), 0xffff0000, "memory near %.2s:", "r1");
  dump_memory(&log_, memory_mock_.get(), 0xffff0000 - 32, "memory near %.2s:", "r1");
  dump_memory(&log_, memory_mock_.get(), 0xffff0000 - 220, "memory near %.2s:", "r1");
  dump_memory(&log_, memory_mock_.get(), 0xffff0000, "memory near r1");
  dump_memory(&log_, memory_mock_.get(), 0xffff0000 - 32, "memory near r1");
  dump_memory(&log_, memory_mock_.get(), 0xffff0000 - 220, "memory near r1");
#endif

  std::string tombstone_contents;
@@ -477,9 +477,9 @@ TEST_F(DumpMemoryTest, memory_address_would_overflow) {
  memory_mock_->SetReadData(buffer, sizeof(buffer));

#if defined(__LP64__)
  dump_memory(&log_, memory_mock_.get(), 0xfffffffffffffff0, "memory near %.2s:", "r1");
  dump_memory(&log_, memory_mock_.get(), 0xfffffffffffffff0, "memory near r1");
#else
  dump_memory(&log_, memory_mock_.get(), 0xfffffff0, "memory near %.2s:", "r1");
  dump_memory(&log_, memory_mock_.get(), 0xfffffff0, "memory near r1");
#endif

  std::string tombstone_contents;
@@ -500,9 +500,9 @@ TEST_F(DumpMemoryTest, memory_address_nearly_too_high) {
  memory_mock_->SetReadData(buffer, sizeof(buffer));

#if defined(__LP64__)
  dump_memory(&log_, memory_mock_.get(), 0x4000000000000000UL - 224, "memory near %.2s:", "r4");
  dump_memory(&log_, memory_mock_.get(), 0x4000000000000000UL - 224, "memory near r4");
#else
  dump_memory(&log_, memory_mock_.get(), 0xffff0000 - 224, "memory near %.2s:", "r4");
  dump_memory(&log_, memory_mock_.get(), 0xffff0000 - 224, "memory near r4");
#endif

  std::string tombstone_contents;
@@ -562,7 +562,7 @@ TEST_F(DumpMemoryTest, first_read_empty) {

  size_t page_size = sysconf(_SC_PAGE_SIZE);
  uintptr_t addr = 0x10000020 + page_size - 120;
  dump_memory(&log_, memory_mock_.get(), addr, "memory near %.2s:", "r4");
  dump_memory(&log_, memory_mock_.get(), addr, "memory near r4");

  std::string tombstone_contents;
  ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
@@ -621,7 +621,7 @@ TEST_F(DumpMemoryTest, first_read_empty_second_read_stops) {

  size_t page_size = sysconf(_SC_PAGE_SIZE);
  uintptr_t addr = 0x10000020 + page_size - 192;
  dump_memory(&log_, memory_mock_.get(), addr, "memory near %.2s:", "r4");
  dump_memory(&log_, memory_mock_.get(), addr, "memory near r4");

  std::string tombstone_contents;
  ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
@@ -679,7 +679,7 @@ TEST_F(DumpMemoryTest, first_read_empty_next_page_out_of_range) {
  memory_mock_->SetPartialReadAmount(0);

  uintptr_t addr = 0x10000020;
  dump_memory(&log_, memory_mock_.get(), addr, "memory near %.2s:", "r4");
  dump_memory(&log_, memory_mock_.get(), addr, "memory near r4");

  std::string tombstone_contents;
  ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
@@ -739,7 +739,7 @@ TEST_F(DumpMemoryTest, first_read_empty_next_page_out_of_range_fence_post) {
  size_t page_size = sysconf(_SC_PAGE_SIZE);
  uintptr_t addr = 0x10000020 + page_size - 256;

  dump_memory(&log_, memory_mock_.get(), addr, "memory near %.2s:", "r4");
  dump_memory(&log_, memory_mock_.get(), addr, "memory near r4");

  std::string tombstone_contents;
  ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
+16 −6
Original line number Diff line number Diff line
@@ -65,6 +65,8 @@ using android::base::unique_fd;
using unwindstack::Memory;
using unwindstack::Regs;

using namespace std::literals::string_literals;

#define STACK_WORDS 16

static void dump_header_info(log_t* log) {
@@ -148,8 +150,9 @@ static void dump_stack_segment(log_t* log, BacktraceMap* backtrace_map, Memory*

    backtrace_map_t map;
    backtrace_map->FillIn(stack_data[i], &map);
    if (BacktraceMap::IsValid(map) && !map.name.empty()) {
      line += "  " + map.name;
    std::string map_name{map.Name()};
    if (BacktraceMap::IsValid(map) && !map_name.empty()) {
      line += "  " + map_name;
      uint64_t offset = 0;
      std::string func_name = backtrace_map->GetFunctionName(stack_data[i], &offset);
      if (!func_name.empty()) {
@@ -382,9 +385,16 @@ void dump_registers(log_t* log, Regs* regs) {
  print_register_row(log, special_row);
}

void dump_memory_and_code(log_t* log, Memory* memory, Regs* regs) {
  regs->IterateRegisters([log, memory](const char* name, uint64_t value) {
    dump_memory(log, memory, value, "memory near %s:", name);
void dump_memory_and_code(log_t* log, BacktraceMap* map, Memory* memory, Regs* regs) {
  regs->IterateRegisters([log, map, memory](const char* reg_name, uint64_t reg_value) {
    std::string label{"memory near "s + reg_name};
    if (map) {
      backtrace_map_t map_info;
      map->FillIn(reg_value, &map_info);
      std::string map_name{map_info.Name()};
      if (!map_name.empty()) label += " (" + map_info.Name() + ")";
    }
    dump_memory(log, memory, reg_value, label);
  });
}

@@ -423,7 +433,7 @@ static bool dump_thread(log_t* log, BacktraceMap* map, Memory* process_memory,
  }

  if (primary_thread) {
    dump_memory_and_code(log, process_memory, thread_info.registers.get());
    dump_memory_and_code(log, map, process_memory, thread_info.registers.get());
    if (map) {
      uint64_t addr = 0;
      siginfo_t* si = thread_info.siginfo;
+2 −8
Original line number Diff line number Diff line
@@ -124,13 +124,7 @@ void _LOG(log_t* log, enum logtype ltype, const char* fmt, ...) {
#define MEMORY_BYTES_TO_DUMP 256
#define MEMORY_BYTES_PER_LINE 16

void dump_memory(log_t* log, unwindstack::Memory* memory, uint64_t addr, const char* fmt, ...) {
  std::string log_msg;
  va_list ap;
  va_start(ap, fmt);
  android::base::StringAppendV(&log_msg, fmt, ap);
  va_end(ap);

void dump_memory(log_t* log, unwindstack::Memory* memory, uint64_t addr, const std::string& label) {
  // Align the address to sizeof(long) and start 32 bytes before the address.
  addr &= ~(sizeof(long) - 1);
  if (addr >= 4128) {
@@ -147,7 +141,7 @@ void dump_memory(log_t* log, unwindstack::Memory* memory, uint64_t addr, const c
    return;
  }

  _LOG(log, logtype::MEMORY, "\n%s\n", log_msg.c_str());
  _LOG(log, logtype::MEMORY, "\n%s:\n", label.c_str());

  // Dump 256 bytes
  uintptr_t data[MEMORY_BYTES_TO_DUMP/sizeof(uintptr_t)];
+1 −3
Original line number Diff line number Diff line
@@ -85,14 +85,12 @@ std::string Backtrace::FormatFrameData(size_t frame_num) {
std::string Backtrace::FormatFrameData(const backtrace_frame_data_t* frame) {
  std::string map_name;
  if (BacktraceMap::IsValid(frame->map)) {
    map_name = frame->map.Name();
    if (!frame->map.name.empty()) {
      map_name = frame->map.name.c_str();
      if (map_name[0] == '[' && map_name[map_name.size() - 1] == ']') {
        map_name.resize(map_name.size() - 1);
        map_name += StringPrintf(":%" PRIPTR "]", frame->map.start);
      }
    } else {
      map_name = StringPrintf("<anonymous:%" PRIPTR ">", frame->map.start);
    }
  } else {
    map_name = "<unknown>";
Loading