Home | History | Annotate | Download | only in linker
      1 /*
      2  * Copyright (C) 2008 The Android Open Source Project
      3  * All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions
      7  * are met:
      8  *  * Redistributions of source code must retain the above copyright
      9  *    notice, this list of conditions and the following disclaimer.
     10  *  * Redistributions in binary form must reproduce the above copyright
     11  *    notice, this list of conditions and the following disclaimer in
     12  *    the documentation and/or other materials provided with the
     13  *    distribution.
     14  *
     15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     16  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     17  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
     18  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
     19  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
     20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
     21  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
     22  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
     23  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
     24  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
     25  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     26  * SUCH DAMAGE.
     27  */
     28 
     29 #include <stdio.h>
     30 #include <stdlib.h>
     31 #include <unistd.h>
     32 #include <ctype.h>
     33 #include <signal.h>
     34 #include <sys/mman.h>
     35 #include <sys/prctl.h>
     36 #include <errno.h>
     37 
     38 #include "linker.h"
     39 
     40 #include <sys/socket.h>
     41 #include <sys/un.h>
     42 
     43 extern int tgkill(int tgid, int tid, int sig);
     44 
     45 void notify_gdb_of_libraries();
     46 
     47 #define DEBUGGER_SOCKET_NAME "android:debuggerd"
     48 
     49 typedef enum {
     50     // dump a crash
     51     DEBUGGER_ACTION_CRASH,
     52     // dump a tombstone file
     53     DEBUGGER_ACTION_DUMP_TOMBSTONE,
     54     // dump a backtrace only back to the socket
     55     DEBUGGER_ACTION_DUMP_BACKTRACE,
     56 } debugger_action_t;
     57 
     58 /* message sent over the socket */
     59 typedef struct {
     60     debugger_action_t action;
     61     pid_t tid;
     62 } debugger_msg_t;
     63 
     64 #define  RETRY_ON_EINTR(ret,cond) \
     65     do { \
     66         ret = (cond); \
     67     } while (ret < 0 && errno == EINTR)
     68 
     69 // see man(2) prctl, specifically the section about PR_GET_NAME
     70 #define MAX_TASK_NAME_LEN (16)
     71 
     72 static int socket_abstract_client(const char *name, int type)
     73 {
     74     struct sockaddr_un addr;
     75     size_t namelen;
     76     socklen_t alen;
     77     int s, err;
     78 
     79     namelen  = strlen(name);
     80 
     81     // Test with length +1 for the *initial* '\0'.
     82     if ((namelen + 1) > sizeof(addr.sun_path)) {
     83         errno = EINVAL;
     84         return -1;
     85     }
     86 
     87     /* This is used for abstract socket namespace, we need
     88      * an initial '\0' at the start of the Unix socket path.
     89      *
     90      * Note: The path in this case is *not* supposed to be
     91      * '\0'-terminated. ("man 7 unix" for the gory details.)
     92      */
     93     memset (&addr, 0, sizeof addr);
     94     addr.sun_family = AF_LOCAL;
     95     addr.sun_path[0] = 0;
     96     memcpy(addr.sun_path + 1, name, namelen);
     97 
     98     alen = namelen + offsetof(struct sockaddr_un, sun_path) + 1;
     99 
    100     s = socket(AF_LOCAL, type, 0);
    101     if(s < 0) return -1;
    102 
    103     RETRY_ON_EINTR(err,connect(s, (struct sockaddr *) &addr, alen));
    104     if (err < 0) {
    105         close(s);
    106         s = -1;
    107     }
    108 
    109     return s;
    110 }
    111 
    112 #include "linker_format.h"
    113 #include <../libc/private/logd.h>
    114 
    115 /*
    116  * Writes a summary of the signal to the log file.
    117  *
    118  * We could be here as a result of native heap corruption, or while a
    119  * mutex is being held, so we don't want to use any libc functions that
    120  * could allocate memory or hold a lock.
    121  */
    122 static void logSignalSummary(int signum, const siginfo_t* info)
    123 {
    124     char buffer[128];
    125     char threadname[MAX_TASK_NAME_LEN + 1]; // one more for termination
    126 
    127     char* signame;
    128     switch (signum) {
    129         case SIGILL:    signame = "SIGILL";     break;
    130         case SIGABRT:   signame = "SIGABRT";    break;
    131         case SIGBUS:    signame = "SIGBUS";     break;
    132         case SIGFPE:    signame = "SIGFPE";     break;
    133         case SIGSEGV:   signame = "SIGSEGV";    break;
    134         case SIGSTKFLT: signame = "SIGSTKFLT";  break;
    135         case SIGPIPE:   signame = "SIGPIPE";    break;
    136         default:        signame = "???";        break;
    137     }
    138 
    139     if (prctl(PR_GET_NAME, (unsigned long)threadname, 0, 0, 0) != 0) {
    140         strcpy(threadname, "<name unknown>");
    141     } else {
    142         // short names are null terminated by prctl, but the manpage
    143         // implies that 16 byte names are not.
    144         threadname[MAX_TASK_NAME_LEN] = 0;
    145     }
    146     format_buffer(buffer, sizeof(buffer),
    147         "Fatal signal %d (%s) at 0x%08x (code=%d), thread %d (%s)",
    148         signum, signame, info->si_addr, info->si_code, gettid(), threadname);
    149 
    150     __libc_android_log_write(ANDROID_LOG_FATAL, "libc", buffer);
    151 }
    152 
    153 /*
    154  * Catches fatal signals so we can ask debuggerd to ptrace us before
    155  * we crash.
    156  */
    157 void debugger_signal_handler(int n, siginfo_t* info, void* unused)
    158 {
    159     char msgbuf[128];
    160     unsigned tid;
    161     int s;
    162 
    163     logSignalSummary(n, info);
    164 
    165     tid = gettid();
    166     s = socket_abstract_client(DEBUGGER_SOCKET_NAME, SOCK_STREAM);
    167 
    168     if (s >= 0) {
    169         /* debugger knows our pid from the credentials on the
    170          * local socket but we need to tell it our tid.  It
    171          * is paranoid and will verify that we are giving a tid
    172          * that's actually in our process
    173          */
    174         int  ret;
    175         debugger_msg_t msg;
    176         msg.action = DEBUGGER_ACTION_CRASH;
    177         msg.tid = tid;
    178         RETRY_ON_EINTR(ret, write(s, &msg, sizeof(msg)));
    179         if (ret == sizeof(msg)) {
    180             /* if the write failed, there is no point to read on
    181              * the file descriptor. */
    182             RETRY_ON_EINTR(ret, read(s, &tid, 1));
    183             int savedErrno = errno;
    184             notify_gdb_of_libraries();
    185             errno = savedErrno;
    186         }
    187 
    188         if (ret < 0) {
    189             /* read or write failed -- broken connection? */
    190             format_buffer(msgbuf, sizeof(msgbuf),
    191                 "Failed while talking to debuggerd: %s", strerror(errno));
    192             __libc_android_log_write(ANDROID_LOG_FATAL, "libc", msgbuf);
    193         }
    194 
    195         close(s);
    196     } else {
    197         /* socket failed; maybe process ran out of fds */
    198         format_buffer(msgbuf, sizeof(msgbuf),
    199             "Unable to open connection to debuggerd: %s", strerror(errno));
    200         __libc_android_log_write(ANDROID_LOG_FATAL, "libc", msgbuf);
    201     }
    202 
    203     /* remove our net so we fault for real when we return */
    204     signal(n, SIG_DFL);
    205 
    206     /*
    207      * These signals are not re-thrown when we resume.  This means that
    208      * crashing due to (say) SIGPIPE doesn't work the way you'd expect it
    209      * to.  We work around this by throwing them manually.  We don't want
    210      * to do this for *all* signals because it'll screw up the address for
    211      * faults like SIGSEGV.
    212      */
    213     switch (n) {
    214         case SIGABRT:
    215         case SIGFPE:
    216         case SIGPIPE:
    217         case SIGSTKFLT:
    218             (void) tgkill(getpid(), gettid(), n);
    219             break;
    220         default:    // SIGILL, SIGBUS, SIGSEGV
    221             break;
    222     }
    223 }
    224 
    225 void debugger_init()
    226 {
    227     struct sigaction act;
    228     memset(&act, 0, sizeof(act));
    229     act.sa_sigaction = debugger_signal_handler;
    230     act.sa_flags = SA_RESTART | SA_SIGINFO;
    231     sigemptyset(&act.sa_mask);
    232 
    233     sigaction(SIGILL, &act, NULL);
    234     sigaction(SIGABRT, &act, NULL);
    235     sigaction(SIGBUS, &act, NULL);
    236     sigaction(SIGFPE, &act, NULL);
    237     sigaction(SIGSEGV, &act, NULL);
    238     sigaction(SIGSTKFLT, &act, NULL);
    239     sigaction(SIGPIPE, &act, NULL);
    240 }
    241