diff options
Diffstat (limited to 'lib/Support/Unix/Signals.inc')
-rw-r--r-- | lib/Support/Unix/Signals.inc | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/lib/Support/Unix/Signals.inc b/lib/Support/Unix/Signals.inc index d6fe7861bb..cdb1be900b 100644 --- a/lib/Support/Unix/Signals.inc +++ b/lib/Support/Unix/Signals.inc @@ -27,10 +27,12 @@ #if HAVE_SYS_STAT_H #include <sys/stat.h> #endif -#if HAVE_DLFCN_H && __GNUG__ -#include <dlfcn.h> +#if HAVE_CXXABI_H #include <cxxabi.h> #endif +#if HAVE_DLFCN_H +#include <dlfcn.h> +#endif #if HAVE_MACH_MACH_H #include <mach/mach.h> #endif @@ -190,6 +192,15 @@ static RETSIGTYPE SignalHandler(int Sig) { // Otherwise if it is a fault (like SEGV) run any handler. for (unsigned i = 0, e = CallBacksToRun.size(); i != e; ++i) CallBacksToRun[i].first(CallBacksToRun[i].second); + +#ifdef __s390__ + // On S/390, certain signals are delivered with PSW Address pointing to + // *after* the faulting instruction. Simply returning from the signal + // handler would continue execution after that point, instead of + // re-raising the signal. Raise the signal manually in those cases. + if (Sig == SIGILL || Sig == SIGFPE || Sig == SIGTRAP) + raise(Sig); +#endif } void llvm::sys::RunInterruptHandlers() { @@ -296,9 +307,13 @@ void llvm::sys::PrintStackTrace(FILE *FD) { (int)(sizeof(void*) * 2) + 2, (unsigned long)StackTrace[i]); if (dlinfo.dli_sname != NULL) { - int res; fputc(' ', FD); +# if HAVE_CXXABI_H + int res; char* d = abi::__cxa_demangle(dlinfo.dli_sname, NULL, NULL, &res); +# else + char* d = NULL; +# endif if (d == NULL) fputs(dlinfo.dli_sname, FD); else fputs(d, FD); free(d); |