summaryrefslogtreecommitdiff
path: root/debuggerd/crash_dump.cpp
diff options
context:
space:
mode:
authorJosh Gao <jmgao@google.com>2017-02-13 14:46:19 -0800
committerJosh Gao <jmgao@google.com>2017-02-14 21:19:38 -0800
commit2f11a25a48897efe35d065472f921759d5941eba (patch)
tree1574e011b4aaf69b8050c6224edbd76ce73597dc /debuggerd/crash_dump.cpp
parent1d26b40ed5b9a8739425c252603c529d9f8d63fb (diff)
debuggerd_handler: set PR_SET_DUMPABLE before running crash_dump.
Set and restore PR_SET_DUMPABLE when performing a dump, so that processes that have it implicitly cleared (e.g. services that acquire filesystem capabilities) still get crash dumps. Bug: http://b/35174939 Test: debuggerd -b `pidof surfaceflinger` Change-Id: Ife933c10086e546726dec12a7efa3f9cedfeea60
Diffstat (limited to 'debuggerd/crash_dump.cpp')
-rw-r--r--debuggerd/crash_dump.cpp80
1 files changed, 43 insertions, 37 deletions
diff --git a/debuggerd/crash_dump.cpp b/debuggerd/crash_dump.cpp
index 288935611..0ca90c3df 100644
--- a/debuggerd/crash_dump.cpp
+++ b/debuggerd/crash_dump.cpp
@@ -238,11 +238,12 @@ int main(int argc, char** argv) {
action.sa_handler = signal_handler;
debuggerd_register_handlers(&action);
- if (argc != 2) {
+ if (argc != 3) {
return 1;
}
pid_t main_tid;
+ pid_t pseudothread_tid;
if (target == 1) {
LOG(FATAL) << "target died before we could attach";
@@ -252,6 +253,10 @@ int main(int argc, char** argv) {
LOG(FATAL) << "invalid main tid: " << argv[1];
}
+ if (!android::base::ParseInt(argv[2], &pseudothread_tid, 1, std::numeric_limits<pid_t>::max())) {
+ LOG(FATAL) << "invalid pseudothread tid: " << argv[1];
+ }
+
android::procinfo::ProcessInfo target_info;
if (!android::procinfo::GetProcessInfo(main_tid, &target_info)) {
LOG(FATAL) << "failed to fetch process info for target " << main_tid;
@@ -284,16 +289,53 @@ int main(int argc, char** argv) {
check_process(target_proc_fd, target);
std::string attach_error;
+
+ // Seize the main thread.
if (!ptrace_seize_thread(target_proc_fd, main_tid, &attach_error)) {
LOG(FATAL) << attach_error;
}
+ // Seize the siblings.
+ std::set<pid_t> attached_siblings;
+ {
+ std::set<pid_t> siblings;
+ if (!android::procinfo::GetProcessTids(target, &siblings)) {
+ PLOG(FATAL) << "failed to get process siblings";
+ }
+
+ // but not the already attached main thread.
+ siblings.erase(main_tid);
+ // or the handler pseudothread.
+ siblings.erase(pseudothread_tid);
+
+ for (pid_t sibling_tid : siblings) {
+ if (!ptrace_seize_thread(target_proc_fd, sibling_tid, &attach_error)) {
+ LOG(WARNING) << attach_error;
+ } else {
+ attached_siblings.insert(sibling_tid);
+ }
+ }
+ }
+
+ // Collect the backtrace map and open files, while the process still has PR_GET_DUMPABLE=1
+ std::unique_ptr<BacktraceMap> backtrace_map(BacktraceMap::Create(main_tid));
+ if (!backtrace_map) {
+ LOG(FATAL) << "failed to create backtrace map";
+ }
+
+ // Collect the list of open files.
+ OpenFilesList open_files;
+ populate_open_files_list(target, &open_files);
+
+ // Drop our capabilities now that we've attached to the threads we care about.
+ drop_capabilities();
check_process(target_proc_fd, target);
LOG(INFO) << "obtaining output fd from tombstoned";
tombstoned_connected = tombstoned_connect(target, &tombstoned_socket, &output_fd);
// 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) {
PLOG(ERROR) << "failed to communicate to target process";
}
@@ -339,45 +381,9 @@ int main(int argc, char** argv) {
abort_address = reinterpret_cast<uintptr_t>(siginfo.si_value.sival_ptr);
}
- // Now that we have the signal that kicked things off, attach all of the
- // sibling threads, and then proceed.
- std::set<pid_t> attached_siblings;
- {
- std::set<pid_t> siblings;
- if (!android::procinfo::GetProcessTids(target, &siblings)) {
- PLOG(FATAL) << "failed to get process siblings";
- }
- siblings.erase(main_tid);
-
- for (pid_t sibling_tid : siblings) {
- if (!ptrace_seize_thread(target_proc_fd, sibling_tid, &attach_error)) {
- LOG(WARNING) << attach_error;
- } else {
- attached_siblings.insert(sibling_tid);
- }
- }
- }
-
- std::unique_ptr<BacktraceMap> backtrace_map(BacktraceMap::Create(main_tid));
- if (!backtrace_map) {
- LOG(FATAL) << "failed to create backtrace map";
- }
-
- // Collect the list of open files.
- OpenFilesList open_files;
- if (!backtrace) {
- populate_open_files_list(target, &open_files);
- }
-
- // Drop our capabilities now that we've attached to the threads we care about.
- drop_capabilities();
-
- check_process(target_proc_fd, target);
-
// TODO: Use seccomp to lock ourselves down.
std::string amfd_data;
-
if (backtrace) {
dump_backtrace(output_fd.get(), backtrace_map.get(), target, main_tid, attached_siblings, 0);
} else {