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

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

Merge "Changing how debuggerd filters log messages to different locations."

parents 60218f19 62ba489b
Loading
Loading
Loading
Loading
+25 −27
Original line number Diff line number Diff line
@@ -40,13 +40,12 @@

// If configured to do so, dump memory around *all* registers
// for the crashing thread.
void dump_memory_and_code(log_t* log, pid_t tid, int scope_flags) {
void dump_memory_and_code(log_t* log, pid_t tid) {
  struct pt_regs regs;
  if (ptrace(PTRACE_GETREGS, tid, 0, &regs)) {
    return;
  }

  if (IS_AT_FAULT(scope_flags) && DUMP_MEMORY_FOR_ALL_REGISTERS) {
  static const char REG_NAMES[] = "r0r1r2r3r4r5r6r7r8r9slfpipsp";

  for (int reg = 0; reg < 14; reg++) {
@@ -59,38 +58,37 @@ void dump_memory_and_code(log_t* log, pid_t tid, int scope_flags) {
      continue;
    }

      _LOG(log, scope_flags | SCOPE_SENSITIVE, "\nmemory near %.2s:\n", &REG_NAMES[reg * 2]);
      dump_memory(log, tid, addr, scope_flags | SCOPE_SENSITIVE);
    }
    _LOG(log, logtype::MEMORY, "\nmemory near %.2s:\n", &REG_NAMES[reg * 2]);
    dump_memory(log, tid, addr);
  }

  // explicitly allow upload of code dump logging
  _LOG(log, scope_flags, "\ncode around pc:\n");
  dump_memory(log, tid, static_cast<uintptr_t>(regs.ARM_pc), scope_flags);
  _LOG(log, logtype::MEMORY, "\ncode around pc:\n");
  dump_memory(log, tid, static_cast<uintptr_t>(regs.ARM_pc));

  if (regs.ARM_pc != regs.ARM_lr) {
    _LOG(log, scope_flags, "\ncode around lr:\n");
    dump_memory(log, tid, static_cast<uintptr_t>(regs.ARM_lr), scope_flags);
    _LOG(log, logtype::MEMORY, "\ncode around lr:\n");
    dump_memory(log, tid, static_cast<uintptr_t>(regs.ARM_lr));
  }
}

void dump_registers(log_t* log, pid_t tid, int scope_flags) {
void dump_registers(log_t* log, pid_t tid) {
  struct pt_regs r;
  if (ptrace(PTRACE_GETREGS, tid, 0, &r)) {
    _LOG(log, scope_flags, "cannot get registers: %s\n", strerror(errno));
    _LOG(log, logtype::REGISTERS, "cannot get registers: %s\n", strerror(errno));
    return;
  }

  _LOG(log, scope_flags, "    r0 %08x  r1 %08x  r2 %08x  r3 %08x\n",
  _LOG(log, logtype::REGISTERS, "    r0 %08x  r1 %08x  r2 %08x  r3 %08x\n",
       static_cast<uint32_t>(r.ARM_r0), static_cast<uint32_t>(r.ARM_r1),
       static_cast<uint32_t>(r.ARM_r2), static_cast<uint32_t>(r.ARM_r3));
  _LOG(log, scope_flags, "    r4 %08x  r5 %08x  r6 %08x  r7 %08x\n",
  _LOG(log, logtype::REGISTERS, "    r4 %08x  r5 %08x  r6 %08x  r7 %08x\n",
       static_cast<uint32_t>(r.ARM_r4), static_cast<uint32_t>(r.ARM_r5),
       static_cast<uint32_t>(r.ARM_r6), static_cast<uint32_t>(r.ARM_r7));
  _LOG(log, scope_flags, "    r8 %08x  r9 %08x  sl %08x  fp %08x\n",
  _LOG(log, logtype::REGISTERS, "    r8 %08x  r9 %08x  sl %08x  fp %08x\n",
       static_cast<uint32_t>(r.ARM_r8), static_cast<uint32_t>(r.ARM_r9),
       static_cast<uint32_t>(r.ARM_r10), static_cast<uint32_t>(r.ARM_fp));
  _LOG(log, scope_flags, "    ip %08x  sp %08x  lr %08x  pc %08x  cpsr %08x\n",
  _LOG(log, logtype::REGISTERS, "    ip %08x  sp %08x  lr %08x  pc %08x  cpsr %08x\n",
       static_cast<uint32_t>(r.ARM_ip), static_cast<uint32_t>(r.ARM_sp),
       static_cast<uint32_t>(r.ARM_lr), static_cast<uint32_t>(r.ARM_pc),
       static_cast<uint32_t>(r.ARM_cpsr));
@@ -100,14 +98,14 @@ void dump_registers(log_t* log, pid_t tid, int scope_flags) {
  int i;

  if (ptrace(PTRACE_GETVFPREGS, tid, 0, &vfp_regs)) {
    _LOG(log, scope_flags, "cannot get registers: %s\n", strerror(errno));
    _LOG(log, logtype::REGISTERS, "cannot get registers: %s\n", strerror(errno));
    return;
  }

  for (i = 0; i < NUM_VFP_REGS; i += 2) {
    _LOG(log, scope_flags, "    d%-2d %016llx  d%-2d %016llx\n",
    _LOG(log, logtype::REGISTERS, "    d%-2d %016llx  d%-2d %016llx\n",
         i, vfp_regs.fpregs[i], i+1, vfp_regs.fpregs[i+1]);
  }
  _LOG(log, scope_flags, "    scr %08lx\n", vfp_regs.fpscr);
  _LOG(log, logtype::REGISTERS, "    scr %08lx\n", vfp_regs.fpscr);
#endif
}
+25 −27
Original line number Diff line number Diff line
@@ -37,19 +37,18 @@
 * If configured to do so, dump memory around *all* registers
 * for the crashing thread.
 */
void dump_memory_and_code(log_t* log, pid_t tid, int scope_flags) {
void dump_memory_and_code(log_t* log, pid_t tid) {
    struct user_pt_regs regs;
    struct iovec io;
    io.iov_base = &regs;
    io.iov_len = sizeof(regs);

    if (ptrace(PTRACE_GETREGSET, tid, (void*)NT_PRSTATUS, &io) == -1) {
        _LOG(log, scope_flags, "%s: ptrace failed to get registers: %s\n",
        LOG_ERROR("%s: ptrace failed to get registers: %s\n",
             __func__, strerror(errno));
        return;
    }

    if (IS_AT_FAULT(scope_flags) && DUMP_MEMORY_FOR_ALL_REGISTERS) {
    for (int reg = 0; reg < 31; reg++) {
        uintptr_t addr = regs.regs[reg];

@@ -61,44 +60,43 @@ void dump_memory_and_code(log_t* log, pid_t tid, int scope_flags) {
            continue;
        }

            _LOG(log, scope_flags | SCOPE_SENSITIVE, "\nmemory near x%d:\n", reg);
            dump_memory(log, tid, addr, scope_flags | SCOPE_SENSITIVE);
        }
        _LOG(log, logtype::MEMORY, "\nmemory near x%d:\n", reg);
        dump_memory(log, tid, addr);
    }

    _LOG(log, scope_flags, "\ncode around pc:\n");
    dump_memory(log, tid, (uintptr_t)regs.pc, scope_flags);
    _LOG(log, logtype::MEMORY, "\ncode around pc:\n");
    dump_memory(log, tid, (uintptr_t)regs.pc);

    if (regs.pc != regs.sp) {
        _LOG(log, scope_flags, "\ncode around sp:\n");
        dump_memory(log, tid, (uintptr_t)regs.sp, scope_flags);
        _LOG(log, logtype::MEMORY, "\ncode around sp:\n");
        dump_memory(log, tid, (uintptr_t)regs.sp);
    }
}

void dump_registers(log_t* log, pid_t tid, int scope_flags)
{
void dump_registers(log_t* log, pid_t tid) {
  struct user_pt_regs r;
  struct iovec io;
  io.iov_base = &r;
  io.iov_len = sizeof(r);

  if (ptrace(PTRACE_GETREGSET, tid, (void*) NT_PRSTATUS, (void*) &io) == -1) {
    _LOG(log, scope_flags, "ptrace error: %s\n", strerror(errno));
    LOG_ERROR("ptrace error: %s\n", strerror(errno));
    return;
  }

  for (int i = 0; i < 28; i += 4) {
    _LOG(log, scope_flags, "    x%-2d  %016lx  x%-2d  %016lx  x%-2d  %016lx  x%-2d  %016lx\n",
    _LOG(log, logtype::REGISTERS,
         "    x%-2d  %016lx  x%-2d  %016lx  x%-2d  %016lx  x%-2d  %016lx\n",
         i, (uint64_t)r.regs[i],
         i+1, (uint64_t)r.regs[i+1],
         i+2, (uint64_t)r.regs[i+2],
         i+3, (uint64_t)r.regs[i+3]);
  }

  _LOG(log, scope_flags, "    x28  %016lx  x29  %016lx  x30  %016lx\n",
  _LOG(log, logtype::REGISTERS, "    x28  %016lx  x29  %016lx  x30  %016lx\n",
       (uint64_t)r.regs[28], (uint64_t)r.regs[29], (uint64_t)r.regs[30]);

  _LOG(log, scope_flags, "    sp   %016lx  pc   %016lx\n",
  _LOG(log, logtype::REGISTERS, "    sp   %016lx  pc   %016lx\n",
       (uint64_t)r.sp, (uint64_t)r.pc);


@@ -107,12 +105,12 @@ void dump_registers(log_t* log, pid_t tid, int scope_flags)
  io.iov_len = sizeof(f);

  if (ptrace(PTRACE_GETREGSET, tid, (void*) NT_PRFPREG, (void*) &io) == -1) {
    _LOG(log, scope_flags, "ptrace error: %s\n", strerror(errno));
    LOG_ERROR("ptrace error: %s\n", strerror(errno));
    return;
  }

  for (int i = 0; i < 32; i += 4) {
    _LOG(log, scope_flags, "    v%-2d  %016lx  v%-2d  %016lx  v%-2d  %016lx  v%-2d  %016lx\n",
    _LOG(log, logtype::REGISTERS, "    v%-2d  %016lx  v%-2d  %016lx  v%-2d  %016lx  v%-2d  %016lx\n",
         i, (uint64_t)f.vregs[i],
         i+1, (uint64_t)f.vregs[i+1],
         i+2, (uint64_t)f.vregs[i+2],
+10 −10
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@
#include <UniquePtr.h>

#include "backtrace.h"

#include "utility.h"

static void dump_process_header(log_t* log, pid_t pid) {
@@ -49,15 +50,15 @@ static void dump_process_header(log_t* log, pid_t pid) {
  localtime_r(&t, &tm);
  char timestr[64];
  strftime(timestr, sizeof(timestr), "%F %T", &tm);
  _LOG(log, SCOPE_AT_FAULT, "\n\n----- pid %d at %s -----\n", pid, timestr);
  _LOG(log, logtype::BACKTRACE, "\n\n----- pid %d at %s -----\n", pid, timestr);

  if (procname) {
    _LOG(log, SCOPE_AT_FAULT, "Cmd line: %s\n", procname);
    _LOG(log, logtype::BACKTRACE, "Cmd line: %s\n", procname);
  }
}

static void dump_process_footer(log_t* log, pid_t pid) {
  _LOG(log, SCOPE_AT_FAULT, "\n----- end %d -----\n", pid);
  _LOG(log, logtype::BACKTRACE, "\n----- end %d -----\n", pid);
}

static void dump_thread(
@@ -79,10 +80,10 @@ static void dump_thread(
    }
  }

  _LOG(log, SCOPE_AT_FAULT, "\n\"%s\" sysTid=%d\n", threadname ? threadname : "<unknown>", tid);
  _LOG(log, logtype::BACKTRACE, "\n\"%s\" sysTid=%d\n", threadname ? threadname : "<unknown>", tid);

  if (!attached && ptrace(PTRACE_ATTACH, tid, 0, 0) < 0) {
    _LOG(log, SCOPE_AT_FAULT, "Could not attach to thread: %s\n", strerror(errno));
    _LOG(log, logtype::BACKTRACE, "Could not attach to thread: %s\n", strerror(errno));
    return;
  }

@@ -90,11 +91,11 @@ static void dump_thread(

  UniquePtr<Backtrace> backtrace(Backtrace::Create(tid, BACKTRACE_CURRENT_THREAD));
  if (backtrace->Unwind(0)) {
    dump_backtrace_to_log(backtrace.get(), log, SCOPE_AT_FAULT, "  ");
    dump_backtrace_to_log(backtrace.get(), log, "  ");
  }

  if (!attached && ptrace(PTRACE_DETACH, tid, 0, 0) != 0) {
    LOG("ptrace detach from %d failed: %s\n", tid, strerror(errno));
    LOG_ERROR("ptrace detach from %d failed: %s\n", tid, strerror(errno));
    *detach_failed = true;
  }
}
@@ -133,9 +134,8 @@ void dump_backtrace(int fd, int amfd, pid_t pid, pid_t tid, bool* detach_failed,
  dump_process_footer(&log, pid);
}

void dump_backtrace_to_log(Backtrace* backtrace, log_t* log,
                           int scope_flags, const char* prefix) {
void dump_backtrace_to_log(Backtrace* backtrace, log_t* log, const char* prefix) {
  for (size_t i = 0; i < backtrace->NumFrames(); i++) {
    _LOG(log, scope_flags, "%s%s\n", prefix, backtrace->FormatFrameData(i).c_str());
    _LOG(log, logtype::BACKTRACE, "%s%s\n", prefix, backtrace->FormatFrameData(i).c_str());
  }
}
+1 −2
Original line number Diff line number Diff line
@@ -29,7 +29,6 @@ void dump_backtrace(int fd, int amfd, pid_t pid, pid_t tid, bool* detach_failed,
                    int* total_sleep_time_usec);

/* Dumps the backtrace in the backtrace data structure to the log. */
void dump_backtrace_to_log(Backtrace* backtrace, log_t* log,
                           int scope_flags, const char* prefix);
void dump_backtrace_to_log(Backtrace* backtrace, log_t* log, const char* prefix);

#endif // _DEBUGGERD_BACKTRACE_H
+17 −18
Original line number Diff line number Diff line
@@ -30,7 +30,6 @@
#include <sys/stat.h>
#include <sys/poll.h>

#include <log/logd.h>
#include <log/logger.h>

#include <cutils/sockets.h>
@@ -62,7 +61,7 @@ static void wait_for_user_action(pid_t pid) {
  char exe[PATH_MAX];
  int count;
  if ((count = readlink(path, exe, sizeof(exe) - 1)) == -1) {
    LOG("readlink('%s') failed: %s", path, strerror(errno));
    LOG_ERROR("readlink('%s') failed: %s", path, strerror(errno));
    strlcpy(exe, "unknown", sizeof(exe));
  } else {
    exe[count] = '\0';
@@ -79,7 +78,7 @@ static void wait_for_user_action(pid_t pid) {
  }

  // Explain how to attach the debugger.
  LOG(    "********************************************************\n"
  LOG_ERROR(    "********************************************************\n"
          "* Process %d has been suspended while crashing.\n"
          "* To attach gdbserver for a gdb connection on port 5039\n"
          "* and start gdbclient:\n"
@@ -104,7 +103,7 @@ static void wait_for_user_action(pid_t pid) {
    uninit_getevent();
  }

  LOG("debuggerd resuming process %d", pid);
  LOG_ERROR("debuggerd resuming process %d", pid);
}

static int get_process_info(pid_t tid, pid_t* out_pid, uid_t* out_uid, uid_t* out_gid) {
@@ -140,7 +139,7 @@ static int read_request(int fd, debugger_request_t* out_request) {
  socklen_t len = sizeof(cr);
  int status = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &cr, &len);
  if (status != 0) {
    LOG("cannot get credentials\n");
    LOG_ERROR("cannot get credentials\n");
    return -1;
  }

@@ -153,7 +152,7 @@ static int read_request(int fd, debugger_request_t* out_request) {
  pollfds[0].revents = 0;
  status = TEMP_FAILURE_RETRY(poll(pollfds, 1, 3000));
  if (status != 1) {
    LOG("timed out reading tid (from pid=%d uid=%d)\n", cr.pid, cr.uid);
    LOG_ERROR("timed out reading tid (from pid=%d uid=%d)\n", cr.pid, cr.uid);
    return -1;
  }

@@ -161,14 +160,14 @@ static int read_request(int fd, debugger_request_t* out_request) {
  memset(&msg, 0, sizeof(msg));
  status = TEMP_FAILURE_RETRY(read(fd, &msg, sizeof(msg)));
  if (status < 0) {
    LOG("read failure? %s (pid=%d uid=%d)\n", strerror(errno), cr.pid, cr.uid);
    LOG_ERROR("read failure? %s (pid=%d uid=%d)\n", strerror(errno), cr.pid, cr.uid);
    return -1;
  }
  if (status == sizeof(debugger_msg_t)) {
    XLOG("crash request of size %d abort_msg_address=0x%" PRIPTR "\n",
         status, msg.abort_msg_address);
  } else {
    LOG("invalid crash request of size %d (from pid=%d uid=%d)\n", status, cr.pid, cr.uid);
    LOG_ERROR("invalid crash request of size %d (from pid=%d uid=%d)\n", status, cr.pid, cr.uid);
    return -1;
  }

@@ -186,7 +185,7 @@ static int read_request(int fd, debugger_request_t* out_request) {
    struct stat s;
    snprintf(buf, sizeof buf, "/proc/%d/task/%d", out_request->pid, out_request->tid);
    if (stat(buf, &s)) {
      LOG("tid %d does not exist in pid %d. ignoring debug request\n",
      LOG_ERROR("tid %d does not exist in pid %d. ignoring debug request\n",
          out_request->tid, out_request->pid);
      return -1;
    }
@@ -197,7 +196,7 @@ static int read_request(int fd, debugger_request_t* out_request) {
    status = get_process_info(out_request->tid, &out_request->pid,
                              &out_request->uid, &out_request->gid);
    if (status < 0) {
      LOG("tid %d does not exist. ignoring explicit dump request\n", out_request->tid);
      LOG_ERROR("tid %d does not exist. ignoring explicit dump request\n", out_request->tid);
      return -1;
    }
  } else {
@@ -238,12 +237,12 @@ static void handle_request(int fd) {
    // See details in bionic/libc/linker/debugger.c, in function
    // debugger_signal_handler().
    if (ptrace(PTRACE_ATTACH, request.tid, 0, 0)) {
      LOG("ptrace attach failed: %s\n", strerror(errno));
      LOG_ERROR("ptrace attach failed: %s\n", strerror(errno));
    } else {
      bool detach_failed = false;
      bool attach_gdb = should_attach_gdb(&request);
      if (TEMP_FAILURE_RETRY(write(fd, "\0", 1)) != 1) {
        LOG("failed responding to client: %s\n", strerror(errno));
        LOG_ERROR("failed responding to client: %s\n", strerror(errno));
      } else {
        char* tombstone_path = NULL;

@@ -275,7 +274,7 @@ static void handle_request(int fd) {
                XLOG("stopped -- continuing\n");
                status = ptrace(PTRACE_CONT, request.tid, 0, 0);
                if (status) {
                  LOG("ptrace continue failed: %s\n", strerror(errno));
                  LOG_ERROR("ptrace continue failed: %s\n", strerror(errno));
                }
                continue; // loop again
              }
@@ -307,7 +306,7 @@ static void handle_request(int fd) {

            default:
              XLOG("stopped -- unexpected signal\n");
              LOG("process stopped due to unexpected signal %d\n", signal);
              LOG_ERROR("process stopped due to unexpected signal %d\n", signal);
              break;
          }
          break;
@@ -330,7 +329,7 @@ static void handle_request(int fd) {

        // detach so we can attach gdbserver
        if (ptrace(PTRACE_DETACH, request.tid, 0, 0)) {
          LOG("ptrace detach from %d failed: %s\n", request.tid, strerror(errno));
          LOG_ERROR("ptrace detach from %d failed: %s\n", request.tid, strerror(errno));
          detach_failed = true;
        }

@@ -342,7 +341,7 @@ static void handle_request(int fd) {
      } else {
        // just detach
        if (ptrace(PTRACE_DETACH, request.tid, 0, 0)) {
          LOG("ptrace detach from %d failed: %s\n", request.tid, strerror(errno));
          LOG_ERROR("ptrace detach from %d failed: %s\n", request.tid, strerror(errno));
          detach_failed = true;
        }
      }
@@ -354,7 +353,7 @@ static void handle_request(int fd) {
      // actual parent won't receive a death notification via wait(2).  At this point
      // there's not much we can do about that.
      if (detach_failed) {
        LOG("debuggerd committing suicide to free the zombie!\n");
        LOG_ERROR("debuggerd committing suicide to free the zombie!\n");
        kill(getpid(), SIGKILL);
      }
    }
@@ -400,7 +399,7 @@ static int do_server() {
    return 1;
  fcntl(s, F_SETFD, FD_CLOEXEC);

  LOG("debuggerd: " __DATE__ " " __TIME__ "\n");
  LOG_ERROR("debuggerd: " __DATE__ " " __TIME__ "\n");

  for (;;) {
    sockaddr addr;
Loading