summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvgeniy Stepanov <eugeni.stepanov@gmail.com>2013-04-05 11:59:16 +0000
committerEvgeniy Stepanov <eugeni.stepanov@gmail.com>2013-04-05 11:59:16 +0000
commita213ab66e1c743ec7a52af4a49ec6c126cc245ae (patch)
treed22d0d5ac5d758aa2b8656859be0069e30d7b4a7
parent48cab523ef7a35ec8417b3fef8d41cfd581590b3 (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.cc2
-rw-r--r--lib/msan/msan_flags.h1
-rw-r--r--lib/msan/msan_interceptors.cc55
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);