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

Commit 7b2078ee authored by Brigid Smith's avatar Brigid Smith
Browse files

Changed maps output in debuggerd.

Now the map output is only sent to the tombstone, and the entire
contents of /prod/$PID/maps is logged, not just 3 lines.  Additionally,
crasher now supports "crasher SIGSEGV-non-null", which attempts to write to a
dereferenced function address, causing a SIGSEGV at a non-zero address.
This new crasher mode can be used to test the new maps output.

Bug: 15343662
Change-Id: I796d92e8352a6b9714bbbfe96f3143c56565ef2f
parent 5bc6b5b8
Loading
Loading
Loading
Loading
+9 −1
Original line number Diff line number Diff line
@@ -110,12 +110,19 @@ static void abuse_heap() {
    free((void*) buf); // GCC is smart enough to warn about this, but we're doing it deliberately.
}

static void sigsegv_non_null() {
    int* a = (int *)(&do_action);
    *a = 42;
}

static int do_action(const char* arg)
{
    fprintf(stderr,"crasher: init pid=%d tid=%d\n", getpid(), gettid());

    if (!strncmp(arg, "thread-", strlen("thread-"))) {
        return do_action_on_thread(arg + strlen("thread-"));
    } else if (!strcmp(arg, "SIGSEGV-non-null")) {
        sigsegv_non_null();
    } else if (!strcmp(arg, "smash-stack")) {
        return smash_stack(42);
    } else if (!strcmp(arg, "stack-overflow")) {
@@ -166,7 +173,8 @@ static int do_action(const char* arg)
    fprintf(stderr, "  LOG_ALWAYS_FATAL      call LOG_ALWAYS_FATAL\n");
    fprintf(stderr, "  LOG_ALWAYS_FATAL_IF   call LOG_ALWAYS_FATAL\n");
    fprintf(stderr, "  SIGPIPE               cause a SIGPIPE\n");
    fprintf(stderr, "  SIGSEGV               cause a SIGSEGV (synonym: crash)\n");
    fprintf(stderr, "  SIGSEGV               cause a SIGSEGV at address 0x0 (synonym: crash)\n");
    fprintf(stderr, "  SIGSEGV-non-null      cause a SIGSEGV at a non-zero address\n");
    fprintf(stderr, "  SIGTRAP               cause a SIGTRAP\n");
    fprintf(stderr, "prefix any of the above with 'thread-' to not run\n");
    fprintf(stderr, "on the process' main thread.\n");
+4 −28
Original line number Diff line number Diff line
@@ -343,14 +343,10 @@ static void dump_backtrace_and_stack(Backtrace* backtrace, log_t* log) {
  }
}

static void dump_map(log_t* log, const backtrace_map_t* map, const char* what) {
  if (map != NULL) {
static void dump_map(log_t* log, const backtrace_map_t* map) {
  _LOG(log, logtype::MAPS, "    %" PRIPTR "-%" PRIPTR " %c%c%c %s\n", map->start, map->end,
         (map->flags & PROT_READ) ? 'r' : '-', (map->flags & PROT_WRITE) ? 'w' : '-',
         (map->flags & PROT_EXEC) ? 'x' : '-', map->name.c_str());
  } else {
    _LOG(log, logtype::MAPS, "    (no %s)\n", what);
  }
}

static void dump_nearby_maps(BacktraceMap* map, log_t* log, pid_t tid) {
@@ -370,31 +366,11 @@ static void dump_nearby_maps(BacktraceMap* map, log_t* log, pid_t tid) {
    return;
  }

  _LOG(log, logtype::MAPS, "\nmemory map around fault addr %" PRIPTR ":\n",
       reinterpret_cast<uintptr_t>(si.si_addr));
  _LOG(log, logtype::MAPS, "\nmemory map:\n");

  // Search for a match, or for a hole where the match would be.  The list
  // is backward from the file content, so it starts at high addresses.
  const backtrace_map_t* cur_map = NULL;
  const backtrace_map_t* next_map = NULL;
  const backtrace_map_t* prev_map = NULL;
  for (BacktraceMap::const_iterator it = map->begin(); it != map->end(); ++it) {
    if (addr >= it->start && addr < it->end) {
      cur_map = &*it;
      if (it != map->begin()) {
        prev_map = &*(it-1);
    dump_map(log, &*it);
  }
      if (++it != map->end()) {
        next_map = &*it;
      }
      break;
    }
  }

  // Show the map address in ascending order (like /proc/pid/maps).
  dump_map(log, prev_map, "map below");
  dump_map(log, cur_map, "map for address");
  dump_map(log, next_map, "map above");
}

static void dump_thread(