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

Commit e3c2e761 authored by Elliott Hughes's avatar Elliott Hughes Committed by Android Git Automerger
Browse files

am 46a97883: Merge "Changing how debuggerd filters log messages to different locations."

* commit '46a97883':
  Changing how debuggerd filters log messages to different locations.
parents 6c65cd5d 46a97883
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