[msan] A runtime option to disable wrapping of signal handlers.

llvm-svn: 178865
This commit is contained in:
Evgeniy Stepanov 2013-04-05 11:59:16 +00:00
parent 2a4668557f
commit 7948c648bf
3 changed files with 37 additions and 21 deletions

View File

@ -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)

View File

@ -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();

View File

@ -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);