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