Home | History | Annotate | Download | only in debuggerd
      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 <log/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 
     62 static 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 
     74 static 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 
     91 static 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 
    160 static 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 
    169 static 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 
    178 static 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 
    196 static 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 
    233 static 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 
    250 static 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 
    298 static 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 
    350 static 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 
    360 static 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 
    372 static 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 
    424 static 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 */
    437 static 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  */
    489 static 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  */
    621 static 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 
    627 static 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  */
    665 static 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  */
    732 static 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 
    781 static 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 
    810 char* 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