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