debuggerd.c revision 41e0cef301637cd1f2daf72953d1230b7fb174b8
1/* system/debuggerd/debuggerd.c 2** 3** Copyright 2006, The Android Open Source Project 4** 5** Licensed under the Apache License, Version 2.0 (the "License"); 6** you may not use this file except in compliance with the License. 7** You may obtain a copy of the License at 8** 9** http://www.apache.org/licenses/LICENSE-2.0 10** 11** Unless required by applicable law or agreed to in writing, software 12** distributed under the License is distributed on an "AS IS" BASIS, 13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14** See the License for the specific language governing permissions and 15** limitations under the License. 16*/ 17 18#include <stdio.h> 19#include <errno.h> 20#include <signal.h> 21#include <pthread.h> 22#include <stdarg.h> 23#include <fcntl.h> 24#include <sys/types.h> 25#include <dirent.h> 26 27#include <sys/ptrace.h> 28#include <sys/wait.h> 29#include <sys/exec_elf.h> 30#include <sys/stat.h> 31 32#include <cutils/sockets.h> 33#include <cutils/logd.h> 34#include <cutils/logger.h> 35#include <cutils/properties.h> 36 37#include <linux/input.h> 38 39#include <private/android_filesystem_config.h> 40 41#include "debuggerd.h" 42#include "utility.h" 43 44#define ANDROID_LOG_INFO 4 45 46/* Log information onto the tombstone */ 47void _LOG(int tfd, bool in_tombstone_only, const char *fmt, ...) 48{ 49 char buf[512]; 50 51 va_list ap; 52 va_start(ap, fmt); 53 54 if (tfd >= 0) { 55 int len; 56 vsnprintf(buf, sizeof(buf), fmt, ap); 57 len = strlen(buf); 58 if(tfd >= 0) write(tfd, buf, len); 59 } 60 61 if (!in_tombstone_only) 62 __android_log_vprint(ANDROID_LOG_INFO, "DEBUG", fmt, ap); 63} 64 65// 6f000000-6f01e000 rwxp 00000000 00:0c 16389419 /system/lib/libcomposer.so 66// 012345678901234567890123456789012345678901234567890123456789 67// 0 1 2 3 4 5 68 69mapinfo *parse_maps_line(char *line) 70{ 71 mapinfo *mi; 72 int len = strlen(line); 73 74 if (len < 1) return 0; /* not expected */ 75 line[--len] = 0; 76 77 if (len < 50) { 78 mi = malloc(sizeof(mapinfo) + 1); 79 } else { 80 mi = malloc(sizeof(mapinfo) + (len - 47)); 81 } 82 if (mi == 0) return 0; 83 84 mi->isExecutable = (line[20] == 'x'); 85 86 mi->start = strtoul(line, 0, 16); 87 mi->end = strtoul(line + 9, 0, 16); 88 /* To be filled in parse_elf_info if the mapped section starts with 89 * elf_header 90 */ 91 mi->exidx_start = mi->exidx_end = 0; 92 mi->symbols = 0; 93 mi->next = 0; 94 if (len < 50) { 95 mi->name[0] = '\0'; 96 } else { 97 strcpy(mi->name, line + 49); 98 } 99 100 return mi; 101} 102 103void dump_build_info(int tfd) 104{ 105 char fingerprint[PROPERTY_VALUE_MAX]; 106 107 property_get("ro.build.fingerprint", fingerprint, "unknown"); 108 109 _LOG(tfd, false, "Build fingerprint: '%s'\n", fingerprint); 110} 111 112const char *get_signame(int sig) 113{ 114 switch(sig) { 115 case SIGILL: return "SIGILL"; 116 case SIGABRT: return "SIGABRT"; 117 case SIGBUS: return "SIGBUS"; 118 case SIGFPE: return "SIGFPE"; 119 case SIGSEGV: return "SIGSEGV"; 120 case SIGSTKFLT: return "SIGSTKFLT"; 121 default: return "?"; 122 } 123} 124 125const char *get_sigcode(int signo, int code) 126{ 127 switch (signo) { 128 case SIGILL: 129 switch (code) { 130 case ILL_ILLOPC: return "ILL_ILLOPC"; 131 case ILL_ILLOPN: return "ILL_ILLOPN"; 132 case ILL_ILLADR: return "ILL_ILLADR"; 133 case ILL_ILLTRP: return "ILL_ILLTRP"; 134 case ILL_PRVOPC: return "ILL_PRVOPC"; 135 case ILL_PRVREG: return "ILL_PRVREG"; 136 case ILL_COPROC: return "ILL_COPROC"; 137 case ILL_BADSTK: return "ILL_BADSTK"; 138 } 139 break; 140 case SIGBUS: 141 switch (code) { 142 case BUS_ADRALN: return "BUS_ADRALN"; 143 case BUS_ADRERR: return "BUS_ADRERR"; 144 case BUS_OBJERR: return "BUS_OBJERR"; 145 } 146 break; 147 case SIGFPE: 148 switch (code) { 149 case FPE_INTDIV: return "FPE_INTDIV"; 150 case FPE_INTOVF: return "FPE_INTOVF"; 151 case FPE_FLTDIV: return "FPE_FLTDIV"; 152 case FPE_FLTOVF: return "FPE_FLTOVF"; 153 case FPE_FLTUND: return "FPE_FLTUND"; 154 case FPE_FLTRES: return "FPE_FLTRES"; 155 case FPE_FLTINV: return "FPE_FLTINV"; 156 case FPE_FLTSUB: return "FPE_FLTSUB"; 157 } 158 break; 159 case SIGSEGV: 160 switch (code) { 161 case SEGV_MAPERR: return "SEGV_MAPERR"; 162 case SEGV_ACCERR: return "SEGV_ACCERR"; 163 } 164 break; 165 } 166 return "?"; 167} 168 169void dump_fault_addr(int tfd, int pid, int sig) 170{ 171 siginfo_t si; 172 173 memset(&si, 0, sizeof(si)); 174 if(ptrace(PTRACE_GETSIGINFO, pid, 0, &si)){ 175 _LOG(tfd, false, "cannot get siginfo: %s\n", strerror(errno)); 176 } else if (signal_has_address(sig)) { 177 _LOG(tfd, false, "signal %d (%s), code %d (%s), fault addr %08x\n", 178 sig, get_signame(sig), 179 si.si_code, get_sigcode(sig, si.si_code), 180 si.si_addr); 181 } else { 182 _LOG(tfd, false, "signal %d (%s), code %d (%s), fault addr --------\n", 183 sig, get_signame(sig), si.si_code, get_sigcode(sig, si.si_code)); 184 } 185} 186 187void dump_crash_banner(int tfd, unsigned pid, unsigned tid, int sig) 188{ 189 char data[1024]; 190 char *x = 0; 191 FILE *fp; 192 193 sprintf(data, "/proc/%d/cmdline", pid); 194 fp = fopen(data, "r"); 195 if(fp) { 196 x = fgets(data, 1024, fp); 197 fclose(fp); 198 } 199 200 _LOG(tfd, false, 201 "*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***\n"); 202 dump_build_info(tfd); 203 _LOG(tfd, false, "pid: %d, tid: %d >>> %s <<<\n", 204 pid, tid, x ? x : "UNKNOWN"); 205 206 if(sig) dump_fault_addr(tfd, tid, sig); 207} 208 209static void parse_elf_info(mapinfo *milist, pid_t pid) 210{ 211 mapinfo *mi; 212 for (mi = milist; mi != NULL; mi = mi->next) { 213 if (!mi->isExecutable) 214 continue; 215 216 Elf32_Ehdr ehdr; 217 218 memset(&ehdr, 0, sizeof(Elf32_Ehdr)); 219 /* Read in sizeof(Elf32_Ehdr) worth of data from the beginning of 220 * mapped section. 221 */ 222 get_remote_struct(pid, (void *) (mi->start), &ehdr, 223 sizeof(Elf32_Ehdr)); 224 /* Check if it has the matching magic words */ 225 if (IS_ELF(ehdr)) { 226 Elf32_Phdr phdr; 227 Elf32_Phdr *ptr; 228 int i; 229 230 ptr = (Elf32_Phdr *) (mi->start + ehdr.e_phoff); 231 for (i = 0; i < ehdr.e_phnum; i++) { 232 /* Parse the program header */ 233 get_remote_struct(pid, (char *) (ptr+i), &phdr, 234 sizeof(Elf32_Phdr)); 235#ifdef __arm__ 236 /* Found a EXIDX segment? */ 237 if (phdr.p_type == PT_ARM_EXIDX) { 238 mi->exidx_start = mi->start + phdr.p_offset; 239 mi->exidx_end = mi->exidx_start + phdr.p_filesz; 240 break; 241 } 242#endif 243 } 244 245 /* Try to load symbols from this file */ 246 mi->symbols = symbol_table_create(mi->name); 247 } 248 } 249} 250 251void dump_crash_report(int tfd, unsigned pid, unsigned tid, bool at_fault) 252{ 253 char data[1024]; 254 FILE *fp; 255 mapinfo *milist = 0; 256 unsigned int sp_list[STACK_CONTENT_DEPTH]; 257 int stack_depth; 258#ifdef __arm__ 259 int frame0_pc_sane = 1; 260#endif 261 262 if (!at_fault) { 263 _LOG(tfd, true, 264 "--- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---\n"); 265 _LOG(tfd, true, "pid: %d, tid: %d\n", pid, tid); 266 } 267 268 dump_registers(tfd, tid, at_fault); 269 270 /* Clear stack pointer records */ 271 memset(sp_list, 0, sizeof(sp_list)); 272 273 sprintf(data, "/proc/%d/maps", pid); 274 fp = fopen(data, "r"); 275 if(fp) { 276 while(fgets(data, 1024, fp)) { 277 mapinfo *mi = parse_maps_line(data); 278 if(mi) { 279 mi->next = milist; 280 milist = mi; 281 } 282 } 283 fclose(fp); 284 } 285 286 parse_elf_info(milist, tid); 287 288#if __arm__ 289 /* If stack unwinder fails, use the default solution to dump the stack 290 * content. 291 */ 292 stack_depth = unwind_backtrace_with_ptrace(tfd, tid, milist, sp_list, 293 &frame0_pc_sane, at_fault); 294 295 /* The stack unwinder should at least unwind two levels of stack. If less 296 * level is seen we make sure at lease pc and lr are dumped. 297 */ 298 if (stack_depth < 2) { 299 dump_pc_and_lr(tfd, tid, milist, stack_depth, at_fault); 300 } 301 302 dump_stack_and_code(tfd, tid, milist, stack_depth, sp_list, at_fault); 303#elif __i386__ 304 /* If stack unwinder fails, use the default solution to dump the stack 305 * content. 306 */ 307 stack_depth = unwind_backtrace_with_ptrace_x86(tfd, tid, milist,at_fault); 308#else 309#error "Unsupported architecture" 310#endif 311 312 while(milist) { 313 mapinfo *next = milist->next; 314 symbol_table_free(milist->symbols); 315 free(milist); 316 milist = next; 317 } 318} 319 320#define MAX_TOMBSTONES 10 321 322#define typecheck(x,y) { \ 323 typeof(x) __dummy1; \ 324 typeof(y) __dummy2; \ 325 (void)(&__dummy1 == &__dummy2); } 326 327#define TOMBSTONE_DIR "/data/tombstones" 328 329/* 330 * find_and_open_tombstone - find an available tombstone slot, if any, of the 331 * form tombstone_XX where XX is 00 to MAX_TOMBSTONES-1, inclusive. If no 332 * file is available, we reuse the least-recently-modified file. 333 */ 334static int find_and_open_tombstone(void) 335{ 336 unsigned long mtime = ULONG_MAX; 337 struct stat sb; 338 char path[128]; 339 int fd, i, oldest = 0; 340 341 /* 342 * XXX: Our stat.st_mtime isn't time_t. If it changes, as it probably ought 343 * to, our logic breaks. This check will generate a warning if that happens. 344 */ 345 typecheck(mtime, sb.st_mtime); 346 347 /* 348 * In a single wolf-like pass, find an available slot and, in case none 349 * exist, find and record the least-recently-modified file. 350 */ 351 for (i = 0; i < MAX_TOMBSTONES; i++) { 352 snprintf(path, sizeof(path), TOMBSTONE_DIR"/tombstone_%02d", i); 353 354 if (!stat(path, &sb)) { 355 if (sb.st_mtime < mtime) { 356 oldest = i; 357 mtime = sb.st_mtime; 358 } 359 continue; 360 } 361 if (errno != ENOENT) 362 continue; 363 364 fd = open(path, O_CREAT | O_EXCL | O_WRONLY, 0600); 365 if (fd < 0) 366 continue; /* raced ? */ 367 368 fchown(fd, AID_SYSTEM, AID_SYSTEM); 369 return fd; 370 } 371 372 /* we didn't find an available file, so we clobber the oldest one */ 373 snprintf(path, sizeof(path), TOMBSTONE_DIR"/tombstone_%02d", oldest); 374 fd = open(path, O_CREAT | O_TRUNC | O_WRONLY, 0600); 375 fchown(fd, AID_SYSTEM, AID_SYSTEM); 376 377 return fd; 378} 379 380/* Return true if some thread is not detached cleanly */ 381static bool dump_sibling_thread_report(int tfd, unsigned pid, unsigned tid) 382{ 383 char task_path[1024]; 384 385 sprintf(task_path, "/proc/%d/task", pid); 386 DIR *d; 387 struct dirent *de; 388 int need_cleanup = 0; 389 390 d = opendir(task_path); 391 /* Bail early if cannot open the task directory */ 392 if (d == NULL) { 393 XLOG("Cannot open /proc/%d/task\n", pid); 394 return false; 395 } 396 while ((de = readdir(d)) != NULL) { 397 unsigned new_tid; 398 /* Ignore "." and ".." */ 399 if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..")) 400 continue; 401 new_tid = atoi(de->d_name); 402 /* The main thread at fault has been handled individually */ 403 if (new_tid == tid) 404 continue; 405 406 /* Skip this thread if cannot ptrace it */ 407 if (ptrace(PTRACE_ATTACH, new_tid, 0, 0) < 0) 408 continue; 409 410 dump_crash_report(tfd, pid, new_tid, false); 411 need_cleanup |= ptrace(PTRACE_DETACH, new_tid, 0, 0); 412 } 413 closedir(d); 414 return need_cleanup != 0; 415} 416 417/* 418 * Reads the contents of the specified log device, filters out the entries 419 * that don't match the specified pid, and writes them to the tombstone file. 420 */ 421static void dump_log_file(int tfd, unsigned pid, const char* filename) 422{ 423 int logfd = open(filename, O_RDONLY | O_NONBLOCK); 424 if (logfd < 0) { 425 XLOG("Unable to open %s: %s\n", filename, strerror(errno)); 426 return; 427 } 428 _LOG(tfd, true, "--------- log %s\n", filename); 429 430 union { 431 unsigned char buf[LOGGER_ENTRY_MAX_LEN + 1]; 432 struct logger_entry entry; 433 } log_entry; 434 435 while (true) { 436 ssize_t actual = read(logfd, log_entry.buf, LOGGER_ENTRY_MAX_LEN); 437 if (actual < 0) { 438 if (errno == EINTR) { 439 /* interrupted by signal, retry */ 440 continue; 441 } else if (errno == EAGAIN) { 442 /* non-blocking EOF; we're done */ 443 break; 444 } else { 445 _LOG(tfd, true, "Error while reading log: %s\n", 446 strerror(errno)); 447 break; 448 } 449 } else if (actual == 0) { 450 _LOG(tfd, true, "Got zero bytes while reading log: %s\n", 451 strerror(errno)); 452 break; 453 } 454 455 /* 456 * NOTE: if you XLOG something here, this will spin forever, 457 * because you will be writing as fast as you're reading. Any 458 * high-frequency debug diagnostics should just be written to 459 * the tombstone file. 460 */ 461 462 struct logger_entry* entry = &log_entry.entry; 463 464 if (entry->pid != (int32_t) pid) { 465 /* wrong pid, ignore */ 466 continue; 467 } 468 469 /* 470 * Msg format is: <priority:1><tag:N>\0<message:N>\0 471 * 472 * We want to display it in the same format as "logcat -v threadtime" 473 * (although in this case the pid is redundant). 474 * 475 * TODO: scan for line breaks ('\n') and display each text line 476 * on a separate line, prefixed with the header, like logcat does. 477 */ 478 static const char* kPrioChars = "!.VDIWEFS"; 479 unsigned char prio = entry->msg[0]; 480 const char* tag = entry->msg + 1; 481 const char* msg = tag + strlen(tag) + 1; 482 483 log_entry.entry.msg[entry->len] = '\0'; 484 485 char timeBuf[32]; 486 time_t sec = (time_t) entry->sec; 487 struct tm tmBuf; 488 struct tm* ptm; 489 ptm = localtime_r(&sec, &tmBuf); 490 strftime(timeBuf, sizeof(timeBuf), "%m-%d %H:%M:%S", ptm); 491 492 _LOG(tfd, true, "%s.%03ld %5d %5d %c %-8s: %s\n", 493 timeBuf, entry->nsec / 1000000, 494 entry->pid, entry->tid, 495 (prio < strlen(kPrioChars) ? kPrioChars[prio] : '?'), 496 tag, msg); 497 } 498 499 close(logfd); 500} 501 502/* 503 * Dumps the logs generated by the specified pid to the tombstone, from both 504 * "system" and "main" log devices. Ideally we'd interleave the output. 505 */ 506static void dump_logs(int tfd, unsigned pid) 507{ 508 dump_log_file(tfd, pid, "/dev/log/system"); 509 dump_log_file(tfd, pid, "/dev/log/main"); 510} 511 512/* Return true if some thread is not detached cleanly */ 513static bool engrave_tombstone(unsigned pid, unsigned tid, int debug_uid, 514 int signal) 515{ 516 int fd; 517 bool need_cleanup = false; 518 519 mkdir(TOMBSTONE_DIR, 0755); 520 chown(TOMBSTONE_DIR, AID_SYSTEM, AID_SYSTEM); 521 522 fd = find_and_open_tombstone(); 523 if (fd < 0) 524 return need_cleanup; 525 526 dump_crash_banner(fd, pid, tid, signal); 527 dump_crash_report(fd, pid, tid, true); 528 /* 529 * If the user has requested to attach gdb, don't collect the per-thread 530 * information as it increases the chance to lose track of the process. 531 */ 532 if ((signed)pid > debug_uid) { 533 need_cleanup = dump_sibling_thread_report(fd, pid, tid); 534 } 535 536 /* don't copy log to tombstone unless this is a dev device */ 537 char value[PROPERTY_VALUE_MAX]; 538 property_get("ro.debuggable", value, "0"); 539 if (value[0] == '1') { 540 dump_logs(fd, pid); 541 } 542 543 close(fd); 544 return need_cleanup; 545} 546 547static int 548write_string(const char* file, const char* string) 549{ 550 int len; 551 int fd; 552 ssize_t amt; 553 fd = open(file, O_RDWR); 554 len = strlen(string); 555 if (fd < 0) 556 return -errno; 557 amt = write(fd, string, len); 558 close(fd); 559 return amt >= 0 ? 0 : -errno; 560} 561 562static 563void init_debug_led(void) 564{ 565 // trout leds 566 write_string("/sys/class/leds/red/brightness", "0"); 567 write_string("/sys/class/leds/green/brightness", "0"); 568 write_string("/sys/class/leds/blue/brightness", "0"); 569 write_string("/sys/class/leds/red/device/blink", "0"); 570 // sardine leds 571 write_string("/sys/class/leds/left/cadence", "0,0"); 572} 573 574static 575void enable_debug_led(void) 576{ 577 // trout leds 578 write_string("/sys/class/leds/red/brightness", "255"); 579 // sardine leds 580 write_string("/sys/class/leds/left/cadence", "1,0"); 581} 582 583static 584void disable_debug_led(void) 585{ 586 // trout leds 587 write_string("/sys/class/leds/red/brightness", "0"); 588 // sardine leds 589 write_string("/sys/class/leds/left/cadence", "0,0"); 590} 591 592extern int init_getevent(); 593extern void uninit_getevent(); 594extern int get_event(struct input_event* event, int timeout); 595 596static void wait_for_user_action(unsigned tid, struct ucred* cr) 597{ 598 (void)tid; 599 /* First log a helpful message */ 600 LOG( "********************************************************\n" 601 "* Process %d has been suspended while crashing. To\n" 602 "* attach gdbserver for a gdb connection on port 5039:\n" 603 "*\n" 604 "* adb shell gdbserver :5039 --attach %d &\n" 605 "*\n" 606 "* Press HOME key to let the process continue crashing.\n" 607 "********************************************************\n", 608 cr->pid, cr->pid); 609 610 /* wait for HOME key (TODO: something useful for devices w/o HOME key) */ 611 if (init_getevent() == 0) { 612 int ms = 1200 / 10; 613 int dit = 1; 614 int dah = 3*dit; 615 int _ = -dit; 616 int ___ = 3*_; 617 int _______ = 7*_; 618 const signed char codes[] = { 619 dit,_,dit,_,dit,___,dah,_,dah,_,dah,___,dit,_,dit,_,dit,_______ 620 }; 621 size_t s = 0; 622 struct input_event e; 623 int home = 0; 624 init_debug_led(); 625 enable_debug_led(); 626 do { 627 int timeout = abs((int)(codes[s])) * ms; 628 int res = get_event(&e, timeout); 629 if (res == 0) { 630 if (e.type==EV_KEY && e.code==KEY_HOME && e.value==0) 631 home = 1; 632 } else if (res == 1) { 633 if (++s >= sizeof(codes)/sizeof(*codes)) 634 s = 0; 635 if (codes[s] > 0) { 636 enable_debug_led(); 637 } else { 638 disable_debug_led(); 639 } 640 } 641 } while (!home); 642 uninit_getevent(); 643 } 644 645 /* don't forget to turn debug led off */ 646 disable_debug_led(); 647 648 /* close filedescriptor */ 649 LOG("debuggerd resuming process %d", cr->pid); 650 } 651 652static void handle_crashing_process(int fd) 653{ 654 char buf[64]; 655 struct stat s; 656 unsigned tid; 657 struct ucred cr; 658 int n, len, status; 659 int tid_attach_status = -1; 660 unsigned retry = 30; 661 bool need_cleanup = false; 662 663 char value[PROPERTY_VALUE_MAX]; 664 property_get("debug.db.uid", value, "-1"); 665 int debug_uid = atoi(value); 666 667 XLOG("handle_crashing_process(%d)\n", fd); 668 669 len = sizeof(cr); 670 n = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &cr, &len); 671 if(n != 0) { 672 LOG("cannot get credentials\n"); 673 goto done; 674 } 675 676 XLOG("reading tid\n"); 677 fcntl(fd, F_SETFL, O_NONBLOCK); 678 while((n = read(fd, &tid, sizeof(unsigned))) != sizeof(unsigned)) { 679 if(errno == EINTR) continue; 680 if(errno == EWOULDBLOCK) { 681 if(retry-- > 0) { 682 usleep(100 * 1000); 683 continue; 684 } 685 LOG("timed out reading tid\n"); 686 goto done; 687 } 688 LOG("read failure? %s\n", strerror(errno)); 689 goto done; 690 } 691 692 snprintf(buf, sizeof buf, "/proc/%d/task/%d", cr.pid, tid); 693 if(stat(buf, &s)) { 694 LOG("tid %d does not exist in pid %d. ignoring debug request\n", 695 tid, cr.pid); 696 close(fd); 697 return; 698 } 699 700 XLOG("BOOM: pid=%d uid=%d gid=%d tid=%d\n", cr.pid, cr.uid, cr.gid, tid); 701 702 /* Note that at this point, the target thread's signal handler 703 * is blocked in a read() call. This gives us the time to PTRACE_ATTACH 704 * to it before it has a chance to really fault. 705 * 706 * After the attach, the thread is stopped, and we write to the file 707 * descriptor to ensure that it will run as soon as we call PTRACE_CONT 708 * below. See details in bionic/libc/linker/debugger.c, in function 709 * debugger_signal_handler(). 710 */ 711 tid_attach_status = ptrace(PTRACE_ATTACH, tid, 0, 0); 712 int ptrace_error = errno; 713 714 if (TEMP_FAILURE_RETRY(write(fd, &tid, 1)) != 1) { 715 XLOG("failed responding to client: %s\n", 716 strerror(errno)); 717 goto done; 718 } 719 720 if(tid_attach_status < 0) { 721 LOG("ptrace attach failed: %s\n", strerror(ptrace_error)); 722 goto done; 723 } 724 725 close(fd); 726 fd = -1; 727 728 const int sleep_time_usec = 200000; /* 0.2 seconds */ 729 const int max_total_sleep_usec = 3000000; /* 3 seconds */ 730 int loop_limit = max_total_sleep_usec / sleep_time_usec; 731 for(;;) { 732 if (loop_limit-- == 0) { 733 LOG("timed out waiting for pid=%d tid=%d uid=%d to die\n", 734 cr.pid, tid, cr.uid); 735 goto done; 736 } 737 n = waitpid(tid, &status, __WALL | WNOHANG); 738 739 if (n == 0) { 740 /* not ready yet */ 741 XLOG("not ready yet\n"); 742 usleep(sleep_time_usec); 743 continue; 744 } 745 746 if(n < 0) { 747 if(errno == EAGAIN) continue; 748 LOG("waitpid failed: %s\n", strerror(errno)); 749 goto done; 750 } 751 752 XLOG("waitpid: n=%d status=%08x\n", n, status); 753 754 if(WIFSTOPPED(status)){ 755 n = WSTOPSIG(status); 756 switch(n) { 757 case SIGSTOP: 758 XLOG("stopped -- continuing\n"); 759 n = ptrace(PTRACE_CONT, tid, 0, 0); 760 if(n) { 761 LOG("ptrace failed: %s\n", strerror(errno)); 762 goto done; 763 } 764 continue; 765 766 case SIGILL: 767 case SIGABRT: 768 case SIGBUS: 769 case SIGFPE: 770 case SIGSEGV: 771 case SIGSTKFLT: { 772 XLOG("stopped -- fatal signal\n"); 773 need_cleanup = engrave_tombstone(cr.pid, tid, debug_uid, n); 774 kill(tid, SIGSTOP); 775 goto done; 776 } 777 778 default: 779 XLOG("stopped -- unexpected signal\n"); 780 goto done; 781 } 782 } else { 783 XLOG("unexpected waitpid response\n"); 784 goto done; 785 } 786 } 787 788done: 789 XLOG("detaching\n"); 790 791 /* stop the process so we can debug */ 792 kill(cr.pid, SIGSTOP); 793 794 /* 795 * If a thread has been attached by ptrace, make sure it is detached 796 * successfully otherwise we will get a zombie. 797 */ 798 if (tid_attach_status == 0) { 799 int detach_status; 800 /* detach so we can attach gdbserver */ 801 detach_status = ptrace(PTRACE_DETACH, tid, 0, 0); 802 need_cleanup |= (detach_status != 0); 803 } 804 805 /* 806 * if debug.db.uid is set, its value indicates if we should wait 807 * for user action for the crashing process. 808 * in this case, we log a message and turn the debug LED on 809 * waiting for a gdb connection (for instance) 810 */ 811 812 if ((signed)cr.uid <= debug_uid) { 813 wait_for_user_action(tid, &cr); 814 } 815 816 /* resume stopped process (so it can crash in peace) */ 817 kill(cr.pid, SIGCONT); 818 819 if (need_cleanup) { 820 LOG("debuggerd committing suicide to free the zombie!\n"); 821 kill(getpid(), SIGKILL); 822 } 823 824 if(fd != -1) close(fd); 825} 826 827 828int main() 829{ 830 int s; 831 struct sigaction act; 832 int logsocket = -1; 833 834 /* 835 * debuggerd crashes can't be reported to debuggerd. Reset all of the 836 * crash handlers. 837 */ 838 signal(SIGILL, SIG_DFL); 839 signal(SIGABRT, SIG_DFL); 840 signal(SIGBUS, SIG_DFL); 841 signal(SIGFPE, SIG_DFL); 842 signal(SIGSEGV, SIG_DFL); 843 signal(SIGSTKFLT, SIG_DFL); 844 signal(SIGPIPE, SIG_DFL); 845 846 logsocket = socket_local_client("logd", 847 ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_DGRAM); 848 if(logsocket < 0) { 849 logsocket = -1; 850 } else { 851 fcntl(logsocket, F_SETFD, FD_CLOEXEC); 852 } 853 854 act.sa_handler = SIG_DFL; 855 sigemptyset(&act.sa_mask); 856 sigaddset(&act.sa_mask,SIGCHLD); 857 act.sa_flags = SA_NOCLDWAIT; 858 sigaction(SIGCHLD, &act, 0); 859 860 s = socket_local_server("android:debuggerd", 861 ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM); 862 if(s < 0) return -1; 863 fcntl(s, F_SETFD, FD_CLOEXEC); 864 865 LOG("debuggerd: " __DATE__ " " __TIME__ "\n"); 866 867 for(;;) { 868 struct sockaddr addr; 869 socklen_t alen; 870 int fd; 871 872 alen = sizeof(addr); 873 XLOG("waiting for connection\n"); 874 fd = accept(s, &addr, &alen); 875 if(fd < 0) { 876 XLOG("accept failed: %s\n", strerror(errno)); 877 continue; 878 } 879 880 fcntl(fd, F_SETFD, FD_CLOEXEC); 881 882 handle_crashing_process(fd); 883 } 884 return 0; 885} 886