Index: lib/Fuzzer/afl/afl_driver.cpp =================================================================== --- lib/Fuzzer/afl/afl_driver.cpp +++ lib/Fuzzer/afl/afl_driver.cpp @@ -119,8 +119,11 @@ static const char *kExtraStatsFormatString = "peak_rss_mb : %u\n" "slowest_unit_time_sec : %u\n"; +void crash_handler(); + // Copied from FuzzerUtil.cpp. #if LIBFUZZER_POSIX + size_t GetPeakRSSMb() { struct rusage usage; if (getrusage(RUSAGE_SELF, &usage)) @@ -135,14 +138,6 @@ assert(0 && "GetPeakRSSMb() is not implemented for your platform"); return 0; } -#elif LIBFUZZER_WINDOWS -size_t GetPeakRSSMb() { - PROCESS_MEMORY_COUNTERS info; - if (!GetProcessMemoryInfo(GetCurrentProcess(), &info, sizeof(info))) - return 0; - return info.PeakWorkingSetSize >> 20; -} -#endif // Based on SetSigaction in FuzzerUtil.cpp static void SetSigaction(int signum, @@ -156,6 +151,84 @@ } } +static void SignalHandler(int, siginfo_t *, void *) { crash_handler(); } + +void SetCrashHandler() { + int crash_signals[] = {SIGSEGV, SIGBUS, SIGABRT, SIGILL, SIGFPE, SIGINT, + SIGTERM}; + + const size_t num_signals = sizeof(crash_signals) / sizeof(crash_signals[0]); + + for (size_t idx = 0; idx < num_signals; idx++) + SetSigaction(crash_signals[idx], SignalHandler); +} + +#elif LIBFUZZER_WINDOWS + +size_t GetPeakRSSMb() { + PROCESS_MEMORY_COUNTERS info; + if (!GetProcessMemoryInfo(GetCurrentProcess(), &info, sizeof(info))) + return 0; + return info.PeakWorkingSetSize >> 20; +} + +static void AbrtHandler(int) { crash_handler(); } + +BOOL WINAPI CtrlHandler(DWORD dwCtrlType) { + switch (dwCtrlType) { + case CTRL_C_EVENT: + case CTRL_BREAK_EVENT: + crash_handler(); + return TRUE; + } + return FALSE; +} + +LONG CALLBACK ExceptionHandler(PEXCEPTION_POINTERS ExceptionInfo) { + switch (ExceptionInfo->ExceptionRecord->ExceptionCode) { + case EXCEPTION_ACCESS_VIOLATION: + case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: + case EXCEPTION_STACK_OVERFLOW: + case EXCEPTION_DATATYPE_MISALIGNMENT: + case EXCEPTION_IN_PAGE_ERROR: + case EXCEPTION_ILLEGAL_INSTRUCTION: + case EXCEPTION_PRIV_INSTRUCTION: + case EXCEPTION_FLT_DENORMAL_OPERAND: + case EXCEPTION_FLT_DIVIDE_BY_ZERO: + case EXCEPTION_FLT_INEXACT_RESULT: + case EXCEPTION_FLT_INVALID_OPERATION: + case EXCEPTION_FLT_OVERFLOW: + case EXCEPTION_FLT_STACK_CHECK: + case EXCEPTION_FLT_UNDERFLOW: + case EXCEPTION_INT_DIVIDE_BY_ZERO: + case EXCEPTION_INT_OVERFLOW: + crash_handler(); + break; + } + return EXCEPTION_CONTINUE_SEARCH; +} + +void SetCrashHandler() { + if (!SetConsoleCtrlHandler(CtrlHandler, TRUE)) { + DWORD LastError = GetLastError(); + fprintf(stderr, "libFuzzer: SetConsoleCtrlHandler failed (Error code: %lu)." + "\n", LastError); + exit(1); + } + + if (!AddVectoredExceptionHandler(1, ExceptionHandler)) { + fprintf(stderr, "libFuzzer: AddVectoredExceptionHandler failed.\n"); + exit(1); + } + + if (SIG_ERR == signal(SIGABRT, AbrtHandler)) { + fprintf(stderr, "libFuzzer: signal failed with %d\n", errno); + exit(1); + } +} + +#endif + // Write extra stats to the file specified by the user. If none is specified // this function will never be called. static void write_extra_stats() { @@ -174,7 +247,7 @@ } // Call write_extra_stats before we exit. -static void crash_handler(int, siginfo_t *, void *) { +static void crash_handler() { // Make sure we don't try calling write_extra_stats again if we crashed while // trying to call it. static bool first_crash = true; @@ -226,13 +299,7 @@ } // Make sure that crash_handler gets called on any kind of fatal error. - int crash_signals[] = {SIGSEGV, SIGBUS, SIGABRT, SIGILL, SIGFPE, SIGINT, - SIGTERM}; - - const size_t num_signals = sizeof(crash_signals) / sizeof(crash_signals[0]); - - for (size_t idx = 0; idx < num_signals; idx++) - SetSigaction(crash_signals[idx], crash_handler); + SetCrashHandler(); // Make sure it gets called on other kinds of exits. atexit(write_extra_stats);