diff options
author | Evgeniy Stepanov <eugeni.stepanov@gmail.com> | 2013-04-05 11:59:16 +0000 |
---|---|---|
committer | Evgeniy Stepanov <eugeni.stepanov@gmail.com> | 2013-04-05 11:59:16 +0000 |
commit | a213ab66e1c743ec7a52af4a49ec6c126cc245ae (patch) | |
tree | d22d0d5ac5d758aa2b8656859be0069e30d7b4a7 | |
parent | 48cab523ef7a35ec8417b3fef8d41cfd581590b3 (diff) |
[msan] A runtime option to disable wrapping of signal handlers.
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@178865 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/msan/msan.cc | 2 | ||||
-rw-r--r-- | lib/msan/msan_flags.h | 1 | ||||
-rw-r--r-- | lib/msan/msan_interceptors.cc | 55 |
3 files changed, 37 insertions, 21 deletions
diff --git a/lib/msan/msan.cc b/lib/msan/msan.cc index 6470144df..dd5e31b34 100644 --- a/lib/msan/msan.cc +++ b/lib/msan/msan.cc @@ -129,6 +129,7 @@ static void ParseFlagsFromString(Flags *f, const char *str) { ParseFlag(str, &f->strip_path_prefix, "strip_path_prefix"); ParseFlag(str, &f->fast_unwind_on_fatal, "fast_unwind_on_fatal"); ParseFlag(str, &f->fast_unwind_on_malloc, "fast_unwind_on_malloc"); + ParseFlag(str, &f->wrap_signals, "wrap_signals"); } static void InitializeFlags(Flags *f, const char *options) { @@ -144,6 +145,7 @@ static void InitializeFlags(Flags *f, const char *options) { f->strip_path_prefix = ""; f->fast_unwind_on_fatal = false; f->fast_unwind_on_malloc = true; + f->wrap_signals = true; // Override from user-specified string. if (__msan_default_options) diff --git a/lib/msan/msan_flags.h b/lib/msan/msan_flags.h index cfaf96327..dfad8a421 100644 --- a/lib/msan/msan_flags.h +++ b/lib/msan/msan_flags.h @@ -30,6 +30,7 @@ struct Flags { bool fast_unwind_on_fatal; // Use fast (frame-pointer-based) unwinder on malloc/free (if available). bool fast_unwind_on_malloc; + bool wrap_signals; }; Flags *flags(); diff --git a/lib/msan/msan_interceptors.cc b/lib/msan/msan_interceptors.cc index 0ed00f658..d61075063 100644 --- a/lib/msan/msan_interceptors.cc +++ b/lib/msan/msan_interceptors.cc @@ -848,38 +848,51 @@ INTERCEPTOR(int, sigaction, int signo, const __sanitizer_sigaction *act, ENSURE_MSAN_INITED(); // FIXME: check that *act is unpoisoned. // That requires intercepting all of sigemptyset, sigfillset, etc. - SpinMutexLock lock(&sigactions_mu); - CHECK_LT(signo, kMaxSignals); - uptr old_cb = sigactions[signo]; - __sanitizer_sigaction new_act; - __sanitizer_sigaction *pnew_act = act ? &new_act : 0; - if (act) { - internal_memcpy(pnew_act, act, __sanitizer::struct_sigaction_sz); - uptr cb = __sanitizer::__sanitizer_get_sigaction_sa_sigaction(pnew_act); - uptr new_cb = __sanitizer::__sanitizer_get_sigaction_sa_siginfo(pnew_act) ? - (uptr)SignalAction : (uptr)SignalHandler; - if (cb != __sanitizer::sig_ign && cb != __sanitizer::sig_dfl) { - sigactions[signo] = cb; - __sanitizer::__sanitizer_set_sigaction_sa_sigaction(pnew_act, new_cb); + int res; + if (flags()->wrap_signals) { + SpinMutexLock lock(&sigactions_mu); + CHECK_LT(signo, kMaxSignals); + uptr old_cb = sigactions[signo]; + __sanitizer_sigaction new_act; + __sanitizer_sigaction *pnew_act = act ? &new_act : 0; + if (act) { + internal_memcpy(pnew_act, act, __sanitizer::struct_sigaction_sz); + uptr cb = __sanitizer::__sanitizer_get_sigaction_sa_sigaction(pnew_act); + uptr new_cb = + __sanitizer::__sanitizer_get_sigaction_sa_siginfo(pnew_act) ? + (uptr)SignalAction : (uptr)SignalHandler; + if (cb != __sanitizer::sig_ign && cb != __sanitizer::sig_dfl) { + sigactions[signo] = cb; + __sanitizer::__sanitizer_set_sigaction_sa_sigaction(pnew_act, new_cb); + } } + res = REAL(sigaction)(signo, pnew_act, oldact); + if (res == 0 && oldact) { + __sanitizer::__sanitizer_set_sigaction_sa_sigaction(oldact, old_cb); + } + } else { + res = REAL(sigaction)(signo, act, oldact); } - int res = REAL(sigaction)(signo, pnew_act, oldact); + if (res == 0 && oldact) { __msan_unpoison(oldact, __sanitizer::struct_sigaction_sz); - __sanitizer::__sanitizer_set_sigaction_sa_sigaction(oldact, old_cb); } return res; } INTERCEPTOR(int, signal, int signo, uptr cb) { ENSURE_MSAN_INITED(); - CHECK_LT(signo, kMaxSignals); - SpinMutexLock lock(&sigactions_mu); - if (cb != __sanitizer::sig_ign && cb != __sanitizer::sig_dfl) { - sigactions[signo] = cb; - cb = (uptr)SignalHandler; + if (flags()->wrap_signals) { + CHECK_LT(signo, kMaxSignals); + SpinMutexLock lock(&sigactions_mu); + if (cb != __sanitizer::sig_ign && cb != __sanitizer::sig_dfl) { + sigactions[signo] = cb; + cb = (uptr) SignalHandler; + } + return REAL(signal)(signo, cb); + } else { + return REAL(signal)(signo, cb); } - return REAL(signal)(signo, cb); } extern "C" int pthread_attr_init(void *attr); |