diff options
author | Reid Kleckner <rnk@google.com> | 2016-08-03 18:13:14 +0000 |
---|---|---|
committer | Reid Kleckner <rnk@google.com> | 2016-08-03 18:13:14 +0000 |
commit | c081bfe418eb647ae8f90875299c9c768bec261e (patch) | |
tree | 66d180d50255a6a91d32b77aaab0cda63e749ac4 | |
parent | b777b81c57f36e971cfd4aad660b21b08b18be73 (diff) | |
download | compiler-rt-c081bfe418eb647ae8f90875299c9c768bec261e.tar.gz |
[ASan] Report illegal instruction exceptions in ASan
Summary:
Respect the handle_sigill common flag and handle_segv flags while we're
at it.
We still handle signals/exceptions differently on Unix and Windows. The
installation process is tricky on Windows, and difficult to push down
into sanitizer_common without concerning it with the different
static/dynamic CRT models on Windows.
Reviewers: kcc, etienneb
Subscribers: llvm-commits, kubabrecka
Differential Revision: https://reviews.llvm.org/D23098
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@277621 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/asan/asan_win.cc | 38 | ||||
-rw-r--r-- | lib/sanitizer_common/CMakeLists.txt | 8 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_flags.cc | 5 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_flags.inc | 2 | ||||
-rw-r--r-- | test/asan/TestCases/ill.cc | 25 |
5 files changed, 59 insertions, 19 deletions
diff --git a/lib/asan/asan_win.cc b/lib/asan/asan_win.cc index 8857506d5..cb038212e 100644 --- a/lib/asan/asan_win.cc +++ b/lib/asan/asan_win.cc @@ -247,16 +247,44 @@ void InitializePlatformExceptionHandlers() { static LPTOP_LEVEL_EXCEPTION_FILTER default_seh_handler; +// Check based on flags if we should report this exception. +static bool ShouldReportDeadlyException(unsigned code) { + switch (code) { + case EXCEPTION_ACCESS_VIOLATION: + case EXCEPTION_IN_PAGE_ERROR: + return common_flags()->handle_segv; + case EXCEPTION_BREAKPOINT: + case EXCEPTION_ILLEGAL_INSTRUCTION: { + return common_flags()->handle_sigill; + } + } + return false; +} + +// Return the textual name for this exception. +static const char *DescribeDeadlyException(unsigned code) { + switch (code) { + case EXCEPTION_ACCESS_VIOLATION: + return "access-violation"; + case EXCEPTION_IN_PAGE_ERROR: + return "in-page-error"; + case EXCEPTION_BREAKPOINT: + return "breakpoint"; + case EXCEPTION_ILLEGAL_INSTRUCTION: + return "illegal-instruction"; + } + return nullptr; +} + static long WINAPI SEHHandler(EXCEPTION_POINTERS *info) { EXCEPTION_RECORD *exception_record = info->ExceptionRecord; CONTEXT *context = info->ContextRecord; - if (exception_record->ExceptionCode == EXCEPTION_ACCESS_VIOLATION || - exception_record->ExceptionCode == EXCEPTION_IN_PAGE_ERROR) { + if (ShouldReportDeadlyException(exception_record->ExceptionCode)) { + // Get the string description of the exception if this is a known deadly + // exception. const char *description = - (exception_record->ExceptionCode == EXCEPTION_ACCESS_VIOLATION) - ? "access-violation" - : "in-page-error"; + DescribeDeadlyException(exception_record->ExceptionCode); SignalContext sig = SignalContext::Create(exception_record, context); ReportDeadlySignal(description, sig); } diff --git a/lib/sanitizer_common/CMakeLists.txt b/lib/sanitizer_common/CMakeLists.txt index 9a140be45..59a6b3511 100644 --- a/lib/sanitizer_common/CMakeLists.txt +++ b/lib/sanitizer_common/CMakeLists.txt @@ -126,14 +126,6 @@ set(SANITIZER_HEADERS set(SANITIZER_COMMON_DEFINITIONS) -if(MSVC) - list(APPEND SANITIZER_COMMON_DEFINITIONS - SANITIZER_NEEDS_SEGV=0) -else() - list(APPEND SANITIZER_COMMON_DEFINITIONS - SANITIZER_NEEDS_SEGV=1) -endif() - include(CheckIncludeFile) append_have_file_definition(rpc/xdr.h HAVE_RPC_XDR_H SANITIZER_COMMON_DEFINITIONS) append_have_file_definition(tirpc/rpc/xdr.h HAVE_TIRPC_RPC_XDR_H SANITIZER_COMMON_DEFINITIONS) diff --git a/lib/sanitizer_common/sanitizer_flags.cc b/lib/sanitizer_common/sanitizer_flags.cc index c2f19d425..913ce3cb4 100644 --- a/lib/sanitizer_common/sanitizer_flags.cc +++ b/lib/sanitizer_common/sanitizer_flags.cc @@ -30,11 +30,6 @@ struct FlagDescription { IntrusiveList<FlagDescription> flag_descriptions; -// If set, the tool will install its own SEGV signal handler by default. -#ifndef SANITIZER_NEEDS_SEGV -# define SANITIZER_NEEDS_SEGV 1 -#endif - void CommonFlags::SetDefaults() { #define COMMON_FLAG(Type, Name, DefaultValue, Description) Name = DefaultValue; #include "sanitizer_flags.inc" diff --git a/lib/sanitizer_common/sanitizer_flags.inc b/lib/sanitizer_common/sanitizer_flags.inc index 203f41ca3..450436a68 100644 --- a/lib/sanitizer_common/sanitizer_flags.inc +++ b/lib/sanitizer_common/sanitizer_flags.inc @@ -75,7 +75,7 @@ COMMON_FLAG(bool, print_summary, true, "If false, disable printing error summaries in addition to error " "reports.") COMMON_FLAG(bool, check_printf, true, "Check printf arguments.") -COMMON_FLAG(bool, handle_segv, SANITIZER_NEEDS_SEGV, +COMMON_FLAG(bool, handle_segv, true, "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.") diff --git a/test/asan/TestCases/ill.cc b/test/asan/TestCases/ill.cc new file mode 100644 index 000000000..d4f0bdd74 --- /dev/null +++ b/test/asan/TestCases/ill.cc @@ -0,0 +1,25 @@ +// Test the handle_sigill option. +// +// RUN: %clangxx_asan %s -o %t && %env_asan_opts=handle_sigill=0 not --crash %run %t 2>&1 | FileCheck %s --check-prefix=CHECK0 +// RUN: %clangxx_asan %s -o %t && %env_asan_opts=handle_sigill=1 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK1 + +#ifdef _WIN32 +#include <windows.h> +#endif + +int main() { +#ifdef _WIN32 + // Sometimes on Windows this test generates a WER fault dialog. Suppress that. + UINT new_flags = SEM_FAILCRITICALERRORS | + SEM_NOGPFAULTERRORBOX | + SEM_NOOPENFILEERRORBOX; + // Preserve existing error mode, as discussed at + // http://blogs.msdn.com/oldnewthing/archive/2004/07/27/198410.aspx + UINT existing_flags = SetErrorMode(new_flags); + SetErrorMode(existing_flags | new_flags); +#endif + + __builtin_trap(); +} +// CHECK0-NOT: ERROR: AddressSanitizer +// CHECK1: ERROR: AddressSanitizer: {{ILL|illegal-instruction}} on unknown address {{0x0*}} |