[asan] under handle_abort=1 option intercept SIGABRT in addition to SIGSEGV/SIGBUS. Among other things this will allow to set up a death callback for SIGABRT and thus properly handle assert() in lib/Fuzzer

llvm-svn: 236474
This commit is contained in:
Kostya Serebryany
2015-05-05 01:37:33 +00:00
parent e32f2b57ff
commit b044353bb2
4 changed files with 30 additions and 2 deletions

View File

@@ -67,8 +67,9 @@ COMMON_FLAG(bool, print_summary, true,
"reports.")
COMMON_FLAG(bool, check_printf, true, "Check printf arguments.")
COMMON_FLAG(bool, handle_segv, SANITIZER_NEEDS_SEGV,
"If set, registers the tool's custom SEGV handler (both SIGBUS and "
"SIGSEGV on OSX).")
"If set, registers the tool's custom SIGSEGV/SIGBUS handler.")
COMMON_FLAG(bool, handle_abort, false,
"If set, registers the tool's custom SIGABRT handler.")
COMMON_FLAG(bool, allow_user_segv_handler, false,
"If set, allows user to register a SEGV handler even if the tool "
"registers one.")

View File

@@ -907,6 +907,8 @@ void GetExtraActivationFlags(char *buf, uptr size) {
#endif
bool IsDeadlySignal(int signum) {
if (common_flags()->handle_abort)
return signum == SIGABRT;
return (signum == SIGSEGV || signum == SIGBUS) && common_flags()->handle_segv;
}

View File

@@ -178,6 +178,7 @@ void InstallDeadlySignalHandlers(SignalHandlerType handler) {
if (common_flags()->use_sigaltstack) SetAlternateSignalStack();
MaybeInstallSigaction(SIGSEGV, handler);
MaybeInstallSigaction(SIGBUS, handler);
MaybeInstallSigaction(SIGABRT, handler);
}
#endif // SANITIZER_GO

View File

@@ -0,0 +1,24 @@
// Test the handle_abort option.
// RUN: %clang %s -o %t
// RUN: not --crash %run %t 2>&1 | FileCheck --check-prefix=CHECK0 %s
// RUN: %tool_options=handle_abort=0 not --crash %run %t 2>&1 | FileCheck --check-prefix=CHECK0 %s
// RUN: %tool_options=handle_abort=1 not %run %t 2>&1 | FileCheck --check-prefix=CHECK1 %s
// FIXME: implement in other sanitizers, not just asan.
// XFAIL: msan
// XFAIL: lsan
// XFAIL: tsan
#include <assert.h>
#include <stdio.h>
#include <sanitizer/asan_interface.h>
void death() {
fprintf(stderr, "DEATH CALLBACK\n");
}
int main(int argc, char **argv) {
__sanitizer_set_death_callback(death);
assert(argc == 100);
}
// CHECK1: ERROR: {{.*}}Sanitizer:
// CHECK1: DEATH CALLBACK
// CHECK0-NOT: Sanitizer