[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

llvm-svn: 277621
This commit is contained in:
Reid Kleckner 2016-08-03 18:13:14 +00:00
parent 0554d25eb3
commit 222610bf10
5 changed files with 59 additions and 19 deletions

View File

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

View File

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

View File

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

View File

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

View File

@ -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*}}