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

Commit 8a2a2d18 authored by Josh Gao's avatar Josh Gao
Browse files

crash_dump: defer pausing threads until we're ready.

Don't pause the threads we're going to dump until after we're about to
fetch their backtraces.

Bug: http://b/62112103
Test: debuggerd_test
Change-Id: Id7ab0464842b35f98f3b3ebc42fb76161d8afbd2
parent 8bb03907
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@ cc_defaults {
        "-Wno-nullability-completeness",
        "-Os",
    ],
    cpp_std: "experimental",

    local_include_dirs: ["include"],
}
+30 −26
Original line number Diff line number Diff line
@@ -95,11 +95,6 @@ static bool ptrace_seize_thread(int pid_proc_fd, pid_t tid, std::string* error)
    return false;
  }

  // Put the task into ptrace-stop state.
  if (ptrace(PTRACE_INTERRUPT, tid, 0, 0) != 0) {
    PLOG(FATAL) << "failed to interrupt thread " << tid;
  }

  return true;
}

@@ -284,19 +279,22 @@ int main(int argc, char** argv) {
  // Die if we take too long.
  alarm(2);

  std::string process_name = get_process_name(main_tid);
  std::string attach_error;

  std::map<pid_t, std::string> threads;

  {
    ATRACE_NAME("ptrace");
    ATRACE_NAME("ptrace_interrupt");

    // Seize the main thread.
    if (!ptrace_seize_thread(target_proc_fd, main_tid, &attach_error)) {
      LOG(FATAL) << attach_error;
    }

    // Seize the siblings.
    {
    threads.emplace(main_tid, get_thread_name(main_tid));

    // Seize its siblings.
    std::set<pid_t> siblings;
    if (!android::procinfo::GetProcessTids(target, &siblings)) {
      PLOG(FATAL) << "failed to get process siblings";
@@ -310,10 +308,9 @@ int main(int argc, char** argv) {
    for (pid_t sibling_tid : siblings) {
      if (!ptrace_seize_thread(target_proc_fd, sibling_tid, &attach_error)) {
        LOG(WARNING) << attach_error;
        } else {
          threads.emplace(sibling_tid, get_thread_name(sibling_tid));
        }
        continue;
      }
      threads.emplace(sibling_tid, get_thread_name(sibling_tid));
    }
  }

@@ -334,9 +331,6 @@ int main(int argc, char** argv) {
    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();

@@ -347,6 +341,16 @@ int main(int argc, char** argv) {
    tombstoned_connected = tombstoned_connect(target, &tombstoned_socket, &output_fd, dump_type_enum);
  }

  // Pause the threads.
  {
    ATRACE_NAME("ptrace_interrupt");
    for (const auto& [sibling_tid, _] : threads) {
      if (ptrace(PTRACE_INTERRUPT, sibling_tid, 0, 0) != 0) {
        PLOG(FATAL) << "failed to interrupt thread " << sibling_tid;
      }
    }
  }

  // Write a '\1' to stdout to tell the crashing process to resume.
  // It also restores the value of PR_SET_DUMPABLE at this point.
  if (TEMP_FAILURE_RETRY(write(STDOUT_FILENO, "\1", 1)) == -1) {