debuggerd.c revision 9524e4158fbb988b6a5e4f5be68ee10b7e4dd6d8
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#include <sys/poll.h>
32
33#include <cutils/sockets.h>
34#include <cutils/logd.h>
35#include <cutils/logger.h>
36#include <cutils/properties.h>
37
38#include <corkscrew/backtrace.h>
39
40#include <linux/input.h>
41
42#include <private/android_filesystem_config.h>
43
44#include "getevent.h"
45#include "machine.h"
46#include "utility.h"
47
48#define ANDROID_LOG_INFO 4
49
50static void dump_build_info(int tfd)
51{
52    char fingerprint[PROPERTY_VALUE_MAX];
53
54    property_get("ro.build.fingerprint", fingerprint, "unknown");
55
56    _LOG(tfd, false, "Build fingerprint: '%s'\n", fingerprint);
57}
58
59static const char *get_signame(int sig)
60{
61    switch(sig) {
62    case SIGILL:     return "SIGILL";
63    case SIGABRT:    return "SIGABRT";
64    case SIGBUS:     return "SIGBUS";
65    case SIGFPE:     return "SIGFPE";
66    case SIGSEGV:    return "SIGSEGV";
67    case SIGSTKFLT:  return "SIGSTKFLT";
68    case SIGSTOP:    return "SIGSTOP";
69    default:         return "?";
70    }
71}
72
73static const char *get_sigcode(int signo, int code)
74{
75    switch (signo) {
76    case SIGILL:
77        switch (code) {
78        case ILL_ILLOPC: return "ILL_ILLOPC";
79        case ILL_ILLOPN: return "ILL_ILLOPN";
80        case ILL_ILLADR: return "ILL_ILLADR";
81        case ILL_ILLTRP: return "ILL_ILLTRP";
82        case ILL_PRVOPC: return "ILL_PRVOPC";
83        case ILL_PRVREG: return "ILL_PRVREG";
84        case ILL_COPROC: return "ILL_COPROC";
85        case ILL_BADSTK: return "ILL_BADSTK";
86        }
87        break;
88    case SIGBUS:
89        switch (code) {
90        case BUS_ADRALN: return "BUS_ADRALN";
91        case BUS_ADRERR: return "BUS_ADRERR";
92        case BUS_OBJERR: return "BUS_OBJERR";
93        }
94        break;
95    case SIGFPE:
96        switch (code) {
97        case FPE_INTDIV: return "FPE_INTDIV";
98        case FPE_INTOVF: return "FPE_INTOVF";
99        case FPE_FLTDIV: return "FPE_FLTDIV";
100        case FPE_FLTOVF: return "FPE_FLTOVF";
101        case FPE_FLTUND: return "FPE_FLTUND";
102        case FPE_FLTRES: return "FPE_FLTRES";
103        case FPE_FLTINV: return "FPE_FLTINV";
104        case FPE_FLTSUB: return "FPE_FLTSUB";
105        }
106        break;
107    case SIGSEGV:
108        switch (code) {
109        case SEGV_MAPERR: return "SEGV_MAPERR";
110        case SEGV_ACCERR: return "SEGV_ACCERR";
111        }
112        break;
113    }
114    return "?";
115}
116
117static void dump_fault_addr(int tfd, pid_t pid, int sig)
118{
119    siginfo_t si;
120
121    memset(&si, 0, sizeof(si));
122    if(ptrace(PTRACE_GETSIGINFO, pid, 0, &si)){
123        _LOG(tfd, false, "cannot get siginfo: %s\n", strerror(errno));
124    } else if (signal_has_address(sig)) {
125        _LOG(tfd, false, "signal %d (%s), code %d (%s), fault addr %08x\n",
126             sig, get_signame(sig),
127             si.si_code, get_sigcode(sig, si.si_code),
128             (uintptr_t) si.si_addr);
129    } else {
130        _LOG(tfd, false, "signal %d (%s), code %d (%s), fault addr --------\n",
131             sig, get_signame(sig), si.si_code, get_sigcode(sig, si.si_code));
132    }
133}
134
135static void dump_crash_banner(int tfd, pid_t pid, pid_t tid, int sig)
136{
137    char data[1024];
138    char *x = 0;
139    FILE *fp;
140
141    sprintf(data, "/proc/%d/cmdline", pid);
142    fp = fopen(data, "r");
143    if(fp) {
144        x = fgets(data, 1024, fp);
145        fclose(fp);
146    }
147
148    _LOG(tfd, false,
149            "*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***\n");
150    dump_build_info(tfd);
151    _LOG(tfd, false, "pid: %d, tid: %d  >>> %s <<<\n",
152         pid, tid, x ? x : "UNKNOWN");
153
154    if(sig) {
155        dump_fault_addr(tfd, tid, sig);
156    }
157}
158
159/* Return true if some thread is not detached cleanly */
160static bool dump_sibling_thread_report(ptrace_context_t* context,
161        int tfd, pid_t pid, pid_t tid) {
162    char task_path[64];
163    snprintf(task_path, sizeof(task_path), "/proc/%d/task", pid);
164
165    DIR* d = opendir(task_path);
166    /* Bail early if cannot open the task directory */
167    if (d == NULL) {
168        XLOG("Cannot open /proc/%d/task\n", pid);
169        return false;
170    }
171
172    bool detach_failed = false;
173    struct dirent *de;
174    while ((de = readdir(d)) != NULL) {
175        pid_t new_tid;
176        /* Ignore "." and ".." */
177        if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..")) {
178            continue;
179        }
180
181        new_tid = atoi(de->d_name);
182        /* The main thread at fault has been handled individually */
183        if (new_tid == tid) {
184            continue;
185        }
186
187        /* Skip this thread if cannot ptrace it */
188        if (ptrace(PTRACE_ATTACH, new_tid, 0, 0) < 0) {
189            continue;
190        }
191
192        _LOG(tfd, true, "--- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---\n");
193        _LOG(tfd, true, "pid: %d, tid: %d\n", pid, new_tid);
194
195        dump_thread(context, tfd, new_tid, false);
196
197        if (ptrace(PTRACE_DETACH, new_tid, 0, 0) != 0) {
198            LOG("ptrace detach from %d failed: %s\n", new_tid, strerror(errno));
199            detach_failed = true;
200        }
201    }
202
203    closedir(d);
204    return detach_failed;
205}
206
207/*
208 * Reads the contents of the specified log device, filters out the entries
209 * that don't match the specified pid, and writes them to the tombstone file.
210 *
211 * If "tailOnly" is set, we only print the last few lines.
212 */
213static void dump_log_file(int tfd, pid_t pid, const char* filename,
214    bool tailOnly)
215{
216    bool first = true;
217
218    /* circular buffer, for "tailOnly" mode */
219    const int kShortLogMaxLines = 5;
220    const int kShortLogLineLen = 256;
221    char shortLog[kShortLogMaxLines][kShortLogLineLen];
222    int shortLogCount = 0;
223    int shortLogNext = 0;
224
225    int logfd = open(filename, O_RDONLY | O_NONBLOCK);
226    if (logfd < 0) {
227        XLOG("Unable to open %s: %s\n", filename, strerror(errno));
228        return;
229    }
230
231    union {
232        unsigned char buf[LOGGER_ENTRY_MAX_LEN + 1];
233        struct logger_entry entry;
234    } log_entry;
235
236    while (true) {
237        ssize_t actual = read(logfd, log_entry.buf, LOGGER_ENTRY_MAX_LEN);
238        if (actual < 0) {
239            if (errno == EINTR) {
240                /* interrupted by signal, retry */
241                continue;
242            } else if (errno == EAGAIN) {
243                /* non-blocking EOF; we're done */
244                break;
245            } else {
246                _LOG(tfd, true, "Error while reading log: %s\n",
247                    strerror(errno));
248                break;
249            }
250        } else if (actual == 0) {
251            _LOG(tfd, true, "Got zero bytes while reading log: %s\n",
252                strerror(errno));
253            break;
254        }
255
256        /*
257         * NOTE: if you XLOG something here, this will spin forever,
258         * because you will be writing as fast as you're reading.  Any
259         * high-frequency debug diagnostics should just be written to
260         * the tombstone file.
261         */
262
263        struct logger_entry* entry = &log_entry.entry;
264
265        if (entry->pid != (int32_t) pid) {
266            /* wrong pid, ignore */
267            continue;
268        }
269
270        if (first) {
271            _LOG(tfd, true, "--------- %slog %s\n",
272                tailOnly ? "tail end of " : "", filename);
273            first = false;
274        }
275
276        /*
277         * Msg format is: <priority:1><tag:N>\0<message:N>\0
278         *
279         * We want to display it in the same format as "logcat -v threadtime"
280         * (although in this case the pid is redundant).
281         *
282         * TODO: scan for line breaks ('\n') and display each text line
283         * on a separate line, prefixed with the header, like logcat does.
284         */
285        static const char* kPrioChars = "!.VDIWEFS";
286        unsigned char prio = entry->msg[0];
287        char* tag = entry->msg + 1;
288        char* msg = tag + strlen(tag) + 1;
289
290        /* consume any trailing newlines */
291        char* eatnl = msg + strlen(msg) - 1;
292        while (eatnl >= msg && *eatnl == '\n') {
293            *eatnl-- = '\0';
294        }
295
296        char prioChar = (prio < strlen(kPrioChars) ? kPrioChars[prio] : '?');
297
298        char timeBuf[32];
299        time_t sec = (time_t) entry->sec;
300        struct tm tmBuf;
301        struct tm* ptm;
302        ptm = localtime_r(&sec, &tmBuf);
303        strftime(timeBuf, sizeof(timeBuf), "%m-%d %H:%M:%S", ptm);
304
305        if (tailOnly) {
306            snprintf(shortLog[shortLogNext], kShortLogLineLen,
307                "%s.%03d %5d %5d %c %-8s: %s",
308                timeBuf, entry->nsec / 1000000, entry->pid, entry->tid,
309                prioChar, tag, msg);
310            shortLogNext = (shortLogNext + 1) % kShortLogMaxLines;
311            shortLogCount++;
312        } else {
313            _LOG(tfd, true, "%s.%03d %5d %5d %c %-8s: %s\n",
314                timeBuf, entry->nsec / 1000000, entry->pid, entry->tid,
315                prioChar, tag, msg);
316        }
317    }
318
319    if (tailOnly) {
320        int i;
321
322        /*
323         * If we filled the buffer, we want to start at "next", which has
324         * the oldest entry.  If we didn't, we want to start at zero.
325         */
326        if (shortLogCount < kShortLogMaxLines) {
327            shortLogNext = 0;
328        } else {
329            shortLogCount = kShortLogMaxLines;  /* cap at window size */
330        }
331
332        for (i = 0; i < shortLogCount; i++) {
333            _LOG(tfd, true, "%s\n", shortLog[shortLogNext]);
334            shortLogNext = (shortLogNext + 1) % kShortLogMaxLines;
335        }
336    }
337
338    close(logfd);
339}
340
341/*
342 * Dumps the logs generated by the specified pid to the tombstone, from both
343 * "system" and "main" log devices.  Ideally we'd interleave the output.
344 */
345static void dump_logs(int tfd, pid_t pid, bool tailOnly)
346{
347    dump_log_file(tfd, pid, "/dev/log/system", tailOnly);
348    dump_log_file(tfd, pid, "/dev/log/main", tailOnly);
349}
350
351/*
352 * Dumps all information about the specified pid to the tombstone.
353 */
354static bool dump_crash(int tfd, pid_t pid, pid_t tid, int signal,
355        bool dump_sibling_threads)
356{
357    /* don't copy log messages to tombstone unless this is a dev device */
358    char value[PROPERTY_VALUE_MAX];
359    property_get("ro.debuggable", value, "0");
360    bool wantLogs = (value[0] == '1');
361
362    dump_crash_banner(tfd, pid, tid, signal);
363
364    ptrace_context_t* context = load_ptrace_context(pid);
365
366    dump_thread(context, tfd, tid, true);
367
368    if (wantLogs) {
369        dump_logs(tfd, pid, true);
370    }
371
372    bool detach_failed = false;
373    if (dump_sibling_threads) {
374        detach_failed = dump_sibling_thread_report(context, tfd, pid, tid);
375    }
376
377    free_ptrace_context(context);
378
379    if (wantLogs) {
380        dump_logs(tfd, pid, false);
381    }
382    return detach_failed;
383}
384
385#define MAX_TOMBSTONES	10
386
387#define typecheck(x,y) {    \
388    typeof(x) __dummy1;     \
389    typeof(y) __dummy2;     \
390    (void)(&__dummy1 == &__dummy2); }
391
392#define TOMBSTONE_DIR	"/data/tombstones"
393
394/*
395 * find_and_open_tombstone - find an available tombstone slot, if any, of the
396 * form tombstone_XX where XX is 00 to MAX_TOMBSTONES-1, inclusive. If no
397 * file is available, we reuse the least-recently-modified file.
398 */
399static int find_and_open_tombstone(void)
400{
401    unsigned long mtime = ULONG_MAX;
402    struct stat sb;
403    char path[128];
404    int fd, i, oldest = 0;
405
406    /*
407     * XXX: Our stat.st_mtime isn't time_t. If it changes, as it probably ought
408     * to, our logic breaks. This check will generate a warning if that happens.
409     */
410    typecheck(mtime, sb.st_mtime);
411
412    /*
413     * In a single wolf-like pass, find an available slot and, in case none
414     * exist, find and record the least-recently-modified file.
415     */
416    for (i = 0; i < MAX_TOMBSTONES; i++) {
417        snprintf(path, sizeof(path), TOMBSTONE_DIR"/tombstone_%02d", i);
418
419        if (!stat(path, &sb)) {
420            if (sb.st_mtime < mtime) {
421                oldest = i;
422                mtime = sb.st_mtime;
423            }
424            continue;
425        }
426        if (errno != ENOENT)
427            continue;
428
429        fd = open(path, O_CREAT | O_EXCL | O_WRONLY, 0600);
430        if (fd < 0)
431            continue;	/* raced ? */
432
433        fchown(fd, AID_SYSTEM, AID_SYSTEM);
434        return fd;
435    }
436
437    /* we didn't find an available file, so we clobber the oldest one */
438    snprintf(path, sizeof(path), TOMBSTONE_DIR"/tombstone_%02d", oldest);
439    fd = open(path, O_CREAT | O_TRUNC | O_WRONLY, 0600);
440    fchown(fd, AID_SYSTEM, AID_SYSTEM);
441
442    return fd;
443}
444
445/* Return true if some thread is not detached cleanly */
446static bool engrave_tombstone(pid_t pid, pid_t tid, int signal,
447        bool dump_sibling_threads)
448{
449    mkdir(TOMBSTONE_DIR, 0755);
450    chown(TOMBSTONE_DIR, AID_SYSTEM, AID_SYSTEM);
451
452    int fd = find_and_open_tombstone();
453    if (fd < 0) {
454        return false;
455    }
456
457    bool detach_failed = dump_crash(fd, pid, tid, signal, dump_sibling_threads);
458
459    close(fd);
460    return detach_failed;
461}
462
463static int
464write_string(const char* file, const char* string)
465{
466    int len;
467    int fd;
468    ssize_t amt;
469    fd = open(file, O_RDWR);
470    len = strlen(string);
471    if (fd < 0)
472        return -errno;
473    amt = write(fd, string, len);
474    close(fd);
475    return amt >= 0 ? 0 : -errno;
476}
477
478static
479void init_debug_led(void)
480{
481    // trout leds
482    write_string("/sys/class/leds/red/brightness", "0");
483    write_string("/sys/class/leds/green/brightness", "0");
484    write_string("/sys/class/leds/blue/brightness", "0");
485    write_string("/sys/class/leds/red/device/blink", "0");
486    // sardine leds
487    write_string("/sys/class/leds/left/cadence", "0,0");
488}
489
490static
491void enable_debug_led(void)
492{
493    // trout leds
494    write_string("/sys/class/leds/red/brightness", "255");
495    // sardine leds
496    write_string("/sys/class/leds/left/cadence", "1,0");
497}
498
499static
500void disable_debug_led(void)
501{
502    // trout leds
503    write_string("/sys/class/leds/red/brightness", "0");
504    // sardine leds
505    write_string("/sys/class/leds/left/cadence", "0,0");
506}
507
508static void wait_for_user_action(pid_t pid) {
509    /* First log a helpful message */
510    LOG(    "********************************************************\n"
511            "* Process %d has been suspended while crashing.  To\n"
512            "* attach gdbserver for a gdb connection on port 5039\n"
513            "* and start gdbclient:\n"
514            "*\n"
515            "*     gdbclient app_process :5039 %d\n"
516            "*\n"
517            "* Wait for gdb to start, then press HOME or VOLUME DOWN key\n"
518            "* to let the process continue crashing.\n"
519            "********************************************************\n",
520            pid, pid);
521
522    /* wait for HOME or VOLUME DOWN key */
523    if (init_getevent() == 0) {
524        int ms = 1200 / 10;
525        int dit = 1;
526        int dah = 3*dit;
527        int _       = -dit;
528        int ___     = 3*_;
529        int _______ = 7*_;
530        const signed char codes[] = {
531           dit,_,dit,_,dit,___,dah,_,dah,_,dah,___,dit,_,dit,_,dit,_______
532        };
533        size_t s = 0;
534        struct input_event e;
535        bool done = false;
536        init_debug_led();
537        enable_debug_led();
538        do {
539            int timeout = abs((int)(codes[s])) * ms;
540            int res = get_event(&e, timeout);
541            if (res == 0) {
542                if (e.type == EV_KEY
543                        && (e.code == KEY_HOME || e.code == KEY_VOLUMEDOWN)
544                        && e.value == 0) {
545                    done = true;
546                }
547            } else if (res == 1) {
548                if (++s >= sizeof(codes)/sizeof(*codes))
549                    s = 0;
550                if (codes[s] > 0) {
551                    enable_debug_led();
552                } else {
553                    disable_debug_led();
554                }
555            }
556        } while (!done);
557        uninit_getevent();
558    }
559
560    /* don't forget to turn debug led off */
561    disable_debug_led();
562    LOG("debuggerd resuming process %d", pid);
563}
564
565static int get_process_info(pid_t tid, pid_t* out_pid, uid_t* out_uid, uid_t* out_gid) {
566    char path[64];
567    snprintf(path, sizeof(path), "/proc/%d/status", tid);
568
569    FILE* fp = fopen(path, "r");
570    if (!fp) {
571        return -1;
572    }
573
574    int fields = 0;
575    char line[1024];
576    while (fgets(line, sizeof(line), fp)) {
577        size_t len = strlen(line);
578        if (len > 6 && !memcmp(line, "Tgid:\t", 6)) {
579            *out_pid = atoi(line + 6);
580            fields |= 1;
581        } else if (len > 5 && !memcmp(line, "Uid:\t", 5)) {
582            *out_uid = atoi(line + 5);
583            fields |= 2;
584        } else if (len > 5 && !memcmp(line, "Gid:\t", 5)) {
585            *out_gid = atoi(line + 5);
586            fields |= 4;
587        }
588    }
589    fclose(fp);
590    return fields == 7 ? 0 : -1;
591}
592
593static int wait_for_signal(pid_t tid, int* total_sleep_time_usec) {
594    const int sleep_time_usec = 200000;         /* 0.2 seconds */
595    const int max_total_sleep_usec = 3000000;   /* 3 seconds */
596    for (;;) {
597        int status;
598        pid_t n = waitpid(tid, &status, __WALL | WNOHANG);
599        if (n < 0) {
600            if(errno == EAGAIN) continue;
601            LOG("waitpid failed: %s\n", strerror(errno));
602            return -1;
603        } else if (n > 0) {
604            XLOG("waitpid: n=%d status=%08x\n", n, status);
605            if (WIFSTOPPED(status)) {
606                return WSTOPSIG(status);
607            } else {
608                LOG("unexpected waitpid response: n=%d, status=%08x\n", n, status);
609                return -1;
610            }
611        }
612
613        if (*total_sleep_time_usec > max_total_sleep_usec) {
614            LOG("timed out waiting for tid=%d to die\n", tid);
615            return -1;
616        }
617
618        /* not ready yet */
619        XLOG("not ready yet\n");
620        usleep(sleep_time_usec);
621        *total_sleep_time_usec += sleep_time_usec;
622    }
623}
624
625enum {
626    REQUEST_TYPE_CRASH,
627    REQUEST_TYPE_DUMP,
628};
629
630typedef struct {
631    int type;
632    pid_t pid, tid;
633    uid_t uid, gid;
634} request_t;
635
636static int read_request(int fd, request_t* out_request) {
637    struct ucred cr;
638    int len = sizeof(cr);
639    int status = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &cr, &len);
640    if (status != 0) {
641        LOG("cannot get credentials\n");
642        return -1;
643    }
644
645    XLOG("reading tid\n");
646    fcntl(fd, F_SETFL, O_NONBLOCK);
647
648    struct pollfd pollfds[1];
649    pollfds[0].fd = fd;
650    pollfds[0].events = POLLIN;
651    pollfds[0].revents = 0;
652    status = TEMP_FAILURE_RETRY(poll(pollfds, 1, 3000));
653    if (status != 1) {
654        LOG("timed out reading tid\n");
655        return -1;
656    }
657
658    status = TEMP_FAILURE_RETRY(read(fd, &out_request->tid, sizeof(pid_t)));
659    if (status < 0) {
660        LOG("read failure? %s\n", strerror(errno));
661        return -1;
662    }
663    if (status != sizeof(pid_t)) {
664        LOG("invalid crash request of size %d\n", status);
665        return -1;
666    }
667
668    if (out_request->tid < 0 && cr.uid == 0) {
669        /* Root can ask us to attach to any process and dump it explicitly. */
670        out_request->type = REQUEST_TYPE_DUMP;
671        out_request->tid = -out_request->tid;
672        status = get_process_info(out_request->tid, &out_request->pid,
673                &out_request->uid, &out_request->gid);
674        if (status < 0) {
675            LOG("tid %d does not exist. ignoring explicit dump request\n",
676                    out_request->tid);
677            return -1;
678        }
679        return 0;
680    }
681
682    /* Ensure that the tid reported by the crashing process is valid. */
683    out_request->type = REQUEST_TYPE_CRASH;
684    out_request->pid = cr.pid;
685    out_request->uid = cr.uid;
686    out_request->gid = cr.gid;
687
688    char buf[64];
689    struct stat s;
690    snprintf(buf, sizeof buf, "/proc/%d/task/%d", out_request->pid, out_request->tid);
691    if(stat(buf, &s)) {
692        LOG("tid %d does not exist in pid %d. ignoring debug request\n",
693                out_request->tid, out_request->pid);
694        return -1;
695    }
696    return 0;
697}
698
699static bool should_attach_gdb(request_t* request) {
700    if (request->type == REQUEST_TYPE_CRASH) {
701        char value[PROPERTY_VALUE_MAX];
702        property_get("debug.db.uid", value, "-1");
703        int debug_uid = atoi(value);
704        return debug_uid >= 0 && request->uid <= (uid_t)debug_uid;
705    }
706    return false;
707}
708
709static void handle_request(int fd) {
710    XLOG("handle_request(%d)\n", fd);
711
712    request_t request;
713    int status = read_request(fd, &request);
714    if (!status) {
715        XLOG("BOOM: pid=%d uid=%d gid=%d tid=%d\n", pid, uid, gid, tid);
716
717        /* At this point, the thread that made the request is blocked in
718         * a read() call.  If the thread has crashed, then this gives us
719         * time to PTRACE_ATTACH to it before it has a chance to really fault.
720         *
721         * The PTRACE_ATTACH sends a SIGSTOP to the target process, but it
722         * won't necessarily have stopped by the time ptrace() returns.  (We
723         * currently assume it does.)  We write to the file descriptor to
724         * ensure that it can run as soon as we call PTRACE_CONT below.
725         * See details in bionic/libc/linker/debugger.c, in function
726         * debugger_signal_handler().
727         */
728        if (ptrace(PTRACE_ATTACH, request.tid, 0, 0)) {
729            LOG("ptrace attach failed: %s\n", strerror(errno));
730        } else {
731            bool detach_failed = false;
732            bool attach_gdb = should_attach_gdb(&request);
733            char response = 0;
734            if (TEMP_FAILURE_RETRY(write(fd, &response, 1)) != 1) {
735                LOG("failed responding to client: %s\n", strerror(errno));
736            } else {
737                close(fd);
738                fd = -1;
739
740                int total_sleep_time_usec = 0;
741                for (;;) {
742                    int signal = wait_for_signal(request.tid, &total_sleep_time_usec);
743                    if (signal < 0) {
744                        break;
745                    }
746
747                    switch (signal) {
748                    case SIGSTOP:
749                        if (request.type == REQUEST_TYPE_DUMP) {
750                            XLOG("stopped -- dumping\n");
751                            detach_failed = engrave_tombstone(request.pid, request.tid,
752                                    signal, true);
753                        } else {
754                            XLOG("stopped -- continuing\n");
755                            status = ptrace(PTRACE_CONT, request.tid, 0, 0);
756                            if (status) {
757                                LOG("ptrace continue failed: %s\n", strerror(errno));
758                            }
759                            continue; /* loop again */
760                        }
761                        break;
762
763                    case SIGILL:
764                    case SIGABRT:
765                    case SIGBUS:
766                    case SIGFPE:
767                    case SIGSEGV:
768                    case SIGSTKFLT: {
769                        XLOG("stopped -- fatal signal\n");
770                        /* don't dump sibling threads when attaching to GDB because it
771                         * makes the process less reliable, apparently... */
772                        detach_failed = engrave_tombstone(request.pid, request.tid,
773                                signal, !attach_gdb);
774                        break;
775                    }
776
777                    default:
778                        XLOG("stopped -- unexpected signal\n");
779                        LOG("process stopped due to unexpected signal %d\n", signal);
780                        break;
781                    }
782                    break;
783                }
784            }
785
786            XLOG("detaching\n");
787            if (attach_gdb) {
788                /* stop the process so we can debug */
789                kill(request.pid, SIGSTOP);
790
791                /* detach so we can attach gdbserver */
792                if (ptrace(PTRACE_DETACH, request.tid, 0, 0)) {
793                    LOG("ptrace detach from %d failed: %s\n", request.tid, strerror(errno));
794                    detach_failed = true;
795                }
796
797                /*
798                 * if debug.db.uid is set, its value indicates if we should wait
799                 * for user action for the crashing process.
800                 * in this case, we log a message and turn the debug LED on
801                 * waiting for a gdb connection (for instance)
802                 */
803                wait_for_user_action(request.pid);
804            } else {
805                /* just detach */
806                if (ptrace(PTRACE_DETACH, request.tid, 0, 0)) {
807                    LOG("ptrace detach from %d failed: %s\n", request.tid, strerror(errno));
808                    detach_failed = true;
809                }
810            }
811
812            /* resume stopped process (so it can crash in peace). */
813            kill(request.pid, SIGCONT);
814
815            /* If we didn't successfully detach, we're still the parent, and the
816             * actual parent won't receive a death notification via wait(2).  At this point
817             * there's not much we can do about that. */
818            if (detach_failed) {
819                LOG("debuggerd committing suicide to free the zombie!\n");
820                kill(getpid(), SIGKILL);
821            }
822        }
823
824    }
825    if (fd >= 0) {
826        close(fd);
827    }
828}
829
830static int do_server() {
831    int s;
832    struct sigaction act;
833    int logsocket = -1;
834
835    /*
836     * debuggerd crashes can't be reported to debuggerd.  Reset all of the
837     * crash handlers.
838     */
839    signal(SIGILL, SIG_DFL);
840    signal(SIGABRT, SIG_DFL);
841    signal(SIGBUS, SIG_DFL);
842    signal(SIGFPE, SIG_DFL);
843    signal(SIGSEGV, SIG_DFL);
844    signal(SIGSTKFLT, SIG_DFL);
845    signal(SIGPIPE, SIG_DFL);
846
847    logsocket = socket_local_client("logd",
848            ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_DGRAM);
849    if(logsocket < 0) {
850        logsocket = -1;
851    } else {
852        fcntl(logsocket, F_SETFD, FD_CLOEXEC);
853    }
854
855    act.sa_handler = SIG_DFL;
856    sigemptyset(&act.sa_mask);
857    sigaddset(&act.sa_mask,SIGCHLD);
858    act.sa_flags = SA_NOCLDWAIT;
859    sigaction(SIGCHLD, &act, 0);
860
861    s = socket_local_server("android:debuggerd",
862            ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM);
863    if(s < 0) return 1;
864    fcntl(s, F_SETFD, FD_CLOEXEC);
865
866    LOG("debuggerd: " __DATE__ " " __TIME__ "\n");
867
868    for(;;) {
869        struct sockaddr addr;
870        socklen_t alen;
871        int fd;
872
873        alen = sizeof(addr);
874        XLOG("waiting for connection\n");
875        fd = accept(s, &addr, &alen);
876        if(fd < 0) {
877            XLOG("accept failed: %s\n", strerror(errno));
878            continue;
879        }
880
881        fcntl(fd, F_SETFD, FD_CLOEXEC);
882
883        handle_request(fd);
884    }
885    return 0;
886}
887
888static int do_explicit_dump(pid_t tid) {
889    fprintf(stdout, "Sending request to dump task %d.\n", tid);
890
891    int fd = socket_local_client("android:debuggerd",
892            ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM);
893    if (fd < 0) {
894        fputs("Error opening local socket to debuggerd.\n", stderr);
895        return 1;
896    }
897
898    pid_t request = -tid;
899    write(fd, &request, sizeof(pid_t));
900    if (read(fd, &request, 1) != 1) {
901        /* did not get expected reply, debuggerd must have closed the socket */
902        fputs("Error sending request.  Did not receive reply from debuggerd.\n", stderr);
903    }
904    close(fd);
905    return 0;
906}
907
908int main(int argc, char** argv) {
909    if (argc == 2) {
910        pid_t tid = atoi(argv[1]);
911        if (!tid) {
912            fputs("Usage: [<tid>]\n"
913                    "\n"
914                    "If tid specified, sends a request to debuggerd to dump that task.\n"
915                    "Otherwise, starts the debuggerd server.\n", stderr);
916            return 1;
917        }
918        return do_explicit_dump(tid);
919    }
920    return do_server();
921}
922