tombstone.cpp revision cbe70cb0a8cb0171f3802273050e851a47b090ed
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 <sys/ptrace.h> 29#include <sys/stat.h> 30#include <time.h> 31 32#include <memory> 33#include <string> 34 35#include <android/log.h> 36#include <android-base/stringprintf.h> 37#include <backtrace/Backtrace.h> 38#include <backtrace/BacktraceMap.h> 39#include <cutils/properties.h> 40#include <log/log.h> 41#include <log/logprint.h> 42#include <private/android_filesystem_config.h> 43 44#include "debuggerd/handler.h" 45 46#include "backtrace.h" 47#include "elf_utils.h" 48#include "machine.h" 49#include "open_files_list.h" 50#include "tombstone.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 58static bool signal_has_si_addr(int si_signo, int si_code) { 59 // Manually sent signals won't have si_addr. 60 if (si_code == SI_USER || si_code == SI_QUEUE || si_code == SI_TKILL) { 61 return false; 62 } 63 64 switch (si_signo) { 65 case SIGBUS: 66 case SIGFPE: 67 case SIGILL: 68 case SIGSEGV: 69 case SIGTRAP: 70 return true; 71 default: 72 return false; 73 } 74} 75 76static const char* get_signame(int sig) { 77 switch(sig) { 78 case SIGABRT: return "SIGABRT"; 79 case SIGBUS: return "SIGBUS"; 80 case SIGFPE: return "SIGFPE"; 81 case SIGILL: return "SIGILL"; 82 case SIGSEGV: return "SIGSEGV"; 83#if defined(SIGSTKFLT) 84 case SIGSTKFLT: return "SIGSTKFLT"; 85#endif 86 case SIGSTOP: return "SIGSTOP"; 87 case SIGSYS: return "SIGSYS"; 88 case SIGTRAP: return "SIGTRAP"; 89 case DEBUGGER_SIGNAL: return "<debuggerd signal>"; 90 default: return "?"; 91 } 92} 93 94static const char* get_sigcode(int signo, int code) { 95 // Try the signal-specific codes... 96 switch (signo) { 97 case SIGILL: 98 switch (code) { 99 case ILL_ILLOPC: return "ILL_ILLOPC"; 100 case ILL_ILLOPN: return "ILL_ILLOPN"; 101 case ILL_ILLADR: return "ILL_ILLADR"; 102 case ILL_ILLTRP: return "ILL_ILLTRP"; 103 case ILL_PRVOPC: return "ILL_PRVOPC"; 104 case ILL_PRVREG: return "ILL_PRVREG"; 105 case ILL_COPROC: return "ILL_COPROC"; 106 case ILL_BADSTK: return "ILL_BADSTK"; 107 } 108 static_assert(NSIGILL == ILL_BADSTK, "missing ILL_* si_code"); 109 break; 110 case SIGBUS: 111 switch (code) { 112 case BUS_ADRALN: return "BUS_ADRALN"; 113 case BUS_ADRERR: return "BUS_ADRERR"; 114 case BUS_OBJERR: return "BUS_OBJERR"; 115 case BUS_MCEERR_AR: return "BUS_MCEERR_AR"; 116 case BUS_MCEERR_AO: return "BUS_MCEERR_AO"; 117 } 118 static_assert(NSIGBUS == BUS_MCEERR_AO, "missing BUS_* si_code"); 119 break; 120 case SIGFPE: 121 switch (code) { 122 case FPE_INTDIV: return "FPE_INTDIV"; 123 case FPE_INTOVF: return "FPE_INTOVF"; 124 case FPE_FLTDIV: return "FPE_FLTDIV"; 125 case FPE_FLTOVF: return "FPE_FLTOVF"; 126 case FPE_FLTUND: return "FPE_FLTUND"; 127 case FPE_FLTRES: return "FPE_FLTRES"; 128 case FPE_FLTINV: return "FPE_FLTINV"; 129 case FPE_FLTSUB: return "FPE_FLTSUB"; 130 } 131 static_assert(NSIGFPE == FPE_FLTSUB, "missing FPE_* si_code"); 132 break; 133 case SIGSEGV: 134 switch (code) { 135 case SEGV_MAPERR: return "SEGV_MAPERR"; 136 case SEGV_ACCERR: return "SEGV_ACCERR"; 137#if defined(SEGV_BNDERR) 138 case SEGV_BNDERR: return "SEGV_BNDERR"; 139#endif 140#if defined(SEGV_PKUERR) 141 case SEGV_PKUERR: return "SEGV_PKUERR"; 142#endif 143 } 144#if defined(SEGV_PKUERR) 145 static_assert(NSIGSEGV == SEGV_PKUERR, "missing SEGV_* si_code"); 146#elif defined(SEGV_BNDERR) 147 static_assert(NSIGSEGV == SEGV_BNDERR, "missing SEGV_* si_code"); 148#else 149 static_assert(NSIGSEGV == SEGV_ACCERR, "missing SEGV_* si_code"); 150#endif 151 break; 152#if defined(SYS_SECCOMP) // Our glibc is too old, and we build this for the host too. 153 case SIGSYS: 154 switch (code) { 155 case SYS_SECCOMP: return "SYS_SECCOMP"; 156 } 157 static_assert(NSIGSYS == SYS_SECCOMP, "missing SYS_* si_code"); 158 break; 159#endif 160 case SIGTRAP: 161 switch (code) { 162 case TRAP_BRKPT: return "TRAP_BRKPT"; 163 case TRAP_TRACE: return "TRAP_TRACE"; 164 case TRAP_BRANCH: return "TRAP_BRANCH"; 165 case TRAP_HWBKPT: return "TRAP_HWBKPT"; 166 } 167 static_assert(NSIGTRAP == TRAP_HWBKPT, "missing TRAP_* si_code"); 168 break; 169 } 170 // Then the other codes... 171 switch (code) { 172 case SI_USER: return "SI_USER"; 173 case SI_KERNEL: return "SI_KERNEL"; 174 case SI_QUEUE: return "SI_QUEUE"; 175 case SI_TIMER: return "SI_TIMER"; 176 case SI_MESGQ: return "SI_MESGQ"; 177 case SI_ASYNCIO: return "SI_ASYNCIO"; 178 case SI_SIGIO: return "SI_SIGIO"; 179 case SI_TKILL: return "SI_TKILL"; 180 case SI_DETHREAD: return "SI_DETHREAD"; 181 } 182 // Then give up... 183 return "?"; 184} 185 186static void dump_header_info(log_t* log) { 187 char fingerprint[PROPERTY_VALUE_MAX]; 188 char revision[PROPERTY_VALUE_MAX]; 189 190 property_get("ro.build.fingerprint", fingerprint, "unknown"); 191 property_get("ro.revision", revision, "unknown"); 192 193 _LOG(log, logtype::HEADER, "Build fingerprint: '%s'\n", fingerprint); 194 _LOG(log, logtype::HEADER, "Revision: '%s'\n", revision); 195 _LOG(log, logtype::HEADER, "ABI: '%s'\n", ABI_STRING); 196} 197 198static void dump_signal_info(log_t* log, pid_t tid) { 199 siginfo_t si; 200 memset(&si, 0, sizeof(si)); 201 if (ptrace(PTRACE_GETSIGINFO, tid, 0, &si) == -1) { 202 ALOGE("cannot get siginfo: %s\n", strerror(errno)); 203 return; 204 } 205 206 char addr_desc[32]; // ", fault addr 0x1234" 207 if (signal_has_si_addr(si.si_signo, si.si_code)) { 208 snprintf(addr_desc, sizeof(addr_desc), "%p", si.si_addr); 209 } else { 210 snprintf(addr_desc, sizeof(addr_desc), "--------"); 211 } 212 213 _LOG(log, logtype::HEADER, "signal %d (%s), code %d (%s), fault addr %s\n", si.si_signo, 214 get_signame(si.si_signo), si.si_code, get_sigcode(si.si_signo, si.si_code), addr_desc); 215} 216 217static void dump_thread_info(log_t* log, pid_t pid, pid_t tid) { 218 char path[64]; 219 char threadnamebuf[1024]; 220 char* threadname = nullptr; 221 FILE *fp; 222 223 snprintf(path, sizeof(path), "/proc/%d/comm", tid); 224 if ((fp = fopen(path, "r"))) { 225 threadname = fgets(threadnamebuf, sizeof(threadnamebuf), fp); 226 fclose(fp); 227 if (threadname) { 228 size_t len = strlen(threadname); 229 if (len && threadname[len - 1] == '\n') { 230 threadname[len - 1] = '\0'; 231 } 232 } 233 } 234 // Blacklist logd, logd.reader, logd.writer, logd.auditd, logd.control ... 235 static const char logd[] = "logd"; 236 if (threadname != nullptr && !strncmp(threadname, logd, sizeof(logd) - 1) 237 && (!threadname[sizeof(logd) - 1] || (threadname[sizeof(logd) - 1] == '.'))) { 238 log->should_retrieve_logcat = false; 239 } 240 241 char procnamebuf[1024]; 242 char* procname = nullptr; 243 244 snprintf(path, sizeof(path), "/proc/%d/cmdline", pid); 245 if ((fp = fopen(path, "r"))) { 246 procname = fgets(procnamebuf, sizeof(procnamebuf), fp); 247 fclose(fp); 248 } 249 250 _LOG(log, logtype::HEADER, "pid: %d, tid: %d, name: %s >>> %s <<<\n", pid, tid, 251 threadname ? threadname : "UNKNOWN", procname ? procname : "UNKNOWN"); 252} 253 254static void dump_stack_segment( 255 Backtrace* backtrace, log_t* log, uintptr_t* sp, size_t words, int label) { 256 // Read the data all at once. 257 word_t stack_data[words]; 258 size_t bytes_read = backtrace->Read(*sp, reinterpret_cast<uint8_t*>(&stack_data[0]), sizeof(word_t) * words); 259 words = bytes_read / sizeof(word_t); 260 std::string line; 261 for (size_t i = 0; i < words; i++) { 262 line = " "; 263 if (i == 0 && label >= 0) { 264 // Print the label once. 265 line += android::base::StringPrintf("#%02d ", label); 266 } else { 267 line += " "; 268 } 269 line += android::base::StringPrintf("%" PRIPTR " %" PRIPTR, *sp, stack_data[i]); 270 271 backtrace_map_t map; 272 backtrace->FillInMap(stack_data[i], &map); 273 if (BacktraceMap::IsValid(map) && !map.name.empty()) { 274 line += " " + map.name; 275 uintptr_t offset = 0; 276 std::string func_name(backtrace->GetFunctionName(stack_data[i], &offset)); 277 if (!func_name.empty()) { 278 line += " (" + func_name; 279 if (offset) { 280 line += android::base::StringPrintf("+%" PRIuPTR, offset); 281 } 282 line += ')'; 283 } 284 } 285 _LOG(log, logtype::STACK, "%s\n", line.c_str()); 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 std::string get_addr_string(uintptr_t addr) { 337 std::string addr_str; 338#if defined(__LP64__) 339 addr_str = android::base::StringPrintf("%08x'%08x", 340 static_cast<uint32_t>(addr >> 32), 341 static_cast<uint32_t>(addr & 0xffffffff)); 342#else 343 addr_str = android::base::StringPrintf("%08x", addr); 344#endif 345 return addr_str; 346} 347 348static void dump_abort_message(Backtrace* backtrace, log_t* log, uintptr_t address) { 349 if (address == 0) { 350 return; 351 } 352 353 address += sizeof(size_t); // Skip the buffer length. 354 355 char msg[512]; 356 memset(msg, 0, sizeof(msg)); 357 char* p = &msg[0]; 358 while (p < &msg[sizeof(msg)]) { 359 word_t data; 360 size_t len = sizeof(word_t); 361 if (!backtrace->ReadWord(address, &data)) { 362 break; 363 } 364 address += sizeof(word_t); 365 366 while (len > 0 && (*p++ = (data >> (sizeof(word_t) - len) * 8) & 0xff) != 0) { 367 len--; 368 } 369 } 370 msg[sizeof(msg) - 1] = '\0'; 371 372 _LOG(log, logtype::HEADER, "Abort message: '%s'\n", msg); 373} 374 375static void dump_all_maps(Backtrace* backtrace, BacktraceMap* map, log_t* log, pid_t tid) { 376 bool print_fault_address_marker = false; 377 uintptr_t addr = 0; 378 siginfo_t si; 379 memset(&si, 0, sizeof(si)); 380 if (ptrace(PTRACE_GETSIGINFO, tid, 0, &si) != -1) { 381 print_fault_address_marker = signal_has_si_addr(si.si_signo, si.si_code); 382 addr = reinterpret_cast<uintptr_t>(si.si_addr); 383 } else { 384 ALOGE("Cannot get siginfo for %d: %s\n", tid, strerror(errno)); 385 } 386 387 ScopedBacktraceMapIteratorLock lock(map); 388 _LOG(log, logtype::MAPS, "\n"); 389 if (!print_fault_address_marker) { 390 _LOG(log, logtype::MAPS, "memory map:\n"); 391 } else { 392 _LOG(log, logtype::MAPS, "memory map: (fault address prefixed with --->)\n"); 393 if (map->begin() != map->end() && addr < map->begin()->start) { 394 _LOG(log, logtype::MAPS, "--->Fault address falls at %s before any mapped regions\n", 395 get_addr_string(addr).c_str()); 396 print_fault_address_marker = false; 397 } 398 } 399 400 std::string line; 401 for (BacktraceMap::const_iterator it = map->begin(); it != map->end(); ++it) { 402 line = " "; 403 if (print_fault_address_marker) { 404 if (addr < it->start) { 405 _LOG(log, logtype::MAPS, "--->Fault address falls at %s between mapped regions\n", 406 get_addr_string(addr).c_str()); 407 print_fault_address_marker = false; 408 } else if (addr >= it->start && addr < it->end) { 409 line = "--->"; 410 print_fault_address_marker = false; 411 } 412 } 413 line += get_addr_string(it->start) + '-' + get_addr_string(it->end - 1) + ' '; 414 if (it->flags & PROT_READ) { 415 line += 'r'; 416 } else { 417 line += '-'; 418 } 419 if (it->flags & PROT_WRITE) { 420 line += 'w'; 421 } else { 422 line += '-'; 423 } 424 if (it->flags & PROT_EXEC) { 425 line += 'x'; 426 } else { 427 line += '-'; 428 } 429 line += android::base::StringPrintf(" %8" PRIxPTR " %8" PRIxPTR, 430 it->offset, it->end - it->start); 431 bool space_needed = true; 432 if (it->name.length() > 0) { 433 space_needed = false; 434 line += " " + it->name; 435 std::string build_id; 436 if ((it->flags & PROT_READ) && elf_get_build_id(backtrace, it->start, &build_id)) { 437 line += " (BuildId: " + build_id + ")"; 438 } 439 } 440 if (it->load_base != 0) { 441 if (space_needed) { 442 line += ' '; 443 } 444 line += android::base::StringPrintf(" (load base 0x%" PRIxPTR ")", it->load_base); 445 } 446 _LOG(log, logtype::MAPS, "%s\n", line.c_str()); 447 } 448 if (print_fault_address_marker) { 449 _LOG(log, logtype::MAPS, "--->Fault address falls at %s after any mapped regions\n", 450 get_addr_string(addr).c_str()); 451 } 452} 453 454static void dump_backtrace_and_stack(Backtrace* backtrace, log_t* log) { 455 if (backtrace->NumFrames()) { 456 _LOG(log, logtype::BACKTRACE, "\nbacktrace:\n"); 457 dump_backtrace_to_log(backtrace, log, " "); 458 459 _LOG(log, logtype::STACK, "\nstack:\n"); 460 dump_stack(backtrace, log); 461 } 462} 463 464static void dump_thread(log_t* log, pid_t pid, pid_t tid, BacktraceMap* map, 465 uintptr_t abort_msg_address, bool primary_thread) { 466 log->current_tid = tid; 467 if (!primary_thread) { 468 _LOG(log, logtype::THREAD, "--- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---\n"); 469 } 470 dump_thread_info(log, pid, tid); 471 dump_signal_info(log, tid); 472 473 std::unique_ptr<Backtrace> backtrace(Backtrace::Create(pid, tid, map)); 474 if (primary_thread) { 475 dump_abort_message(backtrace.get(), log, abort_msg_address); 476 } 477 dump_registers(log, tid); 478 if (backtrace->Unwind(0)) { 479 dump_backtrace_and_stack(backtrace.get(), log); 480 } else { 481 ALOGE("Unwind failed: pid = %d, tid = %d", pid, tid); 482 } 483 484 if (primary_thread) { 485 dump_memory_and_code(log, backtrace.get()); 486 if (map) { 487 dump_all_maps(backtrace.get(), map, log, tid); 488 } 489 } 490 491 log->current_tid = log->crashed_tid; 492} 493 494// Reads the contents of the specified log device, filters out the entries 495// that don't match the specified pid, and writes them to the tombstone file. 496// 497// If "tail" is non-zero, log the last "tail" number of lines. 498static EventTagMap* g_eventTagMap = NULL; 499 500static void dump_log_file( 501 log_t* log, pid_t pid, const char* filename, unsigned int tail) { 502 bool first = true; 503 struct logger_list* logger_list; 504 505 if (!log->should_retrieve_logcat) { 506 return; 507 } 508 509 logger_list = android_logger_list_open( 510 android_name_to_log_id(filename), ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, tail, pid); 511 512 if (!logger_list) { 513 ALOGE("Unable to open %s: %s\n", filename, strerror(errno)); 514 return; 515 } 516 517 struct log_msg log_entry; 518 519 while (true) { 520 ssize_t actual = android_logger_list_read(logger_list, &log_entry); 521 struct logger_entry* entry; 522 523 if (actual < 0) { 524 if (actual == -EINTR) { 525 // interrupted by signal, retry 526 continue; 527 } else if (actual == -EAGAIN) { 528 // non-blocking EOF; we're done 529 break; 530 } else { 531 ALOGE("Error while reading log: %s\n", strerror(-actual)); 532 break; 533 } 534 } else if (actual == 0) { 535 ALOGE("Got zero bytes while reading log: %s\n", strerror(errno)); 536 break; 537 } 538 539 // NOTE: if you ALOGV something here, this will spin forever, 540 // because you will be writing as fast as you're reading. Any 541 // high-frequency debug diagnostics should just be written to 542 // the tombstone file. 543 544 entry = &log_entry.entry_v1; 545 546 if (first) { 547 _LOG(log, logtype::LOGS, "--------- %slog %s\n", 548 tail ? "tail end of " : "", filename); 549 first = false; 550 } 551 552 // Msg format is: <priority:1><tag:N>\0<message:N>\0 553 // 554 // We want to display it in the same format as "logcat -v threadtime" 555 // (although in this case the pid is redundant). 556 static const char* kPrioChars = "!.VDIWEFS"; 557 unsigned hdr_size = log_entry.entry.hdr_size; 558 if (!hdr_size) { 559 hdr_size = sizeof(log_entry.entry_v1); 560 } 561 if ((hdr_size < sizeof(log_entry.entry_v1)) || 562 (hdr_size > sizeof(log_entry.entry))) { 563 continue; 564 } 565 char* msg = reinterpret_cast<char*>(log_entry.buf) + hdr_size; 566 567 char timeBuf[32]; 568 time_t sec = static_cast<time_t>(entry->sec); 569 struct tm tmBuf; 570 struct tm* ptm; 571 ptm = localtime_r(&sec, &tmBuf); 572 strftime(timeBuf, sizeof(timeBuf), "%m-%d %H:%M:%S", ptm); 573 574 if (log_entry.id() == LOG_ID_EVENTS) { 575 if (!g_eventTagMap) { 576 g_eventTagMap = android_openEventTagMap(NULL); 577 } 578 AndroidLogEntry e; 579 char buf[512]; 580 android_log_processBinaryLogBuffer(entry, &e, g_eventTagMap, buf, sizeof(buf)); 581 _LOG(log, logtype::LOGS, "%s.%03d %5d %5d %c %-8.*s: %s\n", 582 timeBuf, entry->nsec / 1000000, entry->pid, entry->tid, 583 'I', (int)e.tagLen, e.tag, e.message); 584 continue; 585 } 586 587 unsigned char prio = msg[0]; 588 char* tag = msg + 1; 589 msg = tag + strlen(tag) + 1; 590 591 // consume any trailing newlines 592 char* nl = msg + strlen(msg) - 1; 593 while (nl >= msg && *nl == '\n') { 594 *nl-- = '\0'; 595 } 596 597 char prioChar = (prio < strlen(kPrioChars) ? kPrioChars[prio] : '?'); 598 599 // Look for line breaks ('\n') and display each text line 600 // on a separate line, prefixed with the header, like logcat does. 601 do { 602 nl = strchr(msg, '\n'); 603 if (nl) { 604 *nl = '\0'; 605 ++nl; 606 } 607 608 _LOG(log, logtype::LOGS, "%s.%03d %5d %5d %c %-8s: %s\n", 609 timeBuf, entry->nsec / 1000000, entry->pid, entry->tid, 610 prioChar, tag, msg); 611 } while ((msg = nl)); 612 } 613 614 android_logger_list_free(logger_list); 615} 616 617// Dumps the logs generated by the specified pid to the tombstone, from both 618// "system" and "main" log devices. Ideally we'd interleave the output. 619static void dump_logs(log_t* log, pid_t pid, unsigned int tail) { 620 dump_log_file(log, pid, "system", tail); 621 dump_log_file(log, pid, "main", tail); 622} 623 624// Dumps all information about the specified pid to the tombstone. 625static void dump_crash(log_t* log, BacktraceMap* map, 626 const OpenFilesList& open_files, pid_t pid, pid_t tid, 627 const std::set<pid_t>& siblings, uintptr_t abort_msg_address) { 628 // don't copy log messages to tombstone unless this is a dev device 629 char value[PROPERTY_VALUE_MAX]; 630 property_get("ro.debuggable", value, "0"); 631 bool want_logs = (value[0] == '1'); 632 633 _LOG(log, logtype::HEADER, 634 "*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***\n"); 635 dump_header_info(log); 636 dump_thread(log, pid, tid, map, abort_msg_address, true); 637 if (want_logs) { 638 dump_logs(log, pid, 5); 639 } 640 641 if (!siblings.empty()) { 642 for (pid_t sibling : siblings) { 643 dump_thread(log, pid, sibling, map, 0, false); 644 } 645 } 646 647 _LOG(log, logtype::OPEN_FILES, "\nopen files:\n"); 648 dump_open_files_list_to_log(open_files, log, " "); 649 650 if (want_logs) { 651 dump_logs(log, pid, 0); 652 } 653} 654 655// open_tombstone - find an available tombstone slot, if any, of the 656// form tombstone_XX where XX is 00 to MAX_TOMBSTONES-1, inclusive. If no 657// file is available, we reuse the least-recently-modified file. 658int open_tombstone(std::string* out_path) { 659 // In a single pass, find an available slot and, in case none 660 // exist, find and record the least-recently-modified file. 661 char path[128]; 662 int fd = -1; 663 int oldest = -1; 664 struct stat oldest_sb; 665 for (int i = 0; i < MAX_TOMBSTONES; i++) { 666 snprintf(path, sizeof(path), TOMBSTONE_TEMPLATE, i); 667 668 struct stat sb; 669 if (stat(path, &sb) == 0) { 670 if (oldest < 0 || sb.st_mtime < oldest_sb.st_mtime) { 671 oldest = i; 672 oldest_sb.st_mtime = sb.st_mtime; 673 } 674 continue; 675 } 676 if (errno != ENOENT) continue; 677 678 fd = open(path, O_CREAT | O_EXCL | O_WRONLY | O_NOFOLLOW | O_CLOEXEC, 0600); 679 if (fd < 0) continue; // raced ? 680 681 if (out_path) { 682 *out_path = path; 683 } 684 fchown(fd, AID_SYSTEM, AID_SYSTEM); 685 return fd; 686 } 687 688 if (oldest < 0) { 689 ALOGE("debuggerd: failed to find a valid tombstone, default to using tombstone 0.\n"); 690 oldest = 0; 691 } 692 693 // we didn't find an available file, so we clobber the oldest one 694 snprintf(path, sizeof(path), TOMBSTONE_TEMPLATE, oldest); 695 fd = open(path, O_CREAT | O_TRUNC | O_WRONLY | O_NOFOLLOW | O_CLOEXEC, 0600); 696 if (fd < 0) { 697 ALOGE("debuggerd: failed to open tombstone file '%s': %s\n", path, strerror(errno)); 698 return -1; 699 } 700 701 if (out_path) { 702 *out_path = path; 703 } 704 fchown(fd, AID_SYSTEM, AID_SYSTEM); 705 return fd; 706} 707 708void engrave_tombstone(int tombstone_fd, BacktraceMap* map, 709 const OpenFilesList& open_files, pid_t pid, pid_t tid, 710 const std::set<pid_t>& siblings, uintptr_t abort_msg_address, 711 std::string* amfd_data) { 712 log_t log; 713 log.current_tid = tid; 714 log.crashed_tid = tid; 715 716 if (tombstone_fd < 0) { 717 ALOGE("debuggerd: skipping tombstone write, nothing to do.\n"); 718 return; 719 } 720 721 log.tfd = tombstone_fd; 722 log.amfd_data = amfd_data; 723 dump_crash(&log, map, open_files, pid, tid, siblings, abort_msg_address); 724} 725