forked from OSchip/llvm-project
[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:
parent
0554d25eb3
commit
222610bf10
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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.")
|
||||
|
|
|
@ -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*}}
|
Loading…
Reference in New Issue