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