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

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

Merge "Modify debuggerd to cope with the abort message."

parents ad999a09 707b8bbe
Loading
Loading
Loading
Loading
+10 −4
Original line number Diff line number Diff line
@@ -52,6 +52,7 @@ typedef struct {
    debugger_action_t action;
    pid_t pid, tid;
    uid_t uid, gid;
    uintptr_t abort_msg_address;
} debugger_request_t;

static int
@@ -207,12 +208,15 @@ static int read_request(int fd, debugger_request_t* out_request) {
    }

    debugger_msg_t msg;
    memset(&msg, 0, sizeof(msg));
    status = TEMP_FAILURE_RETRY(read(fd, &msg, sizeof(msg)));
    if (status < 0) {
        LOG("read failure? %s\n", strerror(errno));
        return -1;
    }
    if (status != sizeof(msg)) {
    if (status == sizeof(debugger_msg_t)) {
        XLOG("crash request of size %d abort_msg_address=%#08x\n", status, msg.abort_msg_address);
    } else {
        LOG("invalid crash request of size %d\n", status);
        return -1;
    }
@@ -222,6 +226,7 @@ static int read_request(int fd, debugger_request_t* out_request) {
    out_request->pid = cr.pid;
    out_request->uid = cr.uid;
    out_request->gid = cr.gid;
    out_request->abort_msg_address = msg.abort_msg_address;

    if (msg.action == DEBUGGER_ACTION_CRASH) {
        /* Ensure that the tid reported by the crashing process is valid. */
@@ -265,6 +270,7 @@ static void handle_request(int fd) {
    XLOG("handle_request(%d)\n", fd);

    debugger_request_t request;
    memset(&request, 0, sizeof(request));
    int status = read_request(fd, &request);
    if (!status) {
        XLOG("BOOM: pid=%d uid=%d gid=%d tid=%d\n",
@@ -308,7 +314,7 @@ static void handle_request(int fd) {
                        if (request.action == DEBUGGER_ACTION_DUMP_TOMBSTONE) {
                            XLOG("stopped -- dumping to tombstone\n");
                            tombstone_path = engrave_tombstone(request.pid, request.tid,
                                    signal, true, true, &detach_failed,
                                    signal, request.abort_msg_address, true, true, &detach_failed,
                                    &total_sleep_time_usec);
                        } else if (request.action == DEBUGGER_ACTION_DUMP_BACKTRACE) {
                            XLOG("stopped -- dumping to fd\n");
@@ -345,8 +351,8 @@ static void handle_request(int fd) {
                        /* don't dump sibling threads when attaching to GDB because it
                         * makes the process less reliable, apparently... */
                        tombstone_path = engrave_tombstone(request.pid, request.tid,
                                signal, !attach_gdb, false, &detach_failed,
                                &total_sleep_time_usec);
                                signal, request.abort_msg_address, !attach_gdb, false,
                                &detach_failed, &total_sleep_time_usec);
                        break;
                    }

+42 −6
Original line number Diff line number Diff line
@@ -616,10 +616,45 @@ static void dump_logs(log_t* log, pid_t pid, bool tailOnly)
    dump_log_file(log, pid, "/dev/log/main", tailOnly);
}

static void dump_abort_message(log_t* log, pid_t tid, uintptr_t address) {
  if (address == 0) {
    return;
  }

  address += sizeof(size_t); // Skip the buffer length.

  char msg[512];
  memset(msg, 0, sizeof(msg));
  char* p = &msg[0];
  while (p < &msg[sizeof(msg)]) {
    uint32_t data;
    if (!try_get_word_ptrace(tid, address, &data)) {
      break;
    }
    address += sizeof(uint32_t);

    if ((*p++ = (data >>  0) & 0xff) == 0) {
      break;
    }
    if ((*p++ = (data >>  8) & 0xff) == 0) {
      break;
    }
    if ((*p++ = (data >> 16) & 0xff) == 0) {
      break;
    }
    if ((*p++ = (data >> 24) & 0xff) == 0) {
      break;
    }
  }
  msg[sizeof(msg) - 1] = '\0';

  _LOG(log, false, "Abort message: '%s'\n", msg);
}

/*
 * Dumps all information about the specified pid to the tombstone.
 */
static bool dump_crash(log_t* log, pid_t pid, pid_t tid, int signal,
static bool dump_crash(log_t* log, pid_t pid, pid_t tid, int signal, uintptr_t abort_msg_address,
                       bool dump_sibling_threads, int* total_sleep_time_usec)
{
    /* don't copy log messages to tombstone unless this is a dev device */
@@ -635,6 +670,7 @@ static bool dump_crash(log_t* log, pid_t pid, pid_t tid, int signal,
    if (signal) {
        dump_fault_addr(log, tid, signal);
    }
    dump_abort_message(log, tid, abort_msg_address);

    ptrace_context_t* context = load_ptrace_context(tid);
    dump_thread(context, log, tid, true, total_sleep_time_usec);
@@ -712,7 +748,7 @@ static char* find_and_open_tombstone(int* fd)
    return strdup(path);
}

char* engrave_tombstone(pid_t pid, pid_t tid, int signal,
char* engrave_tombstone(pid_t pid, pid_t tid, int signal, uintptr_t abort_msg_address,
        bool dump_sibling_threads, bool quiet, bool* detach_failed,
        int* total_sleep_time_usec) {
    mkdir(TOMBSTONE_DIR, 0755);
@@ -733,7 +769,7 @@ char* engrave_tombstone(pid_t pid, pid_t tid, int signal,
    log_t log;
    log.tfd = fd;
    log.quiet = quiet;
    *detach_failed = dump_crash(&log, pid, tid, signal, dump_sibling_threads,
    *detach_failed = dump_crash(&log, pid, tid, signal, abort_msg_address, dump_sibling_threads,
            total_sleep_time_usec);

    close(fd);
+1 −1
Original line number Diff line number Diff line
@@ -25,7 +25,7 @@

/* Creates a tombstone file and writes the crash dump to it.
 * Returns the path of the tombstone, which must be freed using free(). */
char* engrave_tombstone(pid_t pid, pid_t tid, int signal,
char* engrave_tombstone(pid_t pid, pid_t tid, int signal, uintptr_t abort_msg_address,
        bool dump_sibling_threads, bool quiet, bool* detach_failed, int* total_sleep_time_usec);

#endif // _DEBUGGERD_TOMBSTONE_H
+1 −1
Original line number Diff line number Diff line
@@ -34,10 +34,10 @@ typedef enum {
    DEBUGGER_ACTION_DUMP_BACKTRACE,
} debugger_action_t;

/* message sent over the socket */
typedef struct {
    debugger_action_t action;
    pid_t tid;
    uintptr_t abort_msg_address;
} debugger_msg_t;

/* Dumps a process backtrace, registers, and stack to a tombstone file (requires root).