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