1 /* 2 * Copyright (C) 2013 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #define _GNU_SOURCE 1 18 #include <errno.h> 19 #include <stdint.h> 20 #include <string.h> 21 #include <sys/param.h> 22 #include <sys/ptrace.h> 23 #include <sys/types.h> 24 #include <ucontext.h> 25 #include <unistd.h> 26 27 #include <stdlib.h> 28 29 #include <string> 30 31 #include <backtrace/Backtrace.h> 32 #include <backtrace/BacktraceMap.h> 33 34 #include "BacktraceAsyncSafeLog.h" 35 #include "BacktraceCurrent.h" 36 #include "ThreadEntry.h" 37 #include "thread_utils.h" 38 39 bool BacktraceCurrent::ReadWord(uint64_t ptr, word_t* out_value) { 40 if (!VerifyReadWordArgs(ptr, out_value)) { 41 return false; 42 } 43 44 backtrace_map_t map; 45 FillInMap(ptr, &map); 46 if (BacktraceMap::IsValid(map) && map.flags & PROT_READ) { 47 *out_value = *reinterpret_cast<word_t*>(ptr); 48 return true; 49 } else { 50 BACK_ASYNC_SAFE_LOGW("pointer %p not in a readable map", reinterpret_cast<void*>(ptr)); 51 *out_value = static_cast<word_t>(-1); 52 return false; 53 } 54 } 55 56 size_t BacktraceCurrent::Read(uint64_t addr, uint8_t* buffer, size_t bytes) { 57 backtrace_map_t map; 58 FillInMap(addr, &map); 59 if (!BacktraceMap::IsValid(map) || !(map.flags & PROT_READ)) { 60 return 0; 61 } 62 bytes = MIN(map.end - addr, bytes); 63 memcpy(buffer, reinterpret_cast<uint8_t*>(addr), bytes); 64 return bytes; 65 } 66 67 bool BacktraceCurrent::Unwind(size_t num_ignore_frames, void* ucontext) { 68 if (GetMap() == nullptr) { 69 // Without a map object, we can't do anything. 70 error_.error_code = BACKTRACE_UNWIND_ERROR_MAP_MISSING; 71 return false; 72 } 73 74 error_.error_code = BACKTRACE_UNWIND_NO_ERROR; 75 if (ucontext) { 76 return UnwindFromContext(num_ignore_frames, ucontext); 77 } 78 79 if (Tid() != gettid()) { 80 return UnwindThread(num_ignore_frames); 81 } 82 83 return UnwindFromContext(num_ignore_frames, nullptr); 84 } 85 86 bool BacktraceCurrent::DiscardFrame(const backtrace_frame_data_t& frame) { 87 if (BacktraceMap::IsValid(frame.map)) { 88 const std::string library = basename(frame.map.name.c_str()); 89 if (library == "libunwind.so" || library == "libbacktrace.so") { 90 return true; 91 } 92 } 93 return false; 94 } 95 96 static pthread_mutex_t g_sigaction_mutex = PTHREAD_MUTEX_INITIALIZER; 97 98 // Since errno is stored per thread, changing it in the signal handler 99 // modifies the value on the thread in which the signal handler executes. 100 // If a signal occurs between a call and an errno check, it's possible 101 // to get the errno set here. Always save and restore it just in case 102 // code would modify it. 103 class ErrnoRestorer { 104 public: 105 ErrnoRestorer() : saved_errno_(errno) {} 106 ~ErrnoRestorer() { 107 errno = saved_errno_; 108 } 109 110 private: 111 int saved_errno_; 112 }; 113 114 static void SignalLogOnly(int, siginfo_t*, void*) { 115 ErrnoRestorer restore; 116 117 BACK_ASYNC_SAFE_LOGE("pid %d, tid %d: Received a spurious signal %d\n", getpid(), gettid(), 118 THREAD_SIGNAL); 119 } 120 121 static void SignalHandler(int, siginfo_t*, void* sigcontext) { 122 ErrnoRestorer restore; 123 124 ThreadEntry* entry = ThreadEntry::Get(getpid(), gettid(), false); 125 if (!entry) { 126 BACK_ASYNC_SAFE_LOGE("pid %d, tid %d entry not found", getpid(), gettid()); 127 return; 128 } 129 130 entry->CopyUcontextFromSigcontext(sigcontext); 131 132 // Indicate the ucontext is now valid. 133 entry->Wake(); 134 135 // Pause the thread until the unwind is complete. This avoids having 136 // the thread run ahead causing problems. 137 // The number indicates that we are waiting for the second Wake() call 138 // overall which is made by the thread requesting an unwind. 139 if (entry->Wait(2)) { 140 // Do not remove the entry here because that can result in a deadlock 141 // if the code cannot properly send a signal to the thread under test. 142 entry->Wake(); 143 } else { 144 // At this point, it is possible that entry has been freed, so just exit. 145 BACK_ASYNC_SAFE_LOGE("Timed out waiting for unwind thread to indicate it completed."); 146 } 147 } 148 149 bool BacktraceCurrent::UnwindThread(size_t num_ignore_frames) { 150 // Prevent multiple threads trying to set the trigger action on different 151 // threads at the same time. 152 pthread_mutex_lock(&g_sigaction_mutex); 153 154 ThreadEntry* entry = ThreadEntry::Get(Pid(), Tid()); 155 entry->Lock(); 156 157 struct sigaction act, oldact; 158 memset(&act, 0, sizeof(act)); 159 act.sa_sigaction = SignalHandler; 160 act.sa_flags = SA_RESTART | SA_SIGINFO | SA_ONSTACK; 161 sigemptyset(&act.sa_mask); 162 if (sigaction(THREAD_SIGNAL, &act, &oldact) != 0) { 163 BACK_ASYNC_SAFE_LOGE("sigaction failed: %s", strerror(errno)); 164 ThreadEntry::Remove(entry); 165 pthread_mutex_unlock(&g_sigaction_mutex); 166 error_.error_code = BACKTRACE_UNWIND_ERROR_INTERNAL; 167 return false; 168 } 169 170 if (tgkill(Pid(), Tid(), THREAD_SIGNAL) != 0) { 171 // Do not emit an error message, this might be expected. Set the 172 // error and let the caller decide. 173 if (errno == ESRCH) { 174 error_.error_code = BACKTRACE_UNWIND_ERROR_THREAD_DOESNT_EXIST; 175 } else { 176 error_.error_code = BACKTRACE_UNWIND_ERROR_INTERNAL; 177 } 178 179 sigaction(THREAD_SIGNAL, &oldact, nullptr); 180 ThreadEntry::Remove(entry); 181 pthread_mutex_unlock(&g_sigaction_mutex); 182 return false; 183 } 184 185 // Wait for the thread to get the ucontext. The number indicates 186 // that we are waiting for the first Wake() call made by the thread. 187 bool wait_completed = entry->Wait(1); 188 189 if (!wait_completed && oldact.sa_sigaction == nullptr) { 190 // If the wait failed, it could be that the signal could not be delivered 191 // within the timeout. Add a signal handler that's simply going to log 192 // something so that we don't crash if the signal eventually gets 193 // delivered. Only do this if there isn't already an action set up. 194 memset(&act, 0, sizeof(act)); 195 act.sa_sigaction = SignalLogOnly; 196 act.sa_flags = SA_RESTART | SA_SIGINFO | SA_ONSTACK; 197 sigemptyset(&act.sa_mask); 198 sigaction(THREAD_SIGNAL, &act, nullptr); 199 } else { 200 sigaction(THREAD_SIGNAL, &oldact, nullptr); 201 } 202 // After the thread has received the signal, allow other unwinders to 203 // continue. 204 pthread_mutex_unlock(&g_sigaction_mutex); 205 206 bool unwind_done = false; 207 if (wait_completed) { 208 unwind_done = UnwindFromContext(num_ignore_frames, entry->GetUcontext()); 209 210 // Tell the signal handler to exit and release the entry. 211 entry->Wake(); 212 213 // Wait for the thread to indicate it is done with the ThreadEntry. 214 if (!entry->Wait(3)) { 215 // Send a warning, but do not mark as a failure to unwind. 216 BACK_ASYNC_SAFE_LOGW("Timed out waiting for signal handler to indicate it finished."); 217 } 218 } else { 219 // Check to see if the thread has disappeared. 220 if (tgkill(Pid(), Tid(), 0) == -1 && errno == ESRCH) { 221 error_.error_code = BACKTRACE_UNWIND_ERROR_THREAD_DOESNT_EXIST; 222 } else { 223 error_.error_code = BACKTRACE_UNWIND_ERROR_THREAD_TIMEOUT; 224 BACK_ASYNC_SAFE_LOGE("Timed out waiting for signal handler to get ucontext data."); 225 } 226 } 227 228 ThreadEntry::Remove(entry); 229 230 return unwind_done; 231 } 232