1/*
2 * Copyright (C) 2012 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 <stddef.h>
18#include <stdbool.h>
19#include <stdlib.h>
20#include <signal.h>
21#include <string.h>
22#include <stdio.h>
23#include <fcntl.h>
24#include <errno.h>
25#include <dirent.h>
26#include <time.h>
27#include <sys/ptrace.h>
28#include <sys/stat.h>
29
30#include <private/android_filesystem_config.h>
31
32#include <cutils/logger.h>
33#include <cutils/properties.h>
34
35#include <corkscrew/demangle.h>
36#include <corkscrew/backtrace.h>
37
38#include <sys/socket.h>
39#include <linux/un.h>
40
41#include <selinux/android.h>
42
43#include "machine.h"
44#include "tombstone.h"
45#include "utility.h"
46
47#define STACK_DEPTH 32
48#define STACK_WORDS 16
49
50#define MAX_TOMBSTONES  10
51#define TOMBSTONE_DIR   "/data/tombstones"
52
53/* Must match the path defined in NativeCrashListener.java */
54#define NCRASH_SOCKET_PATH "/data/system/ndebugsocket"
55
56#define typecheck(x,y) {    \
57    typeof(x) __dummy1;     \
58    typeof(y) __dummy2;     \
59    (void)(&__dummy1 == &__dummy2); }
60
61
62static bool signal_has_address(int sig) {
63    switch (sig) {
64        case SIGILL:
65        case SIGFPE:
66        case SIGSEGV:
67        case SIGBUS:
68            return true;
69        default:
70            return false;
71    }
72}
73
74static const char *get_signame(int sig)
75{
76    switch(sig) {
77    case SIGILL:     return "SIGILL";
78    case SIGABRT:    return "SIGABRT";
79    case SIGBUS:     return "SIGBUS";
80    case SIGFPE:     return "SIGFPE";
81    case SIGSEGV:    return "SIGSEGV";
82    case SIGPIPE:    return "SIGPIPE";
83#ifdef SIGSTKFLT
84    case SIGSTKFLT:  return "SIGSTKFLT";
85#endif
86    case SIGSTOP:    return "SIGSTOP";
87    default:         return "?";
88    }
89}
90
91static const char *get_sigcode(int signo, int code)
92{
93    // Try the signal-specific codes...
94    switch (signo) {
95    case SIGILL:
96        switch (code) {
97        case ILL_ILLOPC: return "ILL_ILLOPC";
98        case ILL_ILLOPN: return "ILL_ILLOPN";
99        case ILL_ILLADR: return "ILL_ILLADR";
100        case ILL_ILLTRP: return "ILL_ILLTRP";
101        case ILL_PRVOPC: return "ILL_PRVOPC";
102        case ILL_PRVREG: return "ILL_PRVREG";
103        case ILL_COPROC: return "ILL_COPROC";
104        case ILL_BADSTK: return "ILL_BADSTK";
105        }
106        break;
107    case SIGBUS:
108        switch (code) {
109        case BUS_ADRALN: return "BUS_ADRALN";
110        case BUS_ADRERR: return "BUS_ADRERR";
111        case BUS_OBJERR: return "BUS_OBJERR";
112        }
113        break;
114    case SIGFPE:
115        switch (code) {
116        case FPE_INTDIV: return "FPE_INTDIV";
117        case FPE_INTOVF: return "FPE_INTOVF";
118        case FPE_FLTDIV: return "FPE_FLTDIV";
119        case FPE_FLTOVF: return "FPE_FLTOVF";
120        case FPE_FLTUND: return "FPE_FLTUND";
121        case FPE_FLTRES: return "FPE_FLTRES";
122        case FPE_FLTINV: return "FPE_FLTINV";
123        case FPE_FLTSUB: return "FPE_FLTSUB";
124        }
125        break;
126    case SIGSEGV:
127        switch (code) {
128        case SEGV_MAPERR: return "SEGV_MAPERR";
129        case SEGV_ACCERR: return "SEGV_ACCERR";
130        }
131        break;
132    case SIGTRAP:
133        switch (code) {
134        case TRAP_BRKPT: return "TRAP_BRKPT";
135        case TRAP_TRACE: return "TRAP_TRACE";
136        }
137        break;
138    }
139    // Then the other codes...
140    switch (code) {
141    case SI_USER:    return "SI_USER";
142#if defined(SI_KERNEL)
143    case SI_KERNEL:  return "SI_KERNEL";
144#endif
145    case SI_QUEUE:   return "SI_QUEUE";
146    case SI_TIMER:   return "SI_TIMER";
147    case SI_MESGQ:   return "SI_MESGQ";
148    case SI_ASYNCIO: return "SI_ASYNCIO";
149#if defined(SI_SIGIO)
150    case SI_SIGIO:   return "SI_SIGIO";
151#endif
152#if defined(SI_TKILL)
153    case SI_TKILL:   return "SI_TKILL";
154#endif
155    }
156    // Then give up...
157    return "?";
158}
159
160static void dump_revision_info(log_t* log)
161{
162    char revision[PROPERTY_VALUE_MAX];
163
164    property_get("ro.revision", revision, "unknown");
165
166    _LOG(log, SCOPE_AT_FAULT, "Revision: '%s'\n", revision);
167}
168
169static void dump_build_info(log_t* log)
170{
171    char fingerprint[PROPERTY_VALUE_MAX];
172
173    property_get("ro.build.fingerprint", fingerprint, "unknown");
174
175    _LOG(log, SCOPE_AT_FAULT, "Build fingerprint: '%s'\n", fingerprint);
176}
177
178static void dump_fault_addr(log_t* log, pid_t tid, int sig)
179{
180    siginfo_t si;
181
182    memset(&si, 0, sizeof(si));
183    if(ptrace(PTRACE_GETSIGINFO, tid, 0, &si)){
184        _LOG(log, SCOPE_AT_FAULT, "cannot get siginfo: %s\n", strerror(errno));
185    } else if (signal_has_address(sig)) {
186        _LOG(log, SCOPE_AT_FAULT, "signal %d (%s), code %d (%s), fault addr %08x\n",
187             sig, get_signame(sig),
188             si.si_code, get_sigcode(sig, si.si_code),
189             (uintptr_t) si.si_addr);
190    } else {
191        _LOG(log, SCOPE_AT_FAULT, "signal %d (%s), code %d (%s), fault addr --------\n",
192             sig, get_signame(sig), si.si_code, get_sigcode(sig, si.si_code));
193    }
194}
195
196static void dump_thread_info(log_t* log, pid_t pid, pid_t tid, bool at_fault) {
197    char path[64];
198    char threadnamebuf[1024];
199    char* threadname = NULL;
200    FILE *fp;
201
202    snprintf(path, sizeof(path), "/proc/%d/comm", tid);
203    if ((fp = fopen(path, "r"))) {
204        threadname = fgets(threadnamebuf, sizeof(threadnamebuf), fp);
205        fclose(fp);
206        if (threadname) {
207            size_t len = strlen(threadname);
208            if (len && threadname[len - 1] == '\n') {
209                threadname[len - 1] = '\0';
210            }
211        }
212    }
213
214    if (at_fault) {
215        char procnamebuf[1024];
216        char* procname = NULL;
217
218        snprintf(path, sizeof(path), "/proc/%d/cmdline", pid);
219        if ((fp = fopen(path, "r"))) {
220            procname = fgets(procnamebuf, sizeof(procnamebuf), fp);
221            fclose(fp);
222        }
223
224        _LOG(log, SCOPE_AT_FAULT, "pid: %d, tid: %d, name: %s  >>> %s <<<\n", pid, tid,
225                threadname ? threadname : "UNKNOWN",
226                procname ? procname : "UNKNOWN");
227    } else {
228        _LOG(log, 0, "pid: %d, tid: %d, name: %s\n",
229                pid, tid, threadname ? threadname : "UNKNOWN");
230    }
231}
232
233static void dump_backtrace(const ptrace_context_t* context __attribute((unused)),
234        log_t* log, pid_t tid __attribute((unused)), bool at_fault,
235        const backtrace_frame_t* backtrace, size_t frames) {
236    int scopeFlags = at_fault ? SCOPE_AT_FAULT : 0;
237    _LOG(log, scopeFlags, "\nbacktrace:\n");
238
239    backtrace_symbol_t backtrace_symbols[STACK_DEPTH];
240    get_backtrace_symbols_ptrace(context, backtrace, frames, backtrace_symbols);
241    for (size_t i = 0; i < frames; i++) {
242        char line[MAX_BACKTRACE_LINE_LENGTH];
243        format_backtrace_line(i, &backtrace[i], &backtrace_symbols[i],
244                line, MAX_BACKTRACE_LINE_LENGTH);
245        _LOG(log, scopeFlags, "    %s\n", line);
246    }
247    free_backtrace_symbols(backtrace_symbols, frames);
248}
249
250static void dump_stack_segment(const ptrace_context_t* context, log_t* log, pid_t tid,
251        int scopeFlags, uintptr_t* sp, size_t words, int label) {
252    for (size_t i = 0; i < words; i++) {
253        uint32_t stack_content;
254        if (!try_get_word_ptrace(tid, *sp, &stack_content)) {
255            break;
256        }
257
258        const map_info_t* mi;
259        const symbol_t* symbol;
260        find_symbol_ptrace(context, stack_content, &mi, &symbol);
261
262        if (symbol) {
263            char* demangled_name = demangle_symbol_name(symbol->name);
264            const char* symbol_name = demangled_name ? demangled_name : symbol->name;
265            uint32_t offset = stack_content - (mi->start + symbol->start);
266            if (!i && label >= 0) {
267                if (offset) {
268                    _LOG(log, scopeFlags, "    #%02d  %08x  %08x  %s (%s+%u)\n",
269                            label, *sp, stack_content, mi ? mi->name : "", symbol_name, offset);
270                } else {
271                    _LOG(log, scopeFlags, "    #%02d  %08x  %08x  %s (%s)\n",
272                            label, *sp, stack_content, mi ? mi->name : "", symbol_name);
273                }
274            } else {
275                if (offset) {
276                    _LOG(log, scopeFlags, "         %08x  %08x  %s (%s+%u)\n",
277                            *sp, stack_content, mi ? mi->name : "", symbol_name, offset);
278                } else {
279                    _LOG(log, scopeFlags, "         %08x  %08x  %s (%s)\n",
280                            *sp, stack_content, mi ? mi->name : "", symbol_name);
281                }
282            }
283            free(demangled_name);
284        } else {
285            if (!i && label >= 0) {
286                _LOG(log, scopeFlags, "    #%02d  %08x  %08x  %s\n",
287                        label, *sp, stack_content, mi ? mi->name : "");
288            } else {
289                _LOG(log, scopeFlags, "         %08x  %08x  %s\n",
290                        *sp, stack_content, mi ? mi->name : "");
291            }
292        }
293
294        *sp += sizeof(uint32_t);
295    }
296}
297
298static void dump_stack(const ptrace_context_t* context, log_t* log, pid_t tid, bool at_fault,
299        const backtrace_frame_t* backtrace, size_t frames) {
300    bool have_first = false;
301    size_t first, last;
302    for (size_t i = 0; i < frames; i++) {
303        if (backtrace[i].stack_top) {
304            if (!have_first) {
305                have_first = true;
306                first = i;
307            }
308            last = i;
309        }
310    }
311    if (!have_first) {
312        return;
313    }
314
315    int scopeFlags = SCOPE_SENSITIVE | (at_fault ? SCOPE_AT_FAULT : 0);
316    _LOG(log, scopeFlags, "\nstack:\n");
317
318    // Dump a few words before the first frame.
319    uintptr_t sp = backtrace[first].stack_top - STACK_WORDS * sizeof(uint32_t);
320    dump_stack_segment(context, log, tid, scopeFlags, &sp, STACK_WORDS, -1);
321
322    // Dump a few words from all successive frames.
323    // Only log the first 3 frames, put the rest in the tombstone.
324    for (size_t i = first; i <= last; i++) {
325        const backtrace_frame_t* frame = &backtrace[i];
326        if (sp != frame->stack_top) {
327            _LOG(log, scopeFlags, "         ........  ........\n");
328            sp = frame->stack_top;
329        }
330        if (i - first == 3) {
331            scopeFlags &= (~SCOPE_AT_FAULT);
332        }
333        if (i == last) {
334            dump_stack_segment(context, log, tid, scopeFlags, &sp, STACK_WORDS, i);
335            if (sp < frame->stack_top + frame->stack_size) {
336                _LOG(log, scopeFlags, "         ........  ........\n");
337            }
338        } else {
339            size_t words = frame->stack_size / sizeof(uint32_t);
340            if (words == 0) {
341                words = 1;
342            } else if (words > STACK_WORDS) {
343                words = STACK_WORDS;
344            }
345            dump_stack_segment(context, log, tid, scopeFlags, &sp, words, i);
346        }
347    }
348}
349
350static void dump_backtrace_and_stack(const ptrace_context_t* context, log_t* log, pid_t tid,
351        bool at_fault) {
352    backtrace_frame_t backtrace[STACK_DEPTH];
353    ssize_t frames = unwind_backtrace_ptrace(tid, context, backtrace, 0, STACK_DEPTH);
354    if (frames > 0) {
355        dump_backtrace(context, log, tid, at_fault, backtrace, frames);
356        dump_stack(context, log, tid, at_fault, backtrace, frames);
357    }
358}
359
360static void dump_map(log_t* log, map_info_t* m, const char* what, int scopeFlags) {
361    if (m != NULL) {
362        _LOG(log, scopeFlags, "    %08x-%08x %c%c%c %s\n", m->start, m->end,
363             m->is_readable ? 'r' : '-',
364             m->is_writable ? 'w' : '-',
365             m->is_executable ? 'x' : '-',
366             m->name);
367    } else {
368        _LOG(log, scopeFlags, "    (no %s)\n", what);
369    }
370}
371
372static void dump_nearby_maps(const ptrace_context_t* context, log_t* log, pid_t tid, bool at_fault) {
373    int scopeFlags = SCOPE_SENSITIVE | (at_fault ? SCOPE_AT_FAULT : 0);
374    siginfo_t si;
375    memset(&si, 0, sizeof(si));
376    if (ptrace(PTRACE_GETSIGINFO, tid, 0, &si)) {
377        _LOG(log, scopeFlags, "cannot get siginfo for %d: %s\n",
378                tid, strerror(errno));
379        return;
380    }
381    if (!signal_has_address(si.si_signo)) {
382        return;
383    }
384
385    uintptr_t addr = (uintptr_t) si.si_addr;
386    addr &= ~0xfff;     /* round to 4K page boundary */
387    if (addr == 0) {    /* null-pointer deref */
388        return;
389    }
390
391    _LOG(log, scopeFlags, "\nmemory map around fault addr %08x:\n", (int)si.si_addr);
392
393    /*
394     * Search for a match, or for a hole where the match would be.  The list
395     * is backward from the file content, so it starts at high addresses.
396     */
397    map_info_t* map = context->map_info_list;
398    map_info_t *next = NULL;
399    map_info_t *prev = NULL;
400    while (map != NULL) {
401        if (addr >= map->start && addr < map->end) {
402            next = map->next;
403            break;
404        } else if (addr >= map->end) {
405            /* map would be between "prev" and this entry */
406            next = map;
407            map = NULL;
408            break;
409        }
410
411        prev = map;
412        map = map->next;
413    }
414
415    /*
416     * Show "next" then "match" then "prev" so that the addresses appear in
417     * ascending order (like /proc/pid/maps).
418     */
419    dump_map(log, next, "map below", scopeFlags);
420    dump_map(log, map, "map for address", scopeFlags);
421    dump_map(log, prev, "map above", scopeFlags);
422}
423
424static void dump_thread(const ptrace_context_t* context, log_t* log, pid_t tid, bool at_fault,
425        int* total_sleep_time_usec) {
426    wait_for_stop(tid, total_sleep_time_usec);
427
428    dump_registers(context, log, tid, at_fault);
429    dump_backtrace_and_stack(context, log, tid, at_fault);
430    if (at_fault) {
431        dump_memory_and_code(context, log, tid, at_fault);
432        dump_nearby_maps(context, log, tid, at_fault);
433    }
434}
435
436/* Return true if some thread is not detached cleanly */
437static bool dump_sibling_thread_report(const ptrace_context_t* context,
438        log_t* log, pid_t pid, pid_t tid, int* total_sleep_time_usec) {
439    char task_path[64];
440    snprintf(task_path, sizeof(task_path), "/proc/%d/task", pid);
441
442    DIR* d = opendir(task_path);
443    /* Bail early if cannot open the task directory */
444    if (d == NULL) {
445        XLOG("Cannot open /proc/%d/task\n", pid);
446        return false;
447    }
448
449    bool detach_failed = false;
450    struct dirent* de;
451    while ((de = readdir(d)) != NULL) {
452        /* Ignore "." and ".." */
453        if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..")) {
454            continue;
455        }
456
457        /* The main thread at fault has been handled individually */
458        char* end;
459        pid_t new_tid = strtoul(de->d_name, &end, 10);
460        if (*end || new_tid == tid) {
461            continue;
462        }
463
464        /* Skip this thread if cannot ptrace it */
465        if (ptrace(PTRACE_ATTACH, new_tid, 0, 0) < 0) {
466            continue;
467        }
468
469        _LOG(log, 0, "--- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---\n");
470        dump_thread_info(log, pid, new_tid, false);
471        dump_thread(context, log, new_tid, false, total_sleep_time_usec);
472
473        if (ptrace(PTRACE_DETACH, new_tid, 0, 0) != 0) {
474            LOG("ptrace detach from %d failed: %s\n", new_tid, strerror(errno));
475            detach_failed = true;
476        }
477    }
478
479    closedir(d);
480    return detach_failed;
481}
482
483/*
484 * Reads the contents of the specified log device, filters out the entries
485 * that don't match the specified pid, and writes them to the tombstone file.
486 *
487 * If "tailOnly" is set, we only print the last few lines.
488 */
489static void dump_log_file(log_t* log, pid_t pid, const char* filename,
490    bool tailOnly)
491{
492    bool first = true;
493
494    /* circular buffer, for "tailOnly" mode */
495    const int kShortLogMaxLines = 5;
496    const int kShortLogLineLen = 256;
497    char shortLog[kShortLogMaxLines][kShortLogLineLen];
498    int shortLogCount = 0;
499    int shortLogNext = 0;
500
501    int logfd = open(filename, O_RDONLY | O_NONBLOCK);
502    if (logfd < 0) {
503        XLOG("Unable to open %s: %s\n", filename, strerror(errno));
504        return;
505    }
506
507    union {
508        unsigned char buf[LOGGER_ENTRY_MAX_LEN + 1];
509        struct logger_entry entry;
510    } log_entry;
511
512    while (true) {
513        ssize_t actual = read(logfd, log_entry.buf, LOGGER_ENTRY_MAX_LEN);
514        if (actual < 0) {
515            if (errno == EINTR) {
516                /* interrupted by signal, retry */
517                continue;
518            } else if (errno == EAGAIN) {
519                /* non-blocking EOF; we're done */
520                break;
521            } else {
522                _LOG(log, 0, "Error while reading log: %s\n",
523                    strerror(errno));
524                break;
525            }
526        } else if (actual == 0) {
527            _LOG(log, 0, "Got zero bytes while reading log: %s\n",
528                strerror(errno));
529            break;
530        }
531
532        /*
533         * NOTE: if you XLOG something here, this will spin forever,
534         * because you will be writing as fast as you're reading.  Any
535         * high-frequency debug diagnostics should just be written to
536         * the tombstone file.
537         */
538
539        struct logger_entry* entry = &log_entry.entry;
540
541        if (entry->pid != (int32_t) pid) {
542            /* wrong pid, ignore */
543            continue;
544        }
545
546        if (first) {
547            _LOG(log, 0, "--------- %slog %s\n",
548                tailOnly ? "tail end of " : "", filename);
549            first = false;
550        }
551
552        /*
553         * Msg format is: <priority:1><tag:N>\0<message:N>\0
554         *
555         * We want to display it in the same format as "logcat -v threadtime"
556         * (although in this case the pid is redundant).
557         *
558         * TODO: scan for line breaks ('\n') and display each text line
559         * on a separate line, prefixed with the header, like logcat does.
560         */
561        static const char* kPrioChars = "!.VDIWEFS";
562        unsigned char prio = entry->msg[0];
563        char* tag = entry->msg + 1;
564        char* msg = tag + strlen(tag) + 1;
565
566        /* consume any trailing newlines */
567        char* eatnl = msg + strlen(msg) - 1;
568        while (eatnl >= msg && *eatnl == '\n') {
569            *eatnl-- = '\0';
570        }
571
572        char prioChar = (prio < strlen(kPrioChars) ? kPrioChars[prio] : '?');
573
574        char timeBuf[32];
575        time_t sec = (time_t) entry->sec;
576        struct tm tmBuf;
577        struct tm* ptm;
578        ptm = localtime_r(&sec, &tmBuf);
579        strftime(timeBuf, sizeof(timeBuf), "%m-%d %H:%M:%S", ptm);
580
581        if (tailOnly) {
582            snprintf(shortLog[shortLogNext], kShortLogLineLen,
583                "%s.%03d %5d %5d %c %-8s: %s",
584                timeBuf, entry->nsec / 1000000, entry->pid, entry->tid,
585                prioChar, tag, msg);
586            shortLogNext = (shortLogNext + 1) % kShortLogMaxLines;
587            shortLogCount++;
588        } else {
589            _LOG(log, 0, "%s.%03d %5d %5d %c %-8s: %s\n",
590                timeBuf, entry->nsec / 1000000, entry->pid, entry->tid,
591                prioChar, tag, msg);
592        }
593    }
594
595    if (tailOnly) {
596        int i;
597
598        /*
599         * If we filled the buffer, we want to start at "next", which has
600         * the oldest entry.  If we didn't, we want to start at zero.
601         */
602        if (shortLogCount < kShortLogMaxLines) {
603            shortLogNext = 0;
604        } else {
605            shortLogCount = kShortLogMaxLines;  /* cap at window size */
606        }
607
608        for (i = 0; i < shortLogCount; i++) {
609            _LOG(log, 0, "%s\n", shortLog[shortLogNext]);
610            shortLogNext = (shortLogNext + 1) % kShortLogMaxLines;
611        }
612    }
613
614    close(logfd);
615}
616
617/*
618 * Dumps the logs generated by the specified pid to the tombstone, from both
619 * "system" and "main" log devices.  Ideally we'd interleave the output.
620 */
621static void dump_logs(log_t* log, pid_t pid, bool tailOnly)
622{
623    dump_log_file(log, pid, "/dev/log/system", tailOnly);
624    dump_log_file(log, pid, "/dev/log/main", tailOnly);
625}
626
627static void dump_abort_message(log_t* log, pid_t tid, uintptr_t address) {
628  if (address == 0) {
629    return;
630  }
631
632  address += sizeof(size_t); // Skip the buffer length.
633
634  char msg[512];
635  memset(msg, 0, sizeof(msg));
636  char* p = &msg[0];
637  while (p < &msg[sizeof(msg)]) {
638    uint32_t data;
639    if (!try_get_word_ptrace(tid, address, &data)) {
640      break;
641    }
642    address += sizeof(uint32_t);
643
644    if ((*p++ = (data >>  0) & 0xff) == 0) {
645      break;
646    }
647    if ((*p++ = (data >>  8) & 0xff) == 0) {
648      break;
649    }
650    if ((*p++ = (data >> 16) & 0xff) == 0) {
651      break;
652    }
653    if ((*p++ = (data >> 24) & 0xff) == 0) {
654      break;
655    }
656  }
657  msg[sizeof(msg) - 1] = '\0';
658
659  _LOG(log, SCOPE_AT_FAULT, "Abort message: '%s'\n", msg);
660}
661
662/*
663 * Dumps all information about the specified pid to the tombstone.
664 */
665static bool dump_crash(log_t* log, pid_t pid, pid_t tid, int signal, uintptr_t abort_msg_address,
666                       bool dump_sibling_threads, int* total_sleep_time_usec)
667{
668    /* don't copy log messages to tombstone unless this is a dev device */
669    char value[PROPERTY_VALUE_MAX];
670    property_get("ro.debuggable", value, "0");
671    bool want_logs = (value[0] == '1');
672
673    if (log->amfd >= 0) {
674        /*
675         * Activity Manager protocol: binary 32-bit network-byte-order ints for the
676         * pid and signal number, followed by the raw text of the dump, culminating
677         * in a zero byte that marks end-of-data.
678         */
679        uint32_t datum = htonl(pid);
680        TEMP_FAILURE_RETRY( write(log->amfd, &datum, 4) );
681        datum = htonl(signal);
682        TEMP_FAILURE_RETRY( write(log->amfd, &datum, 4) );
683    }
684
685    _LOG(log, SCOPE_AT_FAULT,
686            "*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***\n");
687    dump_build_info(log);
688    dump_revision_info(log);
689    dump_thread_info(log, pid, tid, true);
690    if (signal) {
691        dump_fault_addr(log, tid, signal);
692    }
693    dump_abort_message(log, tid, abort_msg_address);
694
695    ptrace_context_t* context = load_ptrace_context(tid);
696    dump_thread(context, log, tid, true, total_sleep_time_usec);
697
698    if (want_logs) {
699        dump_logs(log, pid, true);
700    }
701
702    bool detach_failed = false;
703    if (dump_sibling_threads) {
704        detach_failed = dump_sibling_thread_report(context, log, pid, tid, total_sleep_time_usec);
705    }
706
707    free_ptrace_context(context);
708
709    if (want_logs) {
710        dump_logs(log, pid, false);
711    }
712
713    /* send EOD to the Activity Manager, then wait for its ack to avoid racing ahead
714     * and killing the target out from under it */
715    if (log->amfd >= 0) {
716        uint8_t eodMarker = 0;
717        TEMP_FAILURE_RETRY( write(log->amfd, &eodMarker, 1) );
718        /* 3 sec timeout reading the ack; we're fine if that happens */
719        TEMP_FAILURE_RETRY( read(log->amfd, &eodMarker, 1) );
720    }
721
722    return detach_failed;
723}
724
725/*
726 * find_and_open_tombstone - find an available tombstone slot, if any, of the
727 * form tombstone_XX where XX is 00 to MAX_TOMBSTONES-1, inclusive. If no
728 * file is available, we reuse the least-recently-modified file.
729 *
730 * Returns the path of the tombstone file, allocated using malloc().  Caller must free() it.
731 */
732static char* find_and_open_tombstone(int* fd)
733{
734    unsigned long mtime = ULONG_MAX;
735    struct stat sb;
736
737    /*
738     * XXX: Our stat.st_mtime isn't time_t. If it changes, as it probably ought
739     * to, our logic breaks. This check will generate a warning if that happens.
740     */
741    typecheck(mtime, sb.st_mtime);
742
743    /*
744     * In a single wolf-like pass, find an available slot and, in case none
745     * exist, find and record the least-recently-modified file.
746     */
747    char path[128];
748    int oldest = 0;
749    for (int i = 0; i < MAX_TOMBSTONES; i++) {
750        snprintf(path, sizeof(path), TOMBSTONE_DIR"/tombstone_%02d", i);
751
752        if (!stat(path, &sb)) {
753            if (sb.st_mtime < mtime) {
754                oldest = i;
755                mtime = sb.st_mtime;
756            }
757            continue;
758        }
759        if (errno != ENOENT)
760            continue;
761
762        *fd = open(path, O_CREAT | O_EXCL | O_WRONLY, 0600);
763        if (*fd < 0)
764            continue;   /* raced ? */
765
766        fchown(*fd, AID_SYSTEM, AID_SYSTEM);
767        return strdup(path);
768    }
769
770    /* we didn't find an available file, so we clobber the oldest one */
771    snprintf(path, sizeof(path), TOMBSTONE_DIR"/tombstone_%02d", oldest);
772    *fd = open(path, O_CREAT | O_TRUNC | O_WRONLY, 0600);
773    if (*fd < 0) {
774        LOG("failed to open tombstone file '%s': %s\n", path, strerror(errno));
775        return NULL;
776    }
777    fchown(*fd, AID_SYSTEM, AID_SYSTEM);
778    return strdup(path);
779}
780
781static int activity_manager_connect() {
782    int amfd = socket(PF_UNIX, SOCK_STREAM, 0);
783    if (amfd >= 0) {
784        struct sockaddr_un address;
785        int err;
786
787        memset(&address, 0, sizeof(address));
788        address.sun_family = AF_UNIX;
789        strncpy(address.sun_path, NCRASH_SOCKET_PATH, sizeof(address.sun_path));
790        err = TEMP_FAILURE_RETRY( connect(amfd, (struct sockaddr*) &address, sizeof(address)) );
791        if (!err) {
792            struct timeval tv;
793            memset(&tv, 0, sizeof(tv));
794            tv.tv_sec = 1;  // tight leash
795            err = setsockopt(amfd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
796            if (!err) {
797                tv.tv_sec = 3;  // 3 seconds on handshake read
798                err = setsockopt(amfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
799            }
800        }
801        if (err) {
802            close(amfd);
803            amfd = -1;
804        }
805    }
806
807    return amfd;
808}
809
810char* engrave_tombstone(pid_t pid, pid_t tid, int signal, uintptr_t abort_msg_address,
811        bool dump_sibling_threads, bool quiet, bool* detach_failed,
812        int* total_sleep_time_usec) {
813    mkdir(TOMBSTONE_DIR, 0755);
814    chown(TOMBSTONE_DIR, AID_SYSTEM, AID_SYSTEM);
815
816    if (selinux_android_restorecon(TOMBSTONE_DIR) == -1) {
817        *detach_failed = false;
818        return NULL;
819    }
820
821    int fd;
822    char* path = find_and_open_tombstone(&fd);
823    if (!path) {
824        *detach_failed = false;
825        return NULL;
826    }
827
828    log_t log;
829    log.tfd = fd;
830    log.amfd = activity_manager_connect();
831    log.quiet = quiet;
832    *detach_failed = dump_crash(&log, pid, tid, signal, abort_msg_address, dump_sibling_threads,
833            total_sleep_time_usec);
834
835    close(log.amfd);
836    close(fd);
837    return path;
838}
839