• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2016, The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <arpa/inet.h>
18 #include <dirent.h>
19 #include <fcntl.h>
20 #include <stdlib.h>
21 #include <sys/prctl.h>
22 #include <sys/ptrace.h>
23 #include <sys/types.h>
24 #include <sys/un.h>
25 #include <sys/wait.h>
26 #include <syscall.h>
27 #include <unistd.h>
28 
29 #include <limits>
30 #include <map>
31 #include <memory>
32 #include <set>
33 #include <vector>
34 
35 #include <android-base/file.h>
36 #include <android-base/logging.h>
37 #include <android-base/macros.h>
38 #include <android-base/parseint.h>
39 #include <android-base/properties.h>
40 #include <android-base/stringprintf.h>
41 #include <android-base/strings.h>
42 #include <android-base/unique_fd.h>
43 #include <bionic/reserved_signals.h>
44 #include <cutils/sockets.h>
45 #include <log/log.h>
46 #include <private/android_filesystem_config.h>
47 #include <procinfo/process.h>
48 
49 #define ATRACE_TAG ATRACE_TAG_BIONIC
50 #include <utils/Trace.h>
51 
52 #include <unwindstack/DexFiles.h>
53 #include <unwindstack/JitDebug.h>
54 #include <unwindstack/Maps.h>
55 #include <unwindstack/Memory.h>
56 #include <unwindstack/Regs.h>
57 #include <unwindstack/Unwinder.h>
58 
59 #include "libdebuggerd/backtrace.h"
60 #include "libdebuggerd/tombstone.h"
61 #include "libdebuggerd/utility.h"
62 
63 #include "debuggerd/handler.h"
64 #include "tombstoned/tombstoned.h"
65 
66 #include "protocol.h"
67 #include "util.h"
68 
69 using android::base::unique_fd;
70 using android::base::StringPrintf;
71 
pid_contains_tid(int pid_proc_fd,pid_t tid)72 static bool pid_contains_tid(int pid_proc_fd, pid_t tid) {
73   struct stat st;
74   std::string task_path = StringPrintf("task/%d", tid);
75   return fstatat(pid_proc_fd, task_path.c_str(), &st, 0) == 0;
76 }
77 
get_tracer(pid_t tracee)78 static pid_t get_tracer(pid_t tracee) {
79   // Check to see if the thread is being ptraced by another process.
80   android::procinfo::ProcessInfo process_info;
81   if (android::procinfo::GetProcessInfo(tracee, &process_info)) {
82     return process_info.tracer;
83   }
84   return -1;
85 }
86 
87 // Attach to a thread, and verify that it's still a member of the given process
ptrace_seize_thread(int pid_proc_fd,pid_t tid,std::string * error,int flags=0)88 static bool ptrace_seize_thread(int pid_proc_fd, pid_t tid, std::string* error, int flags = 0) {
89   if (ptrace(PTRACE_SEIZE, tid, 0, flags) != 0) {
90     if (errno == EPERM) {
91       pid_t tracer = get_tracer(tid);
92       if (tracer != -1) {
93         *error = StringPrintf("failed to attach to thread %d, already traced by %d (%s)", tid,
94                               tracer, get_process_name(tracer).c_str());
95         return false;
96       }
97     }
98 
99     *error = StringPrintf("failed to attach to thread %d: %s", tid, strerror(errno));
100     return false;
101   }
102 
103   // Make sure that the task we attached to is actually part of the pid we're dumping.
104   if (!pid_contains_tid(pid_proc_fd, tid)) {
105     if (ptrace(PTRACE_DETACH, tid, 0, 0) != 0) {
106       PLOG(WARNING) << "failed to detach from thread " << tid;
107     }
108     *error = StringPrintf("thread %d is not in process", tid);
109     return false;
110   }
111 
112   return true;
113 }
114 
wait_for_stop(pid_t tid,int * received_signal)115 static bool wait_for_stop(pid_t tid, int* received_signal) {
116   while (true) {
117     int status;
118     pid_t result = waitpid(tid, &status, __WALL);
119     if (result != tid) {
120       PLOG(ERROR) << "waitpid failed on " << tid << " while detaching";
121       return false;
122     }
123 
124     if (WIFSTOPPED(status)) {
125       if (status >> 16 == PTRACE_EVENT_STOP) {
126         *received_signal = 0;
127       } else {
128         *received_signal = WSTOPSIG(status);
129       }
130       return true;
131     }
132   }
133 }
134 
135 // Interrupt a process and wait for it to be interrupted.
ptrace_interrupt(pid_t tid,int * received_signal)136 static bool ptrace_interrupt(pid_t tid, int* received_signal) {
137   if (ptrace(PTRACE_INTERRUPT, tid, 0, 0) == 0) {
138     return wait_for_stop(tid, received_signal);
139   }
140 
141   PLOG(ERROR) << "failed to interrupt " << tid << " to detach";
142   return false;
143 }
144 
activity_manager_notify(pid_t pid,int signal,const std::string & amfd_data)145 static bool activity_manager_notify(pid_t pid, int signal, const std::string& amfd_data) {
146   ATRACE_CALL();
147   android::base::unique_fd amfd(socket_local_client(
148       "/data/system/ndebugsocket", ANDROID_SOCKET_NAMESPACE_FILESYSTEM, SOCK_STREAM));
149   if (amfd.get() == -1) {
150     PLOG(ERROR) << "unable to connect to activity manager";
151     return false;
152   }
153 
154   struct timeval tv = {
155     .tv_sec = 1,
156     .tv_usec = 0,
157   };
158   if (setsockopt(amfd.get(), SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)) == -1) {
159     PLOG(ERROR) << "failed to set send timeout on activity manager socket";
160     return false;
161   }
162   tv.tv_sec = 3;  // 3 seconds on handshake read
163   if (setsockopt(amfd.get(), SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) == -1) {
164     PLOG(ERROR) << "failed to set receive timeout on activity manager socket";
165     return false;
166   }
167 
168   // Activity Manager protocol: binary 32-bit network-byte-order ints for the
169   // pid and signal number, followed by the raw text of the dump, culminating
170   // in a zero byte that marks end-of-data.
171   uint32_t datum = htonl(pid);
172   if (!android::base::WriteFully(amfd, &datum, 4)) {
173     PLOG(ERROR) << "AM pid write failed";
174     return false;
175   }
176   datum = htonl(signal);
177   if (!android::base::WriteFully(amfd, &datum, 4)) {
178     PLOG(ERROR) << "AM signal write failed";
179     return false;
180   }
181   if (!android::base::WriteFully(amfd, amfd_data.c_str(), amfd_data.size() + 1)) {
182     PLOG(ERROR) << "AM data write failed";
183     return false;
184   }
185 
186   // 3 sec timeout reading the ack; we're fine if the read fails.
187   char ack;
188   android::base::ReadFully(amfd, &ack, 1);
189   return true;
190 }
191 
192 // Globals used by the abort handler.
193 static pid_t g_target_thread = -1;
194 static bool g_tombstoned_connected = false;
195 static unique_fd g_tombstoned_socket;
196 static unique_fd g_output_fd;
197 
DefuseSignalHandlers()198 static void DefuseSignalHandlers() {
199   // Don't try to dump ourselves.
200   struct sigaction action = {};
201   action.sa_handler = SIG_DFL;
202   debuggerd_register_handlers(&action);
203 
204   sigset_t mask;
205   sigemptyset(&mask);
206   if (sigprocmask(SIG_SETMASK, &mask, nullptr) != 0) {
207     PLOG(FATAL) << "failed to set signal mask";
208   }
209 }
210 
Initialize(char ** argv)211 static void Initialize(char** argv) {
212   android::base::InitLogging(argv);
213   android::base::SetAborter([](const char* abort_msg) {
214     // If we abort before we get an output fd, contact tombstoned to let any
215     // potential listeners know that we failed.
216     if (!g_tombstoned_connected) {
217       if (!tombstoned_connect(g_target_thread, &g_tombstoned_socket, &g_output_fd,
218                               kDebuggerdAnyIntercept)) {
219         // We failed to connect, not much we can do.
220         LOG(ERROR) << "failed to connected to tombstoned to report failure";
221         _exit(1);
222       }
223     }
224 
225     dprintf(g_output_fd.get(), "crash_dump failed to dump process");
226     if (g_target_thread != 1) {
227       dprintf(g_output_fd.get(), " %d: %s\n", g_target_thread, abort_msg);
228     } else {
229       dprintf(g_output_fd.get(), ": %s\n", abort_msg);
230     }
231 
232     _exit(1);
233   });
234 }
235 
ParseArgs(int argc,char ** argv,pid_t * pseudothread_tid,DebuggerdDumpType * dump_type)236 static void ParseArgs(int argc, char** argv, pid_t* pseudothread_tid, DebuggerdDumpType* dump_type) {
237   if (argc != 4) {
238     LOG(FATAL) << "wrong number of args: " << argc << " (expected 4)";
239   }
240 
241   if (!android::base::ParseInt(argv[1], &g_target_thread, 1, std::numeric_limits<pid_t>::max())) {
242     LOG(FATAL) << "invalid target tid: " << argv[1];
243   }
244 
245   if (!android::base::ParseInt(argv[2], pseudothread_tid, 1, std::numeric_limits<pid_t>::max())) {
246     LOG(FATAL) << "invalid pseudothread tid: " << argv[2];
247   }
248 
249   int dump_type_int;
250   if (!android::base::ParseInt(argv[3], &dump_type_int, 0, 1)) {
251     LOG(FATAL) << "invalid requested dump type: " << argv[3];
252   }
253   *dump_type = static_cast<DebuggerdDumpType>(dump_type_int);
254 }
255 
ReadCrashInfo(unique_fd & fd,siginfo_t * siginfo,std::unique_ptr<unwindstack::Regs> * regs,uintptr_t * abort_msg_address,uintptr_t * fdsan_table_address,uintptr_t * gwp_asan_state,uintptr_t * gwp_asan_metadata)256 static void ReadCrashInfo(unique_fd& fd, siginfo_t* siginfo,
257                           std::unique_ptr<unwindstack::Regs>* regs, uintptr_t* abort_msg_address,
258                           uintptr_t* fdsan_table_address, uintptr_t* gwp_asan_state,
259                           uintptr_t* gwp_asan_metadata) {
260   std::aligned_storage<sizeof(CrashInfo) + 1, alignof(CrashInfo)>::type buf;
261   CrashInfo* crash_info = reinterpret_cast<CrashInfo*>(&buf);
262   ssize_t rc = TEMP_FAILURE_RETRY(read(fd.get(), &buf, sizeof(buf)));
263   if (rc == -1) {
264     PLOG(FATAL) << "failed to read target ucontext";
265   } else {
266     ssize_t expected_size = 0;
267     switch (crash_info->header.version) {
268       case 1:
269         expected_size = sizeof(CrashInfoHeader) + sizeof(CrashInfoDataV1);
270         break;
271 
272       case 2:
273         expected_size = sizeof(CrashInfoHeader) + sizeof(CrashInfoDataV2);
274         break;
275 
276       case 3:
277         expected_size = sizeof(CrashInfoHeader) + sizeof(CrashInfoDataV3);
278         break;
279 
280       default:
281         LOG(FATAL) << "unexpected CrashInfo version: " << crash_info->header.version;
282         break;
283     };
284 
285     if (rc != expected_size) {
286       LOG(FATAL) << "read " << rc << " bytes when reading target crash information, expected "
287                  << expected_size;
288     }
289   }
290 
291   *fdsan_table_address = 0;
292   *gwp_asan_state = 0;
293   *gwp_asan_metadata = 0;
294   switch (crash_info->header.version) {
295     case 3:
296       *gwp_asan_state = crash_info->data.v3.gwp_asan_state;
297       *gwp_asan_metadata = crash_info->data.v3.gwp_asan_metadata;
298       FALLTHROUGH_INTENDED;
299     case 2:
300       *fdsan_table_address = crash_info->data.v2.fdsan_table_address;
301       FALLTHROUGH_INTENDED;
302     case 1:
303       *abort_msg_address = crash_info->data.v1.abort_msg_address;
304       *siginfo = crash_info->data.v1.siginfo;
305       regs->reset(unwindstack::Regs::CreateFromUcontext(unwindstack::Regs::CurrentArch(),
306                                                         &crash_info->data.v1.ucontext));
307       break;
308 
309     default:
310       __builtin_unreachable();
311   }
312 }
313 
314 // Wait for a process to clone and return the child's pid.
315 // Note: this leaves the parent in PTRACE_EVENT_STOP.
wait_for_clone(pid_t pid,bool resume_child)316 static pid_t wait_for_clone(pid_t pid, bool resume_child) {
317   int status;
318   pid_t result = TEMP_FAILURE_RETRY(waitpid(pid, &status, __WALL));
319   if (result == -1) {
320     PLOG(FATAL) << "failed to waitpid";
321   }
322 
323   if (WIFEXITED(status)) {
324     LOG(FATAL) << "traced process exited with status " << WEXITSTATUS(status);
325   } else if (WIFSIGNALED(status)) {
326     LOG(FATAL) << "traced process exited with signal " << WTERMSIG(status);
327   } else if (!WIFSTOPPED(status)) {
328     LOG(FATAL) << "process didn't stop? (status = " << status << ")";
329   }
330 
331   if (status >> 8 != (SIGTRAP | (PTRACE_EVENT_CLONE << 8))) {
332     LOG(FATAL) << "process didn't stop due to PTRACE_O_TRACECLONE (status = " << status << ")";
333   }
334 
335   pid_t child;
336   if (ptrace(PTRACE_GETEVENTMSG, pid, 0, &child) != 0) {
337     PLOG(FATAL) << "failed to get child pid via PTRACE_GETEVENTMSG";
338   }
339 
340   int stop_signal;
341   if (!wait_for_stop(child, &stop_signal)) {
342     PLOG(FATAL) << "failed to waitpid on child";
343   }
344 
345   CHECK_EQ(0, stop_signal);
346 
347   if (resume_child) {
348     if (ptrace(PTRACE_CONT, child, 0, 0) != 0) {
349       PLOG(FATAL) << "failed to resume child (pid = " << child << ")";
350     }
351   }
352 
353   return child;
354 }
355 
wait_for_vm_process(pid_t pseudothread_tid)356 static pid_t wait_for_vm_process(pid_t pseudothread_tid) {
357   // The pseudothread will double-fork, we want its grandchild.
358   pid_t intermediate = wait_for_clone(pseudothread_tid, true);
359   pid_t vm_pid = wait_for_clone(intermediate, false);
360   if (ptrace(PTRACE_DETACH, intermediate, 0, 0) != 0) {
361     PLOG(FATAL) << "failed to detach from intermediate vm process";
362   }
363 
364   return vm_pid;
365 }
366 
InstallSigPipeHandler()367 static void InstallSigPipeHandler() {
368   struct sigaction action = {};
369   action.sa_handler = SIG_IGN;
370   action.sa_flags = SA_RESTART;
371   sigaction(SIGPIPE, &action, nullptr);
372 }
373 
main(int argc,char ** argv)374 int main(int argc, char** argv) {
375   DefuseSignalHandlers();
376   InstallSigPipeHandler();
377 
378   // There appears to be a bug in the kernel where our death causes SIGHUP to
379   // be sent to our process group if we exit while it has stopped jobs (e.g.
380   // because of wait_for_gdb). Use setsid to create a new process group to
381   // avoid hitting this.
382   setsid();
383 
384   atrace_begin(ATRACE_TAG, "before reparent");
385   pid_t target_process = getppid();
386 
387   // Open /proc/`getppid()` before we daemonize.
388   std::string target_proc_path = "/proc/" + std::to_string(target_process);
389   int target_proc_fd = open(target_proc_path.c_str(), O_DIRECTORY | O_RDONLY);
390   if (target_proc_fd == -1) {
391     PLOG(FATAL) << "failed to open " << target_proc_path;
392   }
393 
394   // Make sure getppid() hasn't changed.
395   if (getppid() != target_process) {
396     LOG(FATAL) << "parent died";
397   }
398   atrace_end(ATRACE_TAG);
399 
400   // Reparent ourselves to init, so that the signal handler can waitpid on the
401   // original process to avoid leaving a zombie for non-fatal dumps.
402   // Move the input/output pipes off of stdout/stderr, out of paranoia.
403   unique_fd output_pipe(dup(STDOUT_FILENO));
404   unique_fd input_pipe(dup(STDIN_FILENO));
405 
406   unique_fd fork_exit_read, fork_exit_write;
407   if (!Pipe(&fork_exit_read, &fork_exit_write)) {
408     PLOG(FATAL) << "failed to create pipe";
409   }
410 
411   pid_t forkpid = fork();
412   if (forkpid == -1) {
413     PLOG(FATAL) << "fork failed";
414   } else if (forkpid == 0) {
415     fork_exit_read.reset();
416   } else {
417     // We need the pseudothread to live until we get around to verifying the vm pid against it.
418     // The last thing it does is block on a waitpid on us, so wait until our child tells us to die.
419     fork_exit_write.reset();
420     char buf;
421     TEMP_FAILURE_RETRY(read(fork_exit_read.get(), &buf, sizeof(buf)));
422     _exit(0);
423   }
424 
425   ATRACE_NAME("after reparent");
426   pid_t pseudothread_tid;
427   DebuggerdDumpType dump_type;
428   uintptr_t abort_msg_address = 0;
429   uintptr_t fdsan_table_address = 0;
430   uintptr_t gwp_asan_state = 0;
431   uintptr_t gwp_asan_metadata = 0;
432 
433   Initialize(argv);
434   ParseArgs(argc, argv, &pseudothread_tid, &dump_type);
435 
436   // Die if we take too long.
437   //
438   // Note: processes with many threads and minidebug-info can take a bit to
439   //       unwind, do not make this too small. b/62828735
440   alarm(30);
441 
442   // Get the process name (aka cmdline).
443   std::string process_name = get_process_name(g_target_thread);
444 
445   // Collect the list of open files.
446   OpenFilesList open_files;
447   {
448     ATRACE_NAME("open files");
449     populate_open_files_list(&open_files, g_target_thread);
450   }
451 
452   // In order to reduce the duration that we pause the process for, we ptrace
453   // the threads, fetch their registers and associated information, and then
454   // fork a separate process as a snapshot of the process's address space.
455   std::set<pid_t> threads;
456   if (!android::procinfo::GetProcessTids(g_target_thread, &threads)) {
457     PLOG(FATAL) << "failed to get process threads";
458   }
459 
460   std::map<pid_t, ThreadInfo> thread_info;
461   siginfo_t siginfo;
462   std::string error;
463 
464   {
465     ATRACE_NAME("ptrace");
466     for (pid_t thread : threads) {
467       // Trace the pseudothread separately, so we can use different options.
468       if (thread == pseudothread_tid) {
469         continue;
470       }
471 
472       if (!ptrace_seize_thread(target_proc_fd, thread, &error)) {
473         bool fatal = thread == g_target_thread;
474         LOG(fatal ? FATAL : WARNING) << error;
475       }
476 
477       ThreadInfo info;
478       info.pid = target_process;
479       info.tid = thread;
480       info.uid = getuid();
481       info.process_name = process_name;
482       info.thread_name = get_thread_name(thread);
483 
484       if (!ptrace_interrupt(thread, &info.signo)) {
485         PLOG(WARNING) << "failed to ptrace interrupt thread " << thread;
486         ptrace(PTRACE_DETACH, thread, 0, 0);
487         continue;
488       }
489 
490       if (thread == g_target_thread) {
491         // Read the thread's registers along with the rest of the crash info out of the pipe.
492         ReadCrashInfo(input_pipe, &siginfo, &info.registers, &abort_msg_address,
493                       &fdsan_table_address, &gwp_asan_state, &gwp_asan_metadata);
494         info.siginfo = &siginfo;
495         info.signo = info.siginfo->si_signo;
496       } else {
497         info.registers.reset(unwindstack::Regs::RemoteGet(thread));
498         if (!info.registers) {
499           PLOG(WARNING) << "failed to fetch registers for thread " << thread;
500           ptrace(PTRACE_DETACH, thread, 0, 0);
501           continue;
502         }
503       }
504 
505       thread_info[thread] = std::move(info);
506     }
507   }
508 
509   // Trace the pseudothread with PTRACE_O_TRACECLONE and tell it to fork.
510   if (!ptrace_seize_thread(target_proc_fd, pseudothread_tid, &error, PTRACE_O_TRACECLONE)) {
511     LOG(FATAL) << "failed to seize pseudothread: " << error;
512   }
513 
514   if (TEMP_FAILURE_RETRY(write(output_pipe.get(), "\1", 1)) != 1) {
515     PLOG(FATAL) << "failed to write to pseudothread";
516   }
517 
518   pid_t vm_pid = wait_for_vm_process(pseudothread_tid);
519   if (ptrace(PTRACE_DETACH, pseudothread_tid, 0, 0) != 0) {
520     PLOG(FATAL) << "failed to detach from pseudothread";
521   }
522 
523   // The pseudothread can die now.
524   fork_exit_write.reset();
525 
526   // Defer the message until later, for readability.
527   bool wait_for_gdb = android::base::GetBoolProperty("debug.debuggerd.wait_for_gdb", false);
528   if (siginfo.si_signo == BIONIC_SIGNAL_DEBUGGER) {
529     wait_for_gdb = false;
530   }
531 
532   // Detach from all of our attached threads before resuming.
533   for (const auto& [tid, thread] : thread_info) {
534     int resume_signal = thread.signo == BIONIC_SIGNAL_DEBUGGER ? 0 : thread.signo;
535     if (wait_for_gdb) {
536       resume_signal = 0;
537       if (tgkill(target_process, tid, SIGSTOP) != 0) {
538         PLOG(WARNING) << "failed to send SIGSTOP to " << tid;
539       }
540     }
541 
542     LOG(DEBUG) << "detaching from thread " << tid;
543     if (ptrace(PTRACE_DETACH, tid, 0, resume_signal) != 0) {
544       PLOG(ERROR) << "failed to detach from thread " << tid;
545     }
546   }
547 
548   // Drop our capabilities now that we've fetched all of the information we need.
549   drop_capabilities();
550 
551   {
552     ATRACE_NAME("tombstoned_connect");
553     LOG(INFO) << "obtaining output fd from tombstoned, type: " << dump_type;
554     g_tombstoned_connected =
555         tombstoned_connect(g_target_thread, &g_tombstoned_socket, &g_output_fd, dump_type);
556   }
557 
558   if (g_tombstoned_connected) {
559     if (TEMP_FAILURE_RETRY(dup2(g_output_fd.get(), STDOUT_FILENO)) == -1) {
560       PLOG(ERROR) << "failed to dup2 output fd (" << g_output_fd.get() << ") to STDOUT_FILENO";
561     }
562   } else {
563     unique_fd devnull(TEMP_FAILURE_RETRY(open("/dev/null", O_RDWR)));
564     TEMP_FAILURE_RETRY(dup2(devnull.get(), STDOUT_FILENO));
565     g_output_fd = std::move(devnull);
566   }
567 
568   LOG(INFO) << "performing dump of process " << target_process
569             << " (target tid = " << g_target_thread << ")";
570 
571   int signo = siginfo.si_signo;
572   bool fatal_signal = signo != BIONIC_SIGNAL_DEBUGGER;
573   bool backtrace = false;
574 
575   // si_value is special when used with BIONIC_SIGNAL_DEBUGGER.
576   //   0: dump tombstone
577   //   1: dump backtrace
578   if (!fatal_signal) {
579     int si_val = siginfo.si_value.sival_int;
580     if (si_val == 0) {
581       backtrace = false;
582     } else if (si_val == 1) {
583       backtrace = true;
584     } else {
585       LOG(WARNING) << "unknown si_value value " << si_val;
586     }
587   }
588 
589   // TODO: Use seccomp to lock ourselves down.
590   unwindstack::UnwinderFromPid unwinder(256, vm_pid);
591   if (!unwinder.Init(unwindstack::Regs::CurrentArch())) {
592     LOG(FATAL) << "Failed to init unwinder object.";
593   }
594 
595   std::string amfd_data;
596   if (backtrace) {
597     ATRACE_NAME("dump_backtrace");
598     dump_backtrace(std::move(g_output_fd), &unwinder, thread_info, g_target_thread);
599   } else {
600     {
601       ATRACE_NAME("fdsan table dump");
602       populate_fdsan_table(&open_files, unwinder.GetProcessMemory(), fdsan_table_address);
603     }
604 
605     {
606       ATRACE_NAME("engrave_tombstone");
607       engrave_tombstone(std::move(g_output_fd), &unwinder, thread_info, g_target_thread,
608                         abort_msg_address, &open_files, &amfd_data, gwp_asan_state,
609                         gwp_asan_metadata);
610     }
611   }
612 
613   if (fatal_signal) {
614     // Don't try to notify ActivityManager if it just crashed, or we might hang until timeout.
615     if (thread_info[target_process].thread_name != "system_server") {
616       activity_manager_notify(target_process, signo, amfd_data);
617     }
618   }
619 
620   if (wait_for_gdb) {
621     // Use ALOGI to line up with output from engrave_tombstone.
622     ALOGI(
623         "***********************************************************\n"
624         "* Process %d has been suspended while crashing.\n"
625         "* To attach gdbserver and start gdb, run this on the host:\n"
626         "*\n"
627         "*     gdbclient.py -p %d\n"
628         "*\n"
629         "***********************************************************",
630         target_process, target_process);
631   }
632 
633   // Close stdout before we notify tombstoned of completion.
634   close(STDOUT_FILENO);
635   if (g_tombstoned_connected && !tombstoned_notify_completion(g_tombstoned_socket.get())) {
636     LOG(ERROR) << "failed to notify tombstoned of completion";
637   }
638 
639   return 0;
640 }
641