[compiler-rt][libFuzzer] Add support for capturing SIGTRAP exits. (#149120)

Swift's FatalError raises a SIGTRAP, which currently causes the fuzzer
to exit without writing out the crashing input.

rdar://142975522
This commit is contained in:
Dan Blackwell 2025-07-28 15:46:48 +01:00 committed by GitHub
parent a22d010002
commit 33cc58f46f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 42 additions and 1 deletions

View File

@ -834,6 +834,7 @@ int FuzzerDriver(int *argc, char ***argv, UserCallback Callback) {
Options.HandleInt = Flags.handle_int;
Options.HandleSegv = Flags.handle_segv;
Options.HandleTerm = Flags.handle_term;
Options.HandleTrap = Flags.handle_trap;
Options.HandleXfsz = Flags.handle_xfsz;
Options.HandleUsr1 = Flags.handle_usr1;
Options.HandleUsr2 = Flags.handle_usr2;

View File

@ -152,6 +152,7 @@ FUZZER_FLAG_INT(handle_ill, 1, "If 1, try to intercept SIGILL.")
FUZZER_FLAG_INT(handle_fpe, 1, "If 1, try to intercept SIGFPE.")
FUZZER_FLAG_INT(handle_int, 1, "If 1, try to intercept SIGINT.")
FUZZER_FLAG_INT(handle_term, 1, "If 1, try to intercept SIGTERM.")
FUZZER_FLAG_INT(handle_trap, 1, "If 1, try to intercept SIGTRAP.")
FUZZER_FLAG_INT(handle_xfsz, 1, "If 1, try to intercept SIGXFSZ.")
FUZZER_FLAG_INT(handle_usr1, 1, "If 1, try to intercept SIGUSR1.")
FUZZER_FLAG_INT(handle_usr2, 1, "If 1, try to intercept SIGUSR2.")

View File

@ -82,6 +82,7 @@ struct FuzzingOptions {
bool HandleInt = false;
bool HandleSegv = false;
bool HandleTerm = false;
bool HandleTrap = false;
bool HandleXfsz = false;
bool HandleUsr1 = false;
bool HandleUsr2 = false;

View File

@ -410,7 +410,7 @@ void SetSignalHandler(const FuzzingOptions &Options) {
// Early exit if no crash handler needed.
if (!Options.HandleSegv && !Options.HandleBus && !Options.HandleIll &&
!Options.HandleFpe && !Options.HandleAbrt)
!Options.HandleFpe && !Options.HandleAbrt && !Options.HandleTrap)
return;
// Set up the crash handler and wait until it is ready before proceeding.

View File

@ -132,6 +132,8 @@ void SetSignalHandler(const FuzzingOptions& Options) {
SetSigaction(SIGILL, CrashHandler);
if (Options.HandleFpe)
SetSigaction(SIGFPE, CrashHandler);
if (Options.HandleTrap)
SetSigaction(SIGTRAP, CrashHandler);
if (Options.HandleXfsz)
SetSigaction(SIGXFSZ, FileSizeExceedHandler);
if (Options.HandleUsr1)

View File

@ -0,0 +1,29 @@
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
// Simple test for a fuzzer. The fuzzer must find the string "Hi!".
#include <assert.h>
#include <cstddef>
#include <cstdint>
#include <cstdlib>
#include <iostream>
#include <ostream>
#include <signal.h>
static volatile int Sink;
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
assert(Data);
if (Size > 0 && Data[0] == 'H') {
Sink = 1;
if (Size > 1 && Data[1] == 'i') {
Sink = 2;
if (Size > 2 && Data[2] == '!') {
std::cout << "BINGO; Found the target, exiting\n" << std::flush;
raise(SIGTRAP);
}
}
}
return 0;
}

View File

@ -0,0 +1,7 @@
RUN: %cpp_compiler %S/SigTrapTest.cpp -o %t
RUN: not %run %t 2>&1 | FileCheck %s
CHECK: BINGO
CHECK: ERROR: libFuzzer: deadly signal
RUN: trap "%run %t -handle_trap=0" TRAP