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

Commit fe90276a authored by Josh Gao's avatar Josh Gao
Browse files

crash_dump: use /proc/<pid> fd to check tid process membership.

Bug: http://b/34759490
Test: /data/nativetest/debuggerd_test/debuggerd_test32
Test: debuggerd -b `pidof system_server`
Test: debuggerd -b `pidof zygote`
Change-Id: I627692b44977335a9568cd765ad28205f0a61327
parent 7ae426c7
Loading
Loading
Loading
Loading
+12 −11
Original line number Original line Diff line number Diff line
@@ -51,24 +51,25 @@
using android::base::unique_fd;
using android::base::unique_fd;
using android::base::StringPrintf;
using android::base::StringPrintf;


static bool pid_contains_tid(pid_t pid, pid_t tid) {
static bool pid_contains_tid(int pid_proc_fd, pid_t tid) {
  std::string task_path = StringPrintf("/proc/%d/task/%d", pid, tid);
  struct stat st;
  return access(task_path.c_str(), F_OK) == 0;
  std::string task_path = StringPrintf("task/%d", tid);
  return fstatat(pid_proc_fd, task_path.c_str(), &st, 0) == 0;
}
}


// Attach to a thread, and verify that it's still a member of the given process
// Attach to a thread, and verify that it's still a member of the given process
static bool ptrace_seize_thread(pid_t pid, pid_t tid, std::string* error) {
static bool ptrace_seize_thread(int pid_proc_fd, pid_t tid, std::string* error) {
  if (ptrace(PTRACE_SEIZE, tid, 0, 0) != 0) {
  if (ptrace(PTRACE_SEIZE, tid, 0, 0) != 0) {
    *error = StringPrintf("failed to attach to thread %d: %s", tid, strerror(errno));
    *error = StringPrintf("failed to attach to thread %d: %s", tid, strerror(errno));
    return false;
    return false;
  }
  }


  // Make sure that the task we attached to is actually part of the pid we're dumping.
  // Make sure that the task we attached to is actually part of the pid we're dumping.
  if (!pid_contains_tid(pid, tid)) {
  if (!pid_contains_tid(pid_proc_fd, tid)) {
    if (ptrace(PTRACE_DETACH, tid, 0, 0) != 0) {
    if (ptrace(PTRACE_DETACH, tid, 0, 0) != 0) {
      PLOG(FATAL) << "failed to detach from thread " << tid;
      PLOG(FATAL) << "failed to detach from thread " << tid;
    }
    }
    *error = StringPrintf("thread %d is not in process %d", tid, pid);
    *error = StringPrintf("thread %d is not in process", tid);
    return false;
    return false;
  }
  }


@@ -263,7 +264,7 @@ int main(int argc, char** argv) {
  check_process(target_proc_fd, target);
  check_process(target_proc_fd, target);


  std::string attach_error;
  std::string attach_error;
  if (!ptrace_seize_thread(target, main_tid, &attach_error)) {
  if (!ptrace_seize_thread(target_proc_fd, main_tid, &attach_error)) {
    LOG(FATAL) << attach_error;
    LOG(FATAL) << attach_error;
  }
  }


@@ -304,6 +305,7 @@ int main(int argc, char** argv) {
  }
  }


  int signo = siginfo.si_signo;
  int signo = siginfo.si_signo;
  bool fatal_signal = signo != DEBUGGER_SIGNAL;
  bool backtrace = false;
  bool backtrace = false;
  uintptr_t abort_address = 0;
  uintptr_t abort_address = 0;


@@ -319,17 +321,16 @@ int main(int argc, char** argv) {


  // Now that we have the signal that kicked things off, attach all of the
  // Now that we have the signal that kicked things off, attach all of the
  // sibling threads, and then proceed.
  // sibling threads, and then proceed.
  bool fatal_signal = signo != DEBUGGER_SIGNAL;
  std::set<pid_t> siblings;
  std::set<pid_t> attached_siblings;
  std::set<pid_t> attached_siblings;
  if (fatal_signal || backtrace) {
  {
    std::set<pid_t> siblings;
    if (!android::procinfo::GetProcessTids(target, &siblings)) {
    if (!android::procinfo::GetProcessTids(target, &siblings)) {
      PLOG(FATAL) << "failed to get process siblings";
      PLOG(FATAL) << "failed to get process siblings";
    }
    }
    siblings.erase(main_tid);
    siblings.erase(main_tid);


    for (pid_t sibling_tid : siblings) {
    for (pid_t sibling_tid : siblings) {
      if (!ptrace_seize_thread(target, sibling_tid, &attach_error)) {
      if (!ptrace_seize_thread(target_proc_fd, sibling_tid, &attach_error)) {
        LOG(WARNING) << attach_error;
        LOG(WARNING) << attach_error;
      } else {
      } else {
        attached_siblings.insert(sibling_tid);
        attached_siblings.insert(sibling_tid);