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