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

Commit 7390d96f authored by Josh Gao's avatar Josh Gao Committed by Gerrit Code Review
Browse files

Merge "crash_dump: fetch process/thread names before dropping privileges."

parents 54e7365f 57f58f8e
Loading
Loading
Loading
Loading
+24 −5
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@
#include <unistd.h>

#include <limits>
#include <map>
#include <memory>
#include <set>
#include <vector>
@@ -36,6 +37,7 @@
#include <android-base/parseint.h>
#include <android-base/properties.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
#include <android-base/unique_fd.h>
#include <cutils/sockets.h>
#include <log/log.h>
@@ -52,7 +54,21 @@
#include "debuggerd/util.h"

using android::base::unique_fd;
using android::base::ReadFileToString;
using android::base::StringPrintf;
using android::base::Trim;

static std::string get_process_name(pid_t pid) {
  std::string result = "<unknown>";
  ReadFileToString(StringPrintf("/proc/%d/cmdline", pid), &result);
  return result;
}

static std::string get_thread_name(pid_t tid) {
  std::string result = "<unknown>";
  ReadFileToString(StringPrintf("/proc/%d/comm", tid), &result);
  return Trim(result);
}

static bool pid_contains_tid(int pid_proc_fd, pid_t tid) {
  struct stat st;
@@ -253,7 +269,7 @@ int main(int argc, char** argv) {
  }

  // Seize the siblings.
  std::set<pid_t> attached_siblings;
  std::map<pid_t, std::string> threads;
  {
    std::set<pid_t> siblings;
    if (!android::procinfo::GetProcessTids(target, &siblings)) {
@@ -269,12 +285,12 @@ int main(int argc, char** argv) {
      if (!ptrace_seize_thread(target_proc_fd, sibling_tid, &attach_error)) {
        LOG(WARNING) << attach_error;
      } else {
        attached_siblings.insert(sibling_tid);
        threads.emplace(sibling_tid, get_thread_name(sibling_tid));
      }
    }
  }

  // Collect the backtrace map and open files, while the process still has PR_GET_DUMPABLE=1
  // Collect the backtrace map, open files, and process/thread names, while we still have caps.
  std::unique_ptr<BacktraceMap> backtrace_map(BacktraceMap::Create(main_tid));
  if (!backtrace_map) {
    LOG(FATAL) << "failed to create backtrace map";
@@ -284,6 +300,9 @@ int main(int argc, char** argv) {
  OpenFilesList open_files;
  populate_open_files_list(target, &open_files);

  std::string process_name = get_process_name(main_tid);
  threads.emplace(main_tid, get_thread_name(main_tid));

  // Drop our capabilities now that we've attached to the threads we care about.
  drop_capabilities();

@@ -341,10 +360,10 @@ int main(int argc, char** argv) {

  std::string amfd_data;
  if (backtrace) {
    dump_backtrace(output_fd.get(), backtrace_map.get(), target, main_tid, attached_siblings, 0);
    dump_backtrace(output_fd.get(), backtrace_map.get(), target, main_tid, process_name, threads, 0);
  } else {
    engrave_tombstone(output_fd.get(), backtrace_map.get(), &open_files, target, main_tid,
                      &attached_siblings, abort_address, fatal_signal ? &amfd_data : nullptr);
                      process_name, threads, abort_address, fatal_signal ? &amfd_data : nullptr);
  }

  // We don't actually need to PTRACE_DETACH, as long as our tracees aren't in
+24 −42
Original line number Diff line number Diff line
@@ -38,18 +38,7 @@

#include "utility.h"

static void dump_process_header(log_t* log, pid_t pid) {
  char path[PATH_MAX];
  char procnamebuf[1024];
  char* procname = NULL;
  FILE* fp;

  snprintf(path, sizeof(path), "/proc/%d/cmdline", pid);
  if ((fp = fopen(path, "r"))) {
    procname = fgets(procnamebuf, sizeof(procnamebuf), fp);
    fclose(fp);
  }

static void dump_process_header(log_t* log, pid_t pid, const char* process_name) {
  time_t t = time(NULL);
  struct tm tm;
  localtime_r(&t, &tm);
@@ -57,8 +46,8 @@ static void dump_process_header(log_t* log, pid_t pid) {
  strftime(timestr, sizeof(timestr), "%F %T", &tm);
  _LOG(log, logtype::BACKTRACE, "\n\n----- pid %d at %s -----\n", pid, timestr);

  if (procname) {
    _LOG(log, logtype::BACKTRACE, "Cmd line: %s\n", procname);
  if (process_name) {
    _LOG(log, logtype::BACKTRACE, "Cmd line: %s\n", process_name);
  }
  _LOG(log, logtype::BACKTRACE, "ABI: '%s'\n", ABI_STRING);
}
@@ -67,28 +56,13 @@ static void dump_process_footer(log_t* log, pid_t pid) {
  _LOG(log, logtype::BACKTRACE, "\n----- end %d -----\n", pid);
}

static void log_thread_name(log_t* log, pid_t tid) {
  FILE* fp;
  char buf[1024];
  char path[PATH_MAX];
  char* threadname = NULL;

  snprintf(path, sizeof(path), "/proc/%d/comm", tid);
  if ((fp = fopen(path, "r"))) {
    threadname = fgets(buf, sizeof(buf), fp);
    fclose(fp);
    if (threadname) {
      size_t len = strlen(threadname);
      if (len && threadname[len - 1] == '\n') {
          threadname[len - 1] = '\0';
      }
    }
  }
  _LOG(log, logtype::BACKTRACE, "\n\"%s\" sysTid=%d\n", threadname ? threadname : "<unknown>", tid);
static void log_thread_name(log_t* log, pid_t tid, const char* thread_name) {
  _LOG(log, logtype::BACKTRACE, "\n\"%s\" sysTid=%d\n", thread_name, tid);
}

static void dump_thread(log_t* log, BacktraceMap* map, pid_t pid, pid_t tid) {
  log_thread_name(log, tid);
static void dump_thread(log_t* log, BacktraceMap* map, pid_t pid, pid_t tid,
                        const std::string& thread_name) {
  log_thread_name(log, tid, thread_name.c_str());

  std::unique_ptr<Backtrace> backtrace(Backtrace::Create(pid, tid, map));
  if (backtrace->Unwind(0)) {
@@ -99,17 +73,21 @@ static void dump_thread(log_t* log, BacktraceMap* map, pid_t pid, pid_t tid) {
  }
}

void dump_backtrace(int fd, BacktraceMap* map, pid_t pid, pid_t tid,
                    const std::set<pid_t>& siblings, std::string* amfd_data) {
void dump_backtrace(int fd, BacktraceMap* map, pid_t pid, pid_t tid, const std::string& process_name,
                    const std::map<pid_t, std::string>& threads, std::string* amfd_data) {
  log_t log;
  log.tfd = fd;
  log.amfd_data = amfd_data;

  dump_process_header(&log, pid);
  dump_thread(&log, map, pid, tid);
  dump_process_header(&log, pid, process_name.c_str());
  dump_thread(&log, map, pid, tid, threads.find(tid)->second.c_str());

  for (pid_t sibling : siblings) {
    dump_thread(&log, map, pid, sibling);
  for (const auto& it : threads) {
    pid_t thread_tid = it.first;
    const std::string& thread_name = it.second;
    if (thread_tid != tid) {
      dump_thread(&log, map, pid, thread_tid, thread_name.c_str());
    }
  }

  dump_process_footer(&log, pid);
@@ -123,7 +101,9 @@ void dump_backtrace_ucontext(int output_fd, ucontext_t* ucontext) {
  log.tfd = output_fd;
  log.amfd_data = nullptr;

  log_thread_name(&log, tid);
  char thread_name[16];
  read_with_default("/proc/self/comm", thread_name, sizeof(thread_name), "<unknown>");
  log_thread_name(&log, tid, thread_name);

  std::unique_ptr<Backtrace> backtrace(Backtrace::Create(pid, tid));
  if (backtrace->Unwind(0, ucontext)) {
@@ -139,7 +119,9 @@ void dump_backtrace_header(int output_fd) {
  log.tfd = output_fd;
  log.amfd_data = nullptr;

  dump_process_header(&log, getpid());
  char process_name[128];
  read_with_default("/proc/self/cmdline", process_name, sizeof(process_name), "<unknown>");
  dump_process_header(&log, getpid(), process_name);
}

void dump_backtrace_footer(int output_fd) {
+3 −3
Original line number Diff line number Diff line
@@ -20,7 +20,7 @@
#include <sys/types.h>
#include <sys/ucontext.h>

#include <set>
#include <map>
#include <string>

#include "utility.h"
@@ -30,8 +30,8 @@ class BacktraceMap;

// Dumps a backtrace using a format similar to what Dalvik uses so that the result
// can be intermixed in a bug report.
void dump_backtrace(int fd, BacktraceMap* map, pid_t pid, pid_t tid,
                    const std::set<pid_t>& siblings, std::string* amfd_data);
void dump_backtrace(int fd, BacktraceMap* map, pid_t pid, pid_t tid, const std::string& process_name,
                    const std::map<pid_t, std::string>& threads, std::string* amfd_data);

/* Dumps the backtrace in the backtrace data structure to the log. */
void dump_backtrace_to_log(Backtrace* backtrace, log_t* log, const char* prefix);
+5 −4
Original line number Diff line number Diff line
@@ -20,7 +20,8 @@
#include <stdbool.h>
#include <stddef.h>
#include <sys/types.h>
#include <set>

#include <map>
#include <string>

#include "open_files_list.h"
@@ -34,9 +35,9 @@ class BacktraceMap;
int open_tombstone(std::string* path);

/* Creates a tombstone file and writes the crash dump to it. */
void engrave_tombstone(int tombstone_fd, BacktraceMap* map,
                       const OpenFilesList* open_files, pid_t pid, pid_t tid,
                       const std::set<pid_t>* siblings, uintptr_t abort_msg_address,
void engrave_tombstone(int tombstone_fd, BacktraceMap* map, const OpenFilesList* open_files,
                       pid_t pid, pid_t tid, const std::string& process_name,
                       const std::map<pid_t, std::string>& threads, uintptr_t abort_msg_address,
                       std::string* amfd_data);

void engrave_tombstone_ucontext(int tombstone_fd, uintptr_t abort_msg_address, siginfo_t* siginfo,
+2 −0
Original line number Diff line number Diff line
@@ -83,4 +83,6 @@ bool wait_for_signal(pid_t tid, siginfo_t* siginfo);

void dump_memory(log_t* log, Backtrace* backtrace, uintptr_t addr, const char* fmt, ...);

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

#endif // _DEBUGGERD_UTILITY_H
Loading