LLVM API Documentation
00001 //===- Signals.cpp - Generic Unix Signals Implementation -----*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file defines some helpful functions for dealing with the possibility of 00011 // Unix signals occurring while your program is running. 00012 // 00013 //===----------------------------------------------------------------------===// 00014 00015 #include "Unix.h" 00016 #include "llvm/ADT/STLExtras.h" 00017 #include "llvm/Support/Mutex.h" 00018 #include "llvm/Support/UniqueLock.h" 00019 #include "llvm/Support/ManagedStatic.h" 00020 #include <algorithm> 00021 #include <string> 00022 #include <vector> 00023 #if HAVE_EXECINFO_H 00024 # include <execinfo.h> // For backtrace(). 00025 #endif 00026 #if HAVE_SIGNAL_H 00027 #include <signal.h> 00028 #endif 00029 #if HAVE_SYS_STAT_H 00030 #include <sys/stat.h> 00031 #endif 00032 #if HAVE_CXXABI_H 00033 #include <cxxabi.h> 00034 #endif 00035 #if HAVE_DLFCN_H 00036 #include <dlfcn.h> 00037 #endif 00038 #if HAVE_MACH_MACH_H 00039 #include <mach/mach.h> 00040 #endif 00041 00042 using namespace llvm; 00043 00044 static RETSIGTYPE SignalHandler(int Sig); // defined below. 00045 00046 static ManagedStatic<SmartMutex<true> > SignalsMutex; 00047 00048 /// InterruptFunction - The function to call if ctrl-c is pressed. 00049 static void (*InterruptFunction)() = nullptr; 00050 00051 static ManagedStatic<std::vector<std::string>> FilesToRemove; 00052 static ManagedStatic<std::vector<std::pair<void (*)(void *), void *>>> 00053 CallBacksToRun; 00054 00055 // IntSigs - Signals that represent requested termination. There's no bug 00056 // or failure, or if there is, it's not our direct responsibility. For whatever 00057 // reason, our continued execution is no longer desirable. 00058 static const int IntSigs[] = { 00059 SIGHUP, SIGINT, SIGPIPE, SIGTERM, SIGUSR1, SIGUSR2 00060 }; 00061 00062 // KillSigs - Signals that represent that we have a bug, and our prompt 00063 // termination has been ordered. 00064 static const int KillSigs[] = { 00065 SIGILL, SIGTRAP, SIGABRT, SIGFPE, SIGBUS, SIGSEGV, SIGQUIT 00066 #ifdef SIGSYS 00067 , SIGSYS 00068 #endif 00069 #ifdef SIGXCPU 00070 , SIGXCPU 00071 #endif 00072 #ifdef SIGXFSZ 00073 , SIGXFSZ 00074 #endif 00075 #ifdef SIGEMT 00076 , SIGEMT 00077 #endif 00078 }; 00079 00080 static unsigned NumRegisteredSignals = 0; 00081 static struct { 00082 struct sigaction SA; 00083 int SigNo; 00084 } RegisteredSignalInfo[(sizeof(IntSigs)+sizeof(KillSigs))/sizeof(KillSigs[0])]; 00085 00086 00087 static void RegisterHandler(int Signal) { 00088 assert(NumRegisteredSignals < 00089 sizeof(RegisteredSignalInfo)/sizeof(RegisteredSignalInfo[0]) && 00090 "Out of space for signal handlers!"); 00091 00092 struct sigaction NewHandler; 00093 00094 NewHandler.sa_handler = SignalHandler; 00095 NewHandler.sa_flags = SA_NODEFER|SA_RESETHAND; 00096 sigemptyset(&NewHandler.sa_mask); 00097 00098 // Install the new handler, save the old one in RegisteredSignalInfo. 00099 sigaction(Signal, &NewHandler, 00100 &RegisteredSignalInfo[NumRegisteredSignals].SA); 00101 RegisteredSignalInfo[NumRegisteredSignals].SigNo = Signal; 00102 ++NumRegisteredSignals; 00103 } 00104 00105 static void RegisterHandlers() { 00106 // If the handlers are already registered, we're done. 00107 if (NumRegisteredSignals != 0) return; 00108 00109 for (auto S : IntSigs) RegisterHandler(S); 00110 for (auto S : KillSigs) RegisterHandler(S); 00111 } 00112 00113 static void UnregisterHandlers() { 00114 // Restore all of the signal handlers to how they were before we showed up. 00115 for (unsigned i = 0, e = NumRegisteredSignals; i != e; ++i) 00116 sigaction(RegisteredSignalInfo[i].SigNo, 00117 &RegisteredSignalInfo[i].SA, nullptr); 00118 NumRegisteredSignals = 0; 00119 } 00120 00121 00122 /// RemoveFilesToRemove - Process the FilesToRemove list. This function 00123 /// should be called with the SignalsMutex lock held. 00124 /// NB: This must be an async signal safe function. It cannot allocate or free 00125 /// memory, even in debug builds. 00126 static void RemoveFilesToRemove() { 00127 // We avoid iterators in case of debug iterators that allocate or release 00128 // memory. 00129 std::vector<std::string>& FilesToRemoveRef = *FilesToRemove; 00130 for (unsigned i = 0, e = FilesToRemoveRef.size(); i != e; ++i) { 00131 // We rely on a std::string implementation for which repeated calls to 00132 // 'c_str()' don't allocate memory. We pre-call 'c_str()' on all of these 00133 // strings to try to ensure this is safe. 00134 const char *path = FilesToRemoveRef[i].c_str(); 00135 00136 // Get the status so we can determine if it's a file or directory. If we 00137 // can't stat the file, ignore it. 00138 struct stat buf; 00139 if (stat(path, &buf) != 0) 00140 continue; 00141 00142 // If this is not a regular file, ignore it. We want to prevent removal of 00143 // special files like /dev/null, even if the compiler is being run with the 00144 // super-user permissions. 00145 if (!S_ISREG(buf.st_mode)) 00146 continue; 00147 00148 // Otherwise, remove the file. We ignore any errors here as there is nothing 00149 // else we can do. 00150 unlink(path); 00151 } 00152 } 00153 00154 // SignalHandler - The signal handler that runs. 00155 static RETSIGTYPE SignalHandler(int Sig) { 00156 // Restore the signal behavior to default, so that the program actually 00157 // crashes when we return and the signal reissues. This also ensures that if 00158 // we crash in our signal handler that the program will terminate immediately 00159 // instead of recursing in the signal handler. 00160 UnregisterHandlers(); 00161 00162 // Unmask all potentially blocked kill signals. 00163 sigset_t SigMask; 00164 sigfillset(&SigMask); 00165 sigprocmask(SIG_UNBLOCK, &SigMask, nullptr); 00166 00167 { 00168 unique_lock<SmartMutex<true>> Guard(*SignalsMutex); 00169 RemoveFilesToRemove(); 00170 00171 if (std::find(std::begin(IntSigs), std::end(IntSigs), Sig) 00172 != std::end(IntSigs)) { 00173 if (InterruptFunction) { 00174 void (*IF)() = InterruptFunction; 00175 Guard.unlock(); 00176 InterruptFunction = nullptr; 00177 IF(); // run the interrupt function. 00178 return; 00179 } 00180 00181 Guard.unlock(); 00182 raise(Sig); // Execute the default handler. 00183 return; 00184 } 00185 } 00186 00187 // Otherwise if it is a fault (like SEGV) run any handler. 00188 std::vector<std::pair<void (*)(void *), void *>>& CallBacksToRunRef = 00189 *CallBacksToRun; 00190 for (unsigned i = 0, e = CallBacksToRun->size(); i != e; ++i) 00191 CallBacksToRunRef[i].first(CallBacksToRunRef[i].second); 00192 00193 #ifdef __s390__ 00194 // On S/390, certain signals are delivered with PSW Address pointing to 00195 // *after* the faulting instruction. Simply returning from the signal 00196 // handler would continue execution after that point, instead of 00197 // re-raising the signal. Raise the signal manually in those cases. 00198 if (Sig == SIGILL || Sig == SIGFPE || Sig == SIGTRAP) 00199 raise(Sig); 00200 #endif 00201 } 00202 00203 void llvm::sys::RunInterruptHandlers() { 00204 sys::SmartScopedLock<true> Guard(*SignalsMutex); 00205 RemoveFilesToRemove(); 00206 } 00207 00208 void llvm::sys::SetInterruptFunction(void (*IF)()) { 00209 { 00210 sys::SmartScopedLock<true> Guard(*SignalsMutex); 00211 InterruptFunction = IF; 00212 } 00213 RegisterHandlers(); 00214 } 00215 00216 // RemoveFileOnSignal - The public API 00217 bool llvm::sys::RemoveFileOnSignal(StringRef Filename, 00218 std::string* ErrMsg) { 00219 { 00220 sys::SmartScopedLock<true> Guard(*SignalsMutex); 00221 std::vector<std::string>& FilesToRemoveRef = *FilesToRemove; 00222 std::string *OldPtr = 00223 FilesToRemoveRef.empty() ? nullptr : &FilesToRemoveRef[0]; 00224 FilesToRemoveRef.push_back(Filename); 00225 00226 // We want to call 'c_str()' on every std::string in this vector so that if 00227 // the underlying implementation requires a re-allocation, it happens here 00228 // rather than inside of the signal handler. If we see the vector grow, we 00229 // have to call it on every entry. If it remains in place, we only need to 00230 // call it on the latest one. 00231 if (OldPtr == &FilesToRemoveRef[0]) 00232 FilesToRemoveRef.back().c_str(); 00233 else 00234 for (unsigned i = 0, e = FilesToRemoveRef.size(); i != e; ++i) 00235 FilesToRemoveRef[i].c_str(); 00236 } 00237 00238 RegisterHandlers(); 00239 return false; 00240 } 00241 00242 // DontRemoveFileOnSignal - The public API 00243 void llvm::sys::DontRemoveFileOnSignal(StringRef Filename) { 00244 sys::SmartScopedLock<true> Guard(*SignalsMutex); 00245 std::vector<std::string>::reverse_iterator RI = 00246 std::find(FilesToRemove->rbegin(), FilesToRemove->rend(), Filename); 00247 std::vector<std::string>::iterator I = FilesToRemove->end(); 00248 if (RI != FilesToRemove->rend()) 00249 I = FilesToRemove->erase(RI.base()-1); 00250 00251 // We need to call c_str() on every element which would have been moved by 00252 // the erase. These elements, in a C++98 implementation where c_str() 00253 // requires a reallocation on the first call may have had the call to c_str() 00254 // made on insertion become invalid by being copied down an element. 00255 for (std::vector<std::string>::iterator E = FilesToRemove->end(); I != E; ++I) 00256 I->c_str(); 00257 } 00258 00259 /// AddSignalHandler - Add a function to be called when a signal is delivered 00260 /// to the process. The handler can have a cookie passed to it to identify 00261 /// what instance of the handler it is. 00262 void llvm::sys::AddSignalHandler(void (*FnPtr)(void *), void *Cookie) { 00263 CallBacksToRun->push_back(std::make_pair(FnPtr, Cookie)); 00264 RegisterHandlers(); 00265 } 00266 00267 00268 // PrintStackTrace - In the case of a program crash or fault, print out a stack 00269 // trace so that the user has an indication of why and where we died. 00270 // 00271 // On glibc systems we have the 'backtrace' function, which works nicely, but 00272 // doesn't demangle symbols. 00273 void llvm::sys::PrintStackTrace(FILE *FD) { 00274 #if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES) 00275 static void* StackTrace[256]; 00276 // Use backtrace() to output a backtrace on Linux systems with glibc. 00277 int depth = backtrace(StackTrace, 00278 static_cast<int>(array_lengthof(StackTrace))); 00279 #if HAVE_DLFCN_H && __GNUG__ 00280 int width = 0; 00281 for (int i = 0; i < depth; ++i) { 00282 Dl_info dlinfo; 00283 dladdr(StackTrace[i], &dlinfo); 00284 const char* name = strrchr(dlinfo.dli_fname, '/'); 00285 00286 int nwidth; 00287 if (!name) nwidth = strlen(dlinfo.dli_fname); 00288 else nwidth = strlen(name) - 1; 00289 00290 if (nwidth > width) width = nwidth; 00291 } 00292 00293 for (int i = 0; i < depth; ++i) { 00294 Dl_info dlinfo; 00295 dladdr(StackTrace[i], &dlinfo); 00296 00297 fprintf(FD, "%-2d", i); 00298 00299 const char* name = strrchr(dlinfo.dli_fname, '/'); 00300 if (!name) fprintf(FD, " %-*s", width, dlinfo.dli_fname); 00301 else fprintf(FD, " %-*s", width, name+1); 00302 00303 fprintf(FD, " %#0*lx", 00304 (int)(sizeof(void*) * 2) + 2, (unsigned long)StackTrace[i]); 00305 00306 if (dlinfo.dli_sname != nullptr) { 00307 fputc(' ', FD); 00308 # if HAVE_CXXABI_H 00309 int res; 00310 char* d = abi::__cxa_demangle(dlinfo.dli_sname, nullptr, nullptr, &res); 00311 # else 00312 char* d = NULL; 00313 # endif 00314 if (!d) fputs(dlinfo.dli_sname, FD); 00315 else fputs(d, FD); 00316 free(d); 00317 00318 // FIXME: When we move to C++11, use %t length modifier. It's not in 00319 // C++03 and causes gcc to issue warnings. Losing the upper 32 bits of 00320 // the stack offset for a stack dump isn't likely to cause any problems. 00321 fprintf(FD, " + %u",(unsigned)((char*)StackTrace[i]- 00322 (char*)dlinfo.dli_saddr)); 00323 } 00324 fputc('\n', FD); 00325 } 00326 #else 00327 backtrace_symbols_fd(StackTrace, depth, STDERR_FILENO); 00328 #endif 00329 #endif 00330 } 00331 00332 static void PrintStackTraceSignalHandler(void *) { 00333 PrintStackTrace(stderr); 00334 } 00335 00336 /// PrintStackTraceOnErrorSignal - When an error signal (such as SIGABRT or 00337 /// SIGSEGV) is delivered to the process, print a stack trace and then exit. 00338 void llvm::sys::PrintStackTraceOnErrorSignal() { 00339 AddSignalHandler(PrintStackTraceSignalHandler, nullptr); 00340 00341 #if defined(__APPLE__) && defined(ENABLE_CRASH_OVERRIDES) 00342 // Environment variable to disable any kind of crash dialog. 00343 if (getenv("LLVM_DISABLE_CRASH_REPORT")) { 00344 mach_port_t self = mach_task_self(); 00345 00346 exception_mask_t mask = EXC_MASK_CRASH; 00347 00348 kern_return_t ret = task_set_exception_ports(self, 00349 mask, 00350 MACH_PORT_NULL, 00351 EXCEPTION_STATE_IDENTITY | MACH_EXCEPTION_CODES, 00352 THREAD_STATE_NONE); 00353 (void)ret; 00354 } 00355 #endif 00356 } 00357 00358 00359 /***/ 00360 00361 // On Darwin, raise sends a signal to the main thread instead of the current 00362 // thread. This has the unfortunate effect that assert() and abort() will end up 00363 // bypassing our crash recovery attempts. We work around this for anything in 00364 // the same linkage unit by just defining our own versions of the assert handler 00365 // and abort. 00366 00367 #if defined(__APPLE__) && defined(ENABLE_CRASH_OVERRIDES) 00368 00369 #include <signal.h> 00370 #include <pthread.h> 00371 00372 int raise(int sig) { 00373 return pthread_kill(pthread_self(), sig); 00374 } 00375 00376 void __assert_rtn(const char *func, 00377 const char *file, 00378 int line, 00379 const char *expr) { 00380 if (func) 00381 fprintf(stderr, "Assertion failed: (%s), function %s, file %s, line %d.\n", 00382 expr, func, file, line); 00383 else 00384 fprintf(stderr, "Assertion failed: (%s), file %s, line %d.\n", 00385 expr, file, line); 00386 abort(); 00387 } 00388 00389 void abort() { 00390 raise(SIGABRT); 00391 usleep(1000); 00392 __builtin_trap(); 00393 } 00394 00395 #endif