• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <stdbool.h>
33 #include <signal.h>
34 #include <sys/prctl.h>
35 #include <errno.h>
36 #include <sys/socket.h>
37 #include <sys/un.h>
38 
39 extern int tgkill(int tgid, int tid, int sig);
40 
41 void notify_gdb_of_libraries();
42 
43 #define DEBUGGER_SOCKET_NAME "android:debuggerd"
44 
45 typedef enum {
46     // dump a crash
47     DEBUGGER_ACTION_CRASH,
48     // dump a tombstone file
49     DEBUGGER_ACTION_DUMP_TOMBSTONE,
50     // dump a backtrace only back to the socket
51     DEBUGGER_ACTION_DUMP_BACKTRACE,
52 } debugger_action_t;
53 
54 /* message sent over the socket */
55 typedef struct {
56     debugger_action_t action;
57     pid_t tid;
58 } debugger_msg_t;
59 
60 #define  RETRY_ON_EINTR(ret,cond) \
61     do { \
62         ret = (cond); \
63     } while (ret < 0 && errno == EINTR)
64 
65 // see man(2) prctl, specifically the section about PR_GET_NAME
66 #define MAX_TASK_NAME_LEN (16)
67 
socket_abstract_client(const char * name,int type)68 static int socket_abstract_client(const char *name, int type)
69 {
70     struct sockaddr_un addr;
71     size_t namelen;
72     socklen_t alen;
73     int s, err;
74 
75     namelen  = strlen(name);
76 
77     // Test with length +1 for the *initial* '\0'.
78     if ((namelen + 1) > sizeof(addr.sun_path)) {
79         errno = EINVAL;
80         return -1;
81     }
82 
83     /* This is used for abstract socket namespace, we need
84      * an initial '\0' at the start of the Unix socket path.
85      *
86      * Note: The path in this case is *not* supposed to be
87      * '\0'-terminated. ("man 7 unix" for the gory details.)
88      */
89     memset (&addr, 0, sizeof addr);
90     addr.sun_family = AF_LOCAL;
91     addr.sun_path[0] = 0;
92     memcpy(addr.sun_path + 1, name, namelen);
93 
94     alen = namelen + offsetof(struct sockaddr_un, sun_path) + 1;
95 
96     s = socket(AF_LOCAL, type, 0);
97     if(s < 0) return -1;
98 
99     RETRY_ON_EINTR(err,connect(s, (struct sockaddr *) &addr, alen));
100     if (err < 0) {
101         close(s);
102         s = -1;
103     }
104 
105     return s;
106 }
107 
108 #include "linker_format.h"
109 #include <../libc/private/logd.h>
110 
111 /*
112  * Writes a summary of the signal to the log file.  We do this so that, if
113  * for some reason we're not able to contact debuggerd, there is still some
114  * indication of the failure in the log.
115  *
116  * We could be here as a result of native heap corruption, or while a
117  * mutex is being held, so we don't want to use any libc functions that
118  * could allocate memory or hold a lock.
119  *
120  * "info" will be NULL if the siginfo_t information was not available.
121  */
logSignalSummary(int signum,const siginfo_t * info)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 #if defined(SIGSTKFLT)
135         case SIGSTKFLT: signame = "SIGSTKFLT";  break;
136 #endif
137         case SIGPIPE:   signame = "SIGPIPE";    break;
138         default:        signame = "???";        break;
139     }
140 
141     if (prctl(PR_GET_NAME, (unsigned long)threadname, 0, 0, 0) != 0) {
142         strcpy(threadname, "<name unknown>");
143     } else {
144         // short names are null terminated by prctl, but the manpage
145         // implies that 16 byte names are not.
146         threadname[MAX_TASK_NAME_LEN] = 0;
147     }
148     if (info != NULL) {
149         format_buffer(buffer, sizeof(buffer),
150             "Fatal signal %d (%s) at 0x%08x (code=%d), thread %d (%s)",
151             signum, signame, info->si_addr, info->si_code, gettid(), threadname);
152     } else {
153         format_buffer(buffer, sizeof(buffer),
154             "Fatal signal %d (%s), thread %d (%s)",
155             signum, signame, gettid(), threadname);
156     }
157 
158     __libc_android_log_write(ANDROID_LOG_FATAL, "libc", buffer);
159 }
160 
161 /*
162  * Returns true if the handler for signal "signum" has SA_SIGINFO set.
163  */
haveSiginfo(int signum)164 static bool haveSiginfo(int signum)
165 {
166     struct sigaction oldact, newact;
167 
168     memset(&newact, 0, sizeof(newact));
169     newact.sa_handler = SIG_DFL;
170     newact.sa_flags = SA_RESTART;
171     sigemptyset(&newact.sa_mask);
172 
173     if (sigaction(signum, &newact, &oldact) < 0) {
174         __libc_android_log_write(ANDROID_LOG_FATAL, "libc",
175             "Failed testing for SA_SIGINFO");
176         return 0;
177     }
178     bool ret = (oldact.sa_flags & SA_SIGINFO) != 0;
179 
180     if (sigaction(signum, &oldact, NULL) < 0) {
181         __libc_android_log_write(ANDROID_LOG_FATAL, "libc",
182             "Restore failed in test for SA_SIGINFO");
183     }
184     return ret;
185 }
186 
187 /*
188  * Catches fatal signals so we can ask debuggerd to ptrace us before
189  * we crash.
190  */
debugger_signal_handler(int n,siginfo_t * info,void * unused)191 void debugger_signal_handler(int n, siginfo_t* info, void* unused __attribute__((unused)))
192 {
193     char msgbuf[128];
194     unsigned tid;
195     int s;
196 
197     /*
198      * It's possible somebody cleared the SA_SIGINFO flag, which would mean
199      * our "info" arg holds an undefined value.
200      */
201     if (!haveSiginfo(n)) {
202         info = NULL;
203     }
204 
205     logSignalSummary(n, info);
206 
207     tid = gettid();
208     s = socket_abstract_client(DEBUGGER_SOCKET_NAME, SOCK_STREAM);
209 
210     if (s >= 0) {
211         /* debugger knows our pid from the credentials on the
212          * local socket but we need to tell it our tid.  It
213          * is paranoid and will verify that we are giving a tid
214          * that's actually in our process
215          */
216         int  ret;
217         debugger_msg_t msg;
218         msg.action = DEBUGGER_ACTION_CRASH;
219         msg.tid = tid;
220         RETRY_ON_EINTR(ret, write(s, &msg, sizeof(msg)));
221         if (ret == sizeof(msg)) {
222             /* if the write failed, there is no point to read on
223              * the file descriptor. */
224             RETRY_ON_EINTR(ret, read(s, &tid, 1));
225             int savedErrno = errno;
226             notify_gdb_of_libraries();
227             errno = savedErrno;
228         }
229 
230         if (ret < 0) {
231             /* read or write failed -- broken connection? */
232             format_buffer(msgbuf, sizeof(msgbuf),
233                 "Failed while talking to debuggerd: %s", strerror(errno));
234             __libc_android_log_write(ANDROID_LOG_FATAL, "libc", msgbuf);
235         }
236 
237         close(s);
238     } else {
239         /* socket failed; maybe process ran out of fds */
240         format_buffer(msgbuf, sizeof(msgbuf),
241             "Unable to open connection to debuggerd: %s", strerror(errno));
242         __libc_android_log_write(ANDROID_LOG_FATAL, "libc", msgbuf);
243     }
244 
245     /* remove our net so we fault for real when we return */
246     signal(n, SIG_DFL);
247 
248     /*
249      * These signals are not re-thrown when we resume.  This means that
250      * crashing due to (say) SIGPIPE doesn't work the way you'd expect it
251      * to.  We work around this by throwing them manually.  We don't want
252      * to do this for *all* signals because it'll screw up the address for
253      * faults like SIGSEGV.
254      */
255     switch (n) {
256         case SIGABRT:
257         case SIGFPE:
258         case SIGPIPE:
259 #ifdef SIGSTKFLT
260         case SIGSTKFLT:
261 #endif
262             (void) tgkill(getpid(), gettid(), n);
263             break;
264         default:    // SIGILL, SIGBUS, SIGSEGV
265             break;
266     }
267 }
268 
debugger_init()269 void debugger_init()
270 {
271     struct sigaction act;
272     memset(&act, 0, sizeof(act));
273     act.sa_sigaction = debugger_signal_handler;
274     act.sa_flags = SA_RESTART | SA_SIGINFO;
275     sigemptyset(&act.sa_mask);
276 
277     sigaction(SIGILL, &act, NULL);
278     sigaction(SIGABRT, &act, NULL);
279     sigaction(SIGBUS, &act, NULL);
280     sigaction(SIGFPE, &act, NULL);
281     sigaction(SIGSEGV, &act, NULL);
282 #if defined(SIGSTKFLT)
283     sigaction(SIGSTKFLT, &act, NULL);
284 #endif
285     sigaction(SIGPIPE, &act, NULL);
286 }
287