summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosh Gao2017-05-30 17:47:05 -0500
committerJosh Gao2017-06-07 16:11:28 -0500
commit8a2a2d182a2ce14638142e78ea4308670984d2e0 (patch)
tree174d6c7ea5ea52c72829f662a2bb32b2d5ca2c51 /debuggerd/crash_dump.cpp
parent8bb039073fa97f380d03392002a3a5bc542f5ace (diff)
downloadplatform-system-core-8a2a2d182a2ce14638142e78ea4308670984d2e0.tar.gz
platform-system-core-8a2a2d182a2ce14638142e78ea4308670984d2e0.tar.xz
platform-system-core-8a2a2d182a2ce14638142e78ea4308670984d2e0.zip
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
Diffstat (limited to 'debuggerd/crash_dump.cpp')
-rw-r--r--debuggerd/crash_dump.cpp56
1 files changed, 30 insertions, 26 deletions
diff --git a/debuggerd/crash_dump.cpp b/debuggerd/crash_dump.cpp
index df7201df3..3ca9c9224 100644
--- a/debuggerd/crash_dump.cpp
+++ b/debuggerd/crash_dump.cpp
@@ -95,11 +95,6 @@ static bool ptrace_seize_thread(int pid_proc_fd, pid_t tid, std::string* error)
95 return false; 95 return false;
96 } 96 }
97 97
98 // Put the task into ptrace-stop state.
99 if (ptrace(PTRACE_INTERRUPT, tid, 0, 0) != 0) {
100 PLOG(FATAL) << "failed to interrupt thread " << tid;
101 }
102
103 return true; 98 return true;
104} 99}
105 100
@@ -284,36 +279,38 @@ int main(int argc, char** argv) {
284 // Die if we take too long. 279 // Die if we take too long.
285 alarm(2); 280 alarm(2);
286 281
282 std::string process_name = get_process_name(main_tid);
287 std::string attach_error; 283 std::string attach_error;
288 284
289 std::map<pid_t, std::string> threads; 285 std::map<pid_t, std::string> threads;
290 286
291 { 287 {
292 ATRACE_NAME("ptrace"); 288 ATRACE_NAME("ptrace_interrupt");
289
293 // Seize the main thread. 290 // Seize the main thread.
294 if (!ptrace_seize_thread(target_proc_fd, main_tid, &attach_error)) { 291 if (!ptrace_seize_thread(target_proc_fd, main_tid, &attach_error)) {
295 LOG(FATAL) << attach_error; 292 LOG(FATAL) << attach_error;
296 } 293 }
297 294
298 // Seize the siblings. 295 threads.emplace(main_tid, get_thread_name(main_tid));
299 { 296
300 std::set<pid_t> siblings; 297 // Seize its siblings.
301 if (!android::procinfo::GetProcessTids(target, &siblings)) { 298 std::set<pid_t> siblings;
302 PLOG(FATAL) << "failed to get process siblings"; 299 if (!android::procinfo::GetProcessTids(target, &siblings)) {
303 } 300 PLOG(FATAL) << "failed to get process siblings";
301 }
302
303 // but not the already attached main thread.
304 siblings.erase(main_tid);
305 // or the handler pseudothread.
306 siblings.erase(pseudothread_tid);
304 307
305 // but not the already attached main thread. 308 for (pid_t sibling_tid : siblings) {
306 siblings.erase(main_tid); 309 if (!ptrace_seize_thread(target_proc_fd, sibling_tid, &attach_error)) {
307 // or the handler pseudothread. 310 LOG(WARNING) << attach_error;
308 siblings.erase(pseudothread_tid); 311 continue;
309
310 for (pid_t sibling_tid : siblings) {
311 if (!ptrace_seize_thread(target_proc_fd, sibling_tid, &attach_error)) {
312 LOG(WARNING) << attach_error;
313 } else {
314 threads.emplace(sibling_tid, get_thread_name(sibling_tid));
315 }
316 } 312 }
313 threads.emplace(sibling_tid, get_thread_name(sibling_tid));
317 } 314 }
318 } 315 }
319 316
@@ -334,9 +331,6 @@ int main(int argc, char** argv) {
334 populate_open_files_list(target, &open_files); 331 populate_open_files_list(target, &open_files);
335 } 332 }
336 333
337 std::string process_name = get_process_name(main_tid);
338 threads.emplace(main_tid, get_thread_name(main_tid));
339
340 // Drop our capabilities now that we've attached to the threads we care about. 334 // Drop our capabilities now that we've attached to the threads we care about.
341 drop_capabilities(); 335 drop_capabilities();
342 336
@@ -347,6 +341,16 @@ int main(int argc, char** argv) {
347 tombstoned_connected = tombstoned_connect(target, &tombstoned_socket, &output_fd, dump_type_enum); 341 tombstoned_connected = tombstoned_connect(target, &tombstoned_socket, &output_fd, dump_type_enum);
348 } 342 }
349 343
344 // Pause the threads.
345 {
346 ATRACE_NAME("ptrace_interrupt");
347 for (const auto& [sibling_tid, _] : threads) {
348 if (ptrace(PTRACE_INTERRUPT, sibling_tid, 0, 0) != 0) {
349 PLOG(FATAL) << "failed to interrupt thread " << sibling_tid;
350 }
351 }
352 }
353
350 // Write a '\1' to stdout to tell the crashing process to resume. 354 // Write a '\1' to stdout to tell the crashing process to resume.
351 // It also restores the value of PR_SET_DUMPABLE at this point. 355 // It also restores the value of PR_SET_DUMPABLE at this point.
352 if (TEMP_FAILURE_RETRY(write(STDOUT_FILENO, "\1", 1)) == -1) { 356 if (TEMP_FAILURE_RETRY(write(STDOUT_FILENO, "\1", 1)) == -1) {