forked from OSchip/llvm-project
[sanitizer] 2-nd attempt. Add the flag handle_sigfpe that is default true to handle SIGFPE crashes same as SIGSEV crashes, patch by Karl Skomski. This time the test is enabled only on x86-64 (it broke on ARM)
llvm-svn: 244234
This commit is contained in:
parent
22eb71056d
commit
cc9fd3cbe9
|
@ -75,7 +75,7 @@ void *AsanDoesNotSupportStaticLinkage();
|
|||
void AsanCheckDynamicRTPrereqs();
|
||||
void AsanCheckIncompatibleRT();
|
||||
|
||||
void AsanOnSIGSEGV(int, void *siginfo, void *context);
|
||||
void AsanOnDeadlySignal(int, void *siginfo, void *context);
|
||||
|
||||
void DisableReexec();
|
||||
void MaybeReexec();
|
||||
|
|
|
@ -33,11 +33,11 @@
|
|||
|
||||
namespace __asan {
|
||||
|
||||
void AsanOnSIGSEGV(int, void *siginfo, void *context) {
|
||||
void AsanOnDeadlySignal(int signo, void *siginfo, void *context) {
|
||||
ScopedDeadlySignal signal_scope(GetCurrentThread());
|
||||
int code = (int)((siginfo_t*)siginfo)->si_code;
|
||||
// Write the first message using the bullet-proof write.
|
||||
if (13 != internal_write(2, "ASAN:SIGSEGV\n", 13)) Die();
|
||||
if (18 != internal_write(2, "ASAN:DEADLYSIGNAL\n", 18)) Die();
|
||||
SignalContext sig = SignalContext::Create(siginfo, context);
|
||||
|
||||
// Access at a reasonable offset above SP, or slightly below it (to account
|
||||
|
@ -75,8 +75,10 @@ void AsanOnSIGSEGV(int, void *siginfo, void *context) {
|
|||
// unaligned memory access.
|
||||
if (IsStackAccess && (code == si_SEGV_MAPERR || code == si_SEGV_ACCERR))
|
||||
ReportStackOverflow(sig);
|
||||
else if (signo == SIGFPE)
|
||||
ReportDeadlySignal("FPE", sig);
|
||||
else
|
||||
ReportSIGSEGV("SEGV", sig);
|
||||
ReportDeadlySignal("SEGV", sig);
|
||||
}
|
||||
|
||||
// ---------------------- TSD ---------------- {{{1
|
||||
|
|
|
@ -686,7 +686,7 @@ void ReportStackOverflow(const SignalContext &sig) {
|
|||
ReportErrorSummary("stack-overflow", &stack);
|
||||
}
|
||||
|
||||
void ReportSIGSEGV(const char *description, const SignalContext &sig) {
|
||||
void ReportDeadlySignal(const char *description, const SignalContext &sig) {
|
||||
ScopedInErrorReport in_report;
|
||||
Decorator d;
|
||||
Printf("%s", d.Warning());
|
||||
|
@ -703,7 +703,7 @@ void ReportSIGSEGV(const char *description, const SignalContext &sig) {
|
|||
stack.Print();
|
||||
MaybeDumpInstructionBytes(sig.pc);
|
||||
Printf("AddressSanitizer can not provide additional info.\n");
|
||||
ReportErrorSummary("SEGV", &stack);
|
||||
ReportErrorSummary(description, &stack);
|
||||
}
|
||||
|
||||
void ReportDoubleFree(uptr addr, BufferedStackTrace *free_stack) {
|
||||
|
|
|
@ -50,7 +50,8 @@ void DescribeThread(AsanThreadContext *context);
|
|||
|
||||
// Different kinds of error reports.
|
||||
void NORETURN ReportStackOverflow(const SignalContext &sig);
|
||||
void NORETURN ReportSIGSEGV(const char *description, const SignalContext &sig);
|
||||
void NORETURN ReportDeadlySignal(const char* description,
|
||||
const SignalContext &sig);
|
||||
void NORETURN ReportNewDeleteSizeMismatch(uptr addr, uptr delete_size,
|
||||
BufferedStackTrace *free_stack);
|
||||
void NORETURN ReportDoubleFree(uptr addr, BufferedStackTrace *free_stack);
|
||||
|
|
|
@ -457,7 +457,7 @@ static void AsanInitInternal() {
|
|||
}
|
||||
|
||||
AsanTSDInit(PlatformTSDDtor);
|
||||
InstallDeadlySignalHandlers(AsanOnSIGSEGV);
|
||||
InstallDeadlySignalHandlers(AsanOnDeadlySignal);
|
||||
|
||||
AllocatorOptions allocator_options;
|
||||
allocator_options.SetFrom(flags(), common_flags());
|
||||
|
|
|
@ -197,7 +197,7 @@ void ReadContextStack(void *context, uptr *stack, uptr *ssize) {
|
|||
UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
void AsanOnSIGSEGV(int, void *siginfo, void *context) {
|
||||
void AsanOnDeadlySignal(int, void *siginfo, void *context) {
|
||||
UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
|
@ -214,7 +214,7 @@ static long WINAPI SEHHandler(EXCEPTION_POINTERS *info) {
|
|||
? "access-violation"
|
||||
: "in-page-error";
|
||||
SignalContext sig = SignalContext::Create(exception_record, context);
|
||||
ReportSIGSEGV(description, sig);
|
||||
ReportDeadlySignal(description, sig);
|
||||
}
|
||||
|
||||
// FIXME: Handle EXCEPTION_STACK_OVERFLOW here.
|
||||
|
|
|
@ -250,12 +250,12 @@ TEST(AddressSanitizer, BitFieldNegativeTest) {
|
|||
#if ASAN_NEEDS_SEGV
|
||||
namespace {
|
||||
|
||||
const char kUnknownCrash[] = "AddressSanitizer: SEGV on unknown address";
|
||||
const char kSEGVCrash[] = "AddressSanitizer: SEGV on unknown address";
|
||||
const char kOverriddenHandler[] = "ASan signal handler has been overridden\n";
|
||||
|
||||
TEST(AddressSanitizer, WildAddressTest) {
|
||||
char *c = (char*)0x123;
|
||||
EXPECT_DEATH(*c = 0, kUnknownCrash);
|
||||
EXPECT_DEATH(*c = 0, kSEGVCrash);
|
||||
}
|
||||
|
||||
void my_sigaction_sighandler(int, siginfo_t*, void*) {
|
||||
|
@ -279,10 +279,10 @@ TEST(AddressSanitizer, SignalTest) {
|
|||
EXPECT_EQ(0, sigaction(SIGBUS, &sigact, 0));
|
||||
#endif
|
||||
char *c = (char*)0x123;
|
||||
EXPECT_DEATH(*c = 0, kUnknownCrash);
|
||||
EXPECT_DEATH(*c = 0, kSEGVCrash);
|
||||
// ... and signal().
|
||||
EXPECT_EQ(0, signal(SIGSEGV, my_signal_sighandler));
|
||||
EXPECT_DEATH(*c = 0, kUnknownCrash);
|
||||
EXPECT_DEATH(*c = 0, kSEGVCrash);
|
||||
}
|
||||
} // namespace
|
||||
#endif
|
||||
|
|
|
@ -78,6 +78,8 @@ COMMON_FLAG(bool, handle_segv, SANITIZER_NEEDS_SEGV,
|
|||
"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, handle_sigfpe, true,
|
||||
"If set, registers the tool's custom SIGFPE handler.")
|
||||
COMMON_FLAG(bool, allow_user_segv_handler, false,
|
||||
"If set, allows user to register a SEGV handler even if the tool "
|
||||
"registers one.")
|
||||
|
|
|
@ -1034,6 +1034,8 @@ AndroidApiLevel AndroidGetApiLevel() {
|
|||
bool IsDeadlySignal(int signum) {
|
||||
if (common_flags()->handle_abort && signum == SIGABRT)
|
||||
return true;
|
||||
if (common_flags()->handle_sigfpe && signum == SIGFPE)
|
||||
return true;
|
||||
return (signum == SIGSEGV || signum == SIGBUS) && common_flags()->handle_segv;
|
||||
}
|
||||
|
||||
|
|
|
@ -188,6 +188,7 @@ void InstallDeadlySignalHandlers(SignalHandlerType handler) {
|
|||
MaybeInstallSigaction(SIGSEGV, handler);
|
||||
MaybeInstallSigaction(SIGBUS, handler);
|
||||
MaybeInstallSigaction(SIGABRT, handler);
|
||||
MaybeInstallSigaction(SIGFPE, handler);
|
||||
}
|
||||
#endif // SANITIZER_GO
|
||||
|
||||
|
|
|
@ -55,5 +55,5 @@ int main() {
|
|||
|
||||
// CHECK: User sigaction installed
|
||||
// CHECK-NEXT: User sigaction called
|
||||
// CHECK-NEXT: ASAN:SIGSEGV
|
||||
// CHECK-NEXT: ASAN:DEADLYSIGNAL
|
||||
// CHECK: AddressSanitizer: SEGV on unknown address
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
// Test the handle_sigfpe option.
|
||||
// RUN: %clang %s -o %t
|
||||
// RUN: not %run %t 2>&1 | FileCheck --check-prefix=CHECK1 %s
|
||||
// RUN: %tool_options=handle_sigfpe=0 not --crash %run %t 2>&1 | FileCheck --check-prefix=CHECK0 %s
|
||||
// RUN: %tool_options=handle_sigfpe=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
|
||||
//
|
||||
// FIXME: seems to fail on ARM
|
||||
// REQUIRES: x86_64-supported-target
|
||||
#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);
|
||||
volatile int one = 1;
|
||||
volatile int zero = 0;
|
||||
volatile int sink;
|
||||
sink = one / zero;
|
||||
}
|
||||
// CHECK1: ERROR: {{.*}}Sanitizer:
|
||||
// CHECK1: DEATH CALLBACK
|
||||
// CHECK0-NOT: Sanitizer
|
Loading…
Reference in New Issue