diff options
Diffstat (limited to 'lib/System/Unix/Signals.inc')
-rw-r--r-- | lib/System/Unix/Signals.inc | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/lib/System/Unix/Signals.inc b/lib/System/Unix/Signals.inc index 1e74647e5fdcb..7b7c43efc7864 100644 --- a/lib/System/Unix/Signals.inc +++ b/lib/System/Unix/Signals.inc @@ -182,6 +182,16 @@ bool llvm::sys::RemoveFileOnSignal(const sys::Path &Filename, return false; } +// DontRemoveFileOnSignal - The public API +void llvm::sys::DontRemoveFileOnSignal(const sys::Path &Filename) { + SignalsMutex.acquire(); + std::vector<sys::Path>::reverse_iterator I = + std::find(FilesToRemove.rbegin(), FilesToRemove.rend(), Filename); + if (I != FilesToRemove.rend()) + FilesToRemove.erase(I.base()-1); + SignalsMutex.release(); +} + /// AddSignalHandler - Add a function to be called when a signal is delivered /// to the process. The handler can have a cookie passed to it to identify /// what instance of the handler it is. @@ -253,3 +263,37 @@ void llvm::sys::PrintStackTraceOnErrorSignal() { AddSignalHandler(PrintStackTrace, 0); } + +/***/ + +// On Darwin, raise sends a signal to the main thread instead of the current +// thread. This has the unfortunate effect that assert() and abort() will end up +// bypassing our crash recovery attempts. We work around this for anything in +// the same linkage unit by just defining our own versions of the assert handler +// and abort. + +#ifdef __APPLE__ + +void __assert_rtn(const char *func, + const char *file, + int line, + const char *expr) { + if (func) + fprintf(stderr, "Assertion failed: (%s), function %s, file %s, line %d.\n", + expr, func, file, line); + else + fprintf(stderr, "Assertion failed: (%s), file %s, line %d.\n", + expr, file, line); + abort(); +} + +#include <signal.h> +#include <pthread.h> + +void abort() { + pthread_kill(pthread_self(), SIGABRT); + usleep(1000); + __builtin_trap(); +} + +#endif |