Allow users to call ASan's deadly exception report mechanism

Users often have their own unhandled exception filters installed. ASan
already goes to great lengths to install its own filter, but our core
wars with Chrome crashpad have escalated to the point that its time to
declare a truce. By exposing this hook, they can call us directly when
they want ASan crash reporting without worrying about who initializes
when.

llvm-svn: 287040
This commit is contained in:
Reid Kleckner 2016-11-15 21:54:58 +00:00
parent 26168ad5c5
commit c9b27ba11d
2 changed files with 25 additions and 16 deletions

View File

@ -293,17 +293,25 @@ const char *DescribeSignalOrException(int signo) {
return nullptr;
}
static long WINAPI SEHHandler(EXCEPTION_POINTERS *info) {
extern "C" SANITIZER_INTERFACE_ATTRIBUTE
long __asan_unhandled_exception_filter(EXCEPTION_POINTERS *info) {
EXCEPTION_RECORD *exception_record = info->ExceptionRecord;
CONTEXT *context = info->ContextRecord;
if (ShouldReportDeadlyException(exception_record->ExceptionCode)) {
SignalContext sig = SignalContext::Create(exception_record, context);
ReportDeadlySignal(exception_record->ExceptionCode, sig);
}
// Continue the search if the signal wasn't deadly.
if (!ShouldReportDeadlyException(exception_record->ExceptionCode))
return EXCEPTION_CONTINUE_SEARCH;
// FIXME: Handle EXCEPTION_STACK_OVERFLOW here.
SignalContext sig = SignalContext::Create(exception_record, context);
ReportDeadlySignal(exception_record->ExceptionCode, sig);
UNREACHABLE("returned from reporting deadly signal");
}
static long WINAPI SEHHandler(EXCEPTION_POINTERS *info) {
__asan_unhandled_exception_filter(info);
// Bubble out to the default exception filter.
return default_seh_handler(info);
}

View File

@ -23,10 +23,16 @@
#include "interception/interception.h"
#include "sanitizer_common/sanitizer_platform_interceptors.h"
#ifdef _M_IX86
#define WINAPI __stdcall
#else
#define WINAPI
#endif
// ---------- Function interception helper functions and macros ----------- {{{1
extern "C" {
void *__stdcall GetModuleHandleA(const char *module_name);
void *__stdcall GetProcAddress(void *module, const char *proc_name);
void *WINAPI GetModuleHandleA(const char *module_name);
void *WINAPI GetProcAddress(void *module, const char *proc_name);
void abort();
}
@ -229,6 +235,7 @@ extern "C" void __asan_version_mismatch_check() {
}
INTERFACE_FUNCTION(__asan_handle_no_return)
INTERFACE_FUNCTION(__asan_unhandled_exception_filter)
INTERFACE_FUNCTION(__asan_report_store1)
INTERFACE_FUNCTION(__asan_report_store2)
@ -456,19 +463,13 @@ static int call_asan_init() {
#pragma section(".CRT$XIB", long, read) // NOLINT
__declspec(allocate(".CRT$XIB")) int (*__asan_preinit)() = call_asan_init;
#ifdef _M_IX86
#define NTAPI __stdcall
#else
#define NTAPI
#endif
static void NTAPI asan_thread_init(void *mod, unsigned long reason,
static void WINAPI asan_thread_init(void *mod, unsigned long reason,
void *reserved) {
if (reason == /*DLL_PROCESS_ATTACH=*/1) __asan_init();
}
#pragma section(".CRT$XLAB", long, read) // NOLINT
__declspec(allocate(".CRT$XLAB")) void (NTAPI *__asan_tls_init)(void *,
__declspec(allocate(".CRT$XLAB")) void (WINAPI *__asan_tls_init)(void *,
unsigned long, void *) = asan_thread_init;
#endif // ASAN_DLL_THUNK