Better SigInt handler (#1710)

* fix simd

* better exit

* chg

* more

* more

* use

* change to proper name

* w

* aaaaaaa

* delete

* just separate them

* shell check
This commit is contained in:
Dongjia "toka" Zhang 2023-12-04 20:06:11 +01:00 committed by GitHub
parent 210315da0f
commit fad59987d9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 148 additions and 194 deletions

View File

@ -282,40 +282,84 @@ jobs:
if: runner.os == 'macOS' # use bash v4
run: /usr/local/bin/bash -c 'RUN_ON_CI=1 ./scripts/test_all_fuzzers.sh'
executions-check:
qemu_fuzzers:
strategy:
matrix:
os: [ubuntu-latest, macos-latest]
os: [ubuntu-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
- name: Fix python (macOS)
if: runner.os == 'macOS'
run: rm /usr/local/bin/2to3* /usr/local/bin/idle3* /usr/local/bin/pydoc3* /usr/local/bin/python3*
- name: Remove obsolete llvm (macOS)
if: runner.os == 'macOS'
run: brew remove --force llvm clang
- name: Free Disk Space (Ubuntu)
if: runner.os == 'Linux'
uses: jlumbroso/free-disk-space@main
with:
# this might remove tools that are actually needed,
# if set to "true" but frees about 6 GB
tool-cache: false
# all of these default to true, but feel free to set to
# "false" if necessary for your workflow
android: true
dotnet: true
haskell: true
large-packages: false
docker-images: true
swap-storage: true
- name: Add nightly rustfmt and clippy
run: rustup toolchain install nightly --component rustfmt --component clippy --allow-downgrade
- name: Add no_std toolchain
run: rustup toolchain install nightly-x86_64-unknown-linux-gnu ; rustup component add rust-src --toolchain nightly-x86_64-unknown-linux-gnu
- name: Add wasm target
run: rustup target add wasm32-unknown-unknown
- name: Install ucd-generate
run: cargo install -f ucd-generate
- name: Remove obsolete llvm (Linux)
if: runner.os == 'Linux'
run: sudo apt purge llvm* clang*
- uses: lyricwulf/abc@v1
with:
linux: llvm-15 llvm-15-dev clang-15
macos: python@3.11 llvm@15 bash coreutils
linux: llvm-15 llvm-15-dev clang-15 nasm ninja-build gcc-arm-linux-gnueabi g++-arm-linux-gnueabi gcc-aarch64-linux-gnu g++-aarch64-linux-gnu gcc-mipsel-linux-gnu g++-mipsel-linux-gnu gcc-powerpc-linux-gnu g++-powerpc-linux-gnu libc6-dev-i386-cross libc6-dev libc6-dev-i386 lib32gcc-11-dev lib32stdc++-11-dev libgtk-3-dev pax-utils libz3-dev
# update bash for macos to support `declare -A` command`
macos: llvm@15 libpng nasm coreutils z3 bash wget
- name: Set clang version
if: runner.os == 'Linux'
run: sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-15 100
- name: Set clang++ version
if: runner.os == 'Linux'
run: sudo update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-15 100
- name: pip install
run: python3 -m pip install msgpack jinja2 find_libpython
# Note that nproc needs to have coreutils installed on macOS, so the order of CI commands matters.
- name: enable mult-thread for `make`
run: export MAKEFLAGS="-j$(expr $(nproc) \+ 1)"
- name: install cargo-make
uses: baptiste0928/cargo-install@v1.3.0
with:
crate: cargo-make
- name: install wasm-pack
uses: baptiste0928/cargo-install@v1.3.0
with:
crate: wasm-pack
- name: install chrome
uses: browser-actions/setup-chrome@v1
with:
chrome-version: stable
- uses: actions/checkout@v3
with:
submodules: true # recursively checkout submodules
fetch-depth: 0
fetch-depth: 0 # to diff with origin/main
- uses: Swatinem/rust-cache@v2
- name: Build and run libfuzzer_libpng (Linux)
- name: Symlink Headers
if: runner.os == 'Linux'
run: ./scripts/executions-check.sh
- name: Build and run libfuzzer_libpng (macOS)
if: runner.os == 'macOS'
run: /usr/local/bin/bash -c './scripts/executions-check.sh'
# We can't install gcc-multilib which would usually do this for us due to collisions with other packages
run: sudo ln -s /usr/include/asm-generic /usr/include/asm
- name: Build and run example fuzzers (Linux)
if: runner.os == 'Linux'
run: RUN_ON_CI=1 RUN_QEMU_FUZZER=1 LLVM_CONFIG=llvm-config-15 ./scripts/test_all_fuzzers.sh
nostd-build:
runs-on: ubuntu-latest

View File

@ -44,7 +44,10 @@ use typed_builder::TypedBuilder;
use crate::events::{CentralizedEventManager, CentralizedLlmpEventBroker};
#[cfg(feature = "std")]
use crate::{
events::{EventConfig, LlmpRestartingEventManager, ManagerKind, RestartingMgr},
events::{
llmp::{LlmpRestartingEventManager, ManagerKind, RestartingMgr},
EventConfig,
},
monitors::Monitor,
state::{HasExecutions, State},
Error,

View File

@ -41,7 +41,7 @@ use typed_builder::TypedBuilder;
use super::{CustomBufEventResult, CustomBufHandlerFn};
#[cfg(all(unix, feature = "std"))]
use crate::events::{shutdown_handler, SHUTDOWN_SIGHANDLER_DATA};
use crate::events::EVENTMGR_SIGHANDLER_STATE;
use crate::{
events::{
BrokerEventResult, Event, EventConfig, EventFirer, EventManager, EventManagerId,
@ -1155,6 +1155,19 @@ where
S: State + HasExecutions,
MT: Monitor + Clone,
{
/// Internal function, returns true when shuttdown is requested by a `SIGINT` signal
#[inline]
#[allow(clippy::unused_self)]
fn is_shutting_down() -> bool {
#[cfg(unix)]
unsafe {
core::ptr::read_volatile(core::ptr::addr_of!(EVENTMGR_SIGHANDLER_STATE.shutting_down))
}
#[cfg(windows)]
false
}
/// Launch the restarting manager
pub fn launch(&mut self) -> Result<(Option<S>, LlmpRestartingEventManager<S, SP>), Error> {
// We start ourself as child process to actually fuzz
@ -1235,7 +1248,7 @@ where
// First, create a channel from the current fuzzer to the next to store state between restarts.
#[cfg(unix)]
let mut staterestorer: StateRestorer<SP> =
let staterestorer: StateRestorer<SP> =
StateRestorer::new(self.shmem_provider.new_shmem(256 * 1024 * 1024)?);
#[cfg(not(unix))]
@ -1244,21 +1257,9 @@ where
// Store the information to a map.
staterestorer.write_to_env(_ENV_FUZZER_SENDER)?;
#[cfg(unix)]
unsafe {
let data = &mut SHUTDOWN_SIGHANDLER_DATA;
// Write the pointer to staterestorer so we can release its shmem later
core::ptr::write_volatile(
&mut data.staterestorer_ptr,
&mut staterestorer as *mut _ as *mut std::ffi::c_void,
);
data.allocator_pid = std::process::id() as usize;
data.shutdown_handler = shutdown_handler::<SP> as *const std::ffi::c_void;
}
// We setup signal handlers to clean up shmem segments used by state restorer
#[cfg(all(unix, not(miri)))]
if let Err(_e) = unsafe { setup_signal_handler(&mut SHUTDOWN_SIGHANDLER_DATA) } {
if let Err(_e) = unsafe { setup_signal_handler(&mut EVENTMGR_SIGHANDLER_STATE) } {
// We can live without a proper ctrl+c signal handler. Print and ignore.
log::error!("Failed to setup signal handlers: {_e}");
}
@ -1305,7 +1306,7 @@ where
panic!("Fuzzer-respawner: Storing state in crashed fuzzer instance did not work, no point to spawn the next client! This can happen if the child calls `exit()`, in that case make sure it uses `abort()`, if it got killed unrecoverable (OOM), or if there is a bug in the fuzzer itself. (Child exited with: {child_status})");
}
if staterestorer.wants_to_exit() {
if staterestorer.wants_to_exit() || Self::is_shutting_down() {
return Err(Error::shutting_down());
}
@ -1739,7 +1740,7 @@ mod tests {
use crate::{
corpus::{Corpus, InMemoryCorpus, Testcase},
events::{llmp::_ENV_FUZZER_SENDER, LlmpEventManager},
events::llmp::{LlmpEventManager, _ENV_FUZZER_SENDER},
executors::{ExitKind, InProcessExecutor},
feedbacks::ConstFeedback,
fuzzer::Fuzzer,

View File

@ -18,8 +18,6 @@ pub mod tcp;
#[cfg(feature = "scalability_introspection")]
use alloc::string::ToString;
use alloc::{boxed::Box, string::String, vec::Vec};
#[cfg(all(unix, feature = "std"))]
use core::ffi::c_void;
use core::{
fmt,
hash::{BuildHasher, Hasher},
@ -33,8 +31,6 @@ pub use launcher::*;
#[cfg(all(unix, feature = "std"))]
use libafl_bolts::os::unix_signals::{siginfo_t, ucontext_t, Handler, Signal};
use libafl_bolts::{current_time, ClientId};
#[cfg(all(unix, feature = "std"))]
use libafl_bolts::{shmem::ShMemProvider, staterestore::StateRestorer};
pub use llmp::*;
use serde::{Deserialize, Serialize};
#[cfg(feature = "std")]
@ -58,10 +54,8 @@ use crate::{
/// Check if ctrl-c is sent with this struct
#[cfg(all(unix, feature = "std"))]
pub static mut SHUTDOWN_SIGHANDLER_DATA: ShutdownSignalData = ShutdownSignalData {
allocator_pid: 0,
staterestorer_ptr: core::ptr::null_mut(),
shutdown_handler: core::ptr::null(),
pub static mut EVENTMGR_SIGHANDLER_STATE: ShutdownSignalData = ShutdownSignalData {
shutting_down: false,
};
/// A signal handler for releasing `StateRestore` `ShMem`
@ -69,60 +63,21 @@ pub static mut SHUTDOWN_SIGHANDLER_DATA: ShutdownSignalData = ShutdownSignalData
#[cfg(all(unix, feature = "std"))]
#[derive(Debug, Clone)]
pub struct ShutdownSignalData {
allocator_pid: usize,
staterestorer_ptr: *mut c_void,
shutdown_handler: *const c_void,
shutting_down: bool,
}
/// Type for shutdown handler
#[cfg(all(unix, feature = "std"))]
pub type ShutdownFuncPtr =
unsafe fn(Signal, &mut siginfo_t, Option<&mut ucontext_t>, data: &mut ShutdownSignalData);
/// Shutdown handler. `SigTerm`, `SigInterrupt`, `SigQuit` call this
/// We can't handle SIGKILL in the signal handler, this means that you shouldn't kill your fuzzer with `kill -9` because then the shmem segments are never freed
///
/// # Safety
///
/// This will acceess `data` and write to the global `data.staterestorer_ptr` if it's not null.
#[cfg(all(unix, feature = "std"))]
#[allow(clippy::needless_pass_by_value)]
pub unsafe fn shutdown_handler<SP>(
signal: Signal,
_info: &mut siginfo_t,
_context: Option<&mut ucontext_t>,
data: &ShutdownSignalData,
) where
SP: ShMemProvider,
{
log::info!(
"Fuzzer shutdown by Signal: {} Pid: {}",
signal,
std::process::id()
);
let ptr = data.staterestorer_ptr;
if ptr.is_null() || data.allocator_pid != std::process::id() as usize {
// Do nothing
} else {
// The process allocated the staterestorer map must take care of it
let sr = (ptr as *mut StateRestorer<SP>).as_mut().unwrap();
// log::trace!("{:#?}", sr);
std::ptr::drop_in_place(sr);
}
log::info!("Bye!");
libc::_exit(0);
}
#[cfg(all(unix, feature = "std"))]
impl Handler for ShutdownSignalData {
fn handle(&mut self, signal: Signal, info: &mut siginfo_t, context: Option<&mut ucontext_t>) {
fn handle(
&mut self,
_signal: Signal,
_info: &mut siginfo_t,
_context: Option<&mut ucontext_t>,
) {
unsafe {
let data = &mut SHUTDOWN_SIGHANDLER_DATA;
if !data.shutdown_handler.is_null() {
let func: ShutdownFuncPtr = std::mem::transmute(data.shutdown_handler);
(func)(signal, info, context, data);
}
core::ptr::write_volatile(core::ptr::addr_of_mut!(self.shutting_down), true);
}
}

View File

@ -5,10 +5,6 @@ use alloc::{
string::{String, ToString},
vec::Vec,
};
#[cfg(all(unix, feature = "std"))]
use core::ffi::c_void;
#[cfg(all(unix, feature = "std"))]
use core::ptr::write_volatile;
use core::{fmt::Debug, marker::PhantomData};
#[cfg(feature = "std")]
use core::{
@ -30,7 +26,7 @@ use serde::{de::DeserializeOwned, Serialize};
use super::{CustomBufEventResult, CustomBufHandlerFn, HasCustomBufHandlers, ProgressReporter};
#[cfg(all(unix, feature = "std"))]
use crate::events::{shutdown_handler, SHUTDOWN_SIGHANDLER_DATA};
use crate::events::EVENTMGR_SIGHANDLER_STATE;
use crate::{
events::{
BrokerEventResult, Event, EventFirer, EventManager, EventManagerId, EventProcessor,
@ -450,6 +446,19 @@ where
}
}
/// Internal function, returns true when shuttdown is requested by a `SIGINT` signal
#[inline]
#[allow(clippy::unused_self)]
fn is_shutting_down() -> bool {
#[cfg(unix)]
unsafe {
core::ptr::read_volatile(core::ptr::addr_of!(EVENTMGR_SIGHANDLER_STATE.shutting_down))
}
#[cfg(windows)]
false
}
/// Launch the simple restarting manager.
/// This [`EventManager`] is simple and single threaded,
/// but can still used shared maps to recover from crashes and timeouts.
@ -463,7 +472,7 @@ where
let mut staterestorer = if std::env::var(_ENV_FUZZER_SENDER).is_err() {
// First, create a place to store state in, for restarts.
#[cfg(unix)]
let mut staterestorer: StateRestorer<SP> =
let staterestorer: StateRestorer<SP> =
StateRestorer::new(shmem_provider.new_shmem(256 * 1024 * 1024)?);
#[cfg(not(unix))]
let staterestorer: StateRestorer<SP> =
@ -472,21 +481,9 @@ where
//let staterestorer = { LlmpSender::new(shmem_provider.clone(), 0, false)? };
staterestorer.write_to_env(_ENV_FUZZER_SENDER)?;
#[cfg(unix)]
unsafe {
let data = &mut SHUTDOWN_SIGHANDLER_DATA;
// Write the pointer to staterestorer so we can release its shmem later
write_volatile(
&mut data.staterestorer_ptr,
&mut staterestorer as *mut _ as *mut c_void,
);
data.allocator_pid = std::process::id() as usize;
data.shutdown_handler = shutdown_handler::<SP> as *const c_void;
}
// We setup signal handlers to clean up shmem segments used by state restorer
#[cfg(all(unix, not(miri)))]
if let Err(_e) = unsafe { setup_signal_handler(&mut SHUTDOWN_SIGHANDLER_DATA) } {
if let Err(_e) = unsafe { setup_signal_handler(&mut EVENTMGR_SIGHANDLER_STATE) } {
// We can live without a proper ctrl+c signal handler. Print and ignore.
log::error!("Failed to setup signal handlers: {_e}");
}
@ -520,7 +517,7 @@ where
compiler_fence(Ordering::SeqCst);
if staterestorer.wants_to_exit() {
if staterestorer.wants_to_exit() || Self::is_shutting_down() {
return Err(Error::shutting_down());
}

View File

@ -39,7 +39,7 @@ use typed_builder::TypedBuilder;
use super::{CustomBufEventResult, CustomBufHandlerFn};
#[cfg(all(unix, feature = "std"))]
use crate::events::{shutdown_handler, SHUTDOWN_SIGHANDLER_DATA};
use crate::events::EVENTMGR_SIGHANDLER_STATE;
use crate::{
events::{
BrokerEventResult, Event, EventConfig, EventFirer, EventManager, EventManagerId,
@ -953,7 +953,7 @@ where
/// The kind of manager we're creating right now
#[cfg(feature = "std")]
#[derive(Debug, Clone, Copy)]
pub enum ManagerKind {
pub enum TcpManagerKind {
/// Any kind will do
Any,
/// A client, getting messages from a local broker.
@ -979,7 +979,7 @@ where
MT: Monitor + Clone,
S: State + HasExecutions,
{
RestartingMgr::builder()
TcpRestartingMgr::builder()
.shmem_provider(StdShMemProvider::new()?)
.monitor(Some(monitor))
.broker_port(broker_port)
@ -988,13 +988,13 @@ where
.launch()
}
/// Provides a `builder` which can be used to build a [`RestartingMgr`], which is a combination of a
/// Provides a `builder` which can be used to build a [`TcpRestartingMgr`], which is a combination of a
/// `restarter` and `runner`, that can be used on systems both with and without `fork` support. The
/// `restarter` will start a new process each time the child crashes or times out.
#[cfg(feature = "std")]
#[allow(clippy::default_trait_access, clippy::ignored_unit_patterns)]
#[derive(TypedBuilder, Debug)]
pub struct RestartingMgr<MT, S, SP>
pub struct TcpRestartingMgr<MT, S, SP>
where
S: UsesInput + DeserializeOwned,
SP: ShMemProvider + 'static,
@ -1016,8 +1016,8 @@ where
#[builder(default = None)]
remote_broker_addr: Option<SocketAddr>,
/// The type of manager to build
#[builder(default = ManagerKind::Any)]
kind: ManagerKind,
#[builder(default = TcpManagerKind::Any)]
kind: TcpManagerKind,
/// The amount of external clients that should have connected (not counting our own tcp client)
/// before this broker quits _after the last client exited_.
/// If `None`, the broker will never quit when the last client exits, but run forever.
@ -1035,12 +1035,21 @@ where
#[cfg(feature = "std")]
#[allow(clippy::type_complexity, clippy::too_many_lines)]
impl<MT, S, SP> RestartingMgr<MT, S, SP>
impl<MT, S, SP> TcpRestartingMgr<MT, S, SP>
where
SP: ShMemProvider,
S: State + HasExecutions,
MT: Monitor + Clone,
{
/// Internal function, returns true when shuttdown is requested by a `SIGINT` signal
#[inline]
#[allow(clippy::unused_self)]
fn is_shutting_down() -> bool {
unsafe {
core::ptr::read_volatile(core::ptr::addr_of!(EVENTMGR_SIGHANDLER_STATE.shutting_down))
}
}
/// Launch the restarting manager
pub fn launch(&mut self) -> Result<(Option<S>, TcpRestartingEventManager<S, SP>), Error> {
// We start ourself as child process to actually fuzz
@ -1057,7 +1066,7 @@ where
// We get here if we are on Unix, or we are a broker on Windows (or without forks).
let (mgr, core_id) = match self.kind {
ManagerKind::Any => {
TcpManagerKind::Any => {
let connection = create_nonblocking_listener(("127.0.0.1", self.broker_port));
match connection {
Ok(listener) => {
@ -1088,7 +1097,7 @@ where
}
}
}
ManagerKind::Broker => {
TcpManagerKind::Broker => {
let event_broker = TcpEventBroker::<S::Input, MT>::new(
format!("127.0.0.1:{}", self.broker_port),
self.monitor.take().unwrap(),
@ -1097,7 +1106,7 @@ where
broker_things(event_broker, self.remote_broker_addr)?;
unreachable!("The broker may never return normally, only on errors or when shutting down.");
}
ManagerKind::Client { cpu_core } => {
TcpManagerKind::Client { cpu_core } => {
// We are a client
let mgr = TcpEventManager::<S>::on_port(self.broker_port, self.configuration)?;
@ -1116,7 +1125,7 @@ where
// First, create a channel from the current fuzzer to the next to store state between restarts.
#[cfg(unix)]
let mut staterestorer: StateRestorer<SP> =
let staterestorer: StateRestorer<SP> =
StateRestorer::new(self.shmem_provider.new_shmem(256 * 1024 * 1024)?);
#[cfg(not(unix))]
@ -1125,21 +1134,9 @@ where
// Store the information to a map.
staterestorer.write_to_env(_ENV_FUZZER_SENDER)?;
#[cfg(unix)]
unsafe {
let data = &mut SHUTDOWN_SIGHANDLER_DATA;
// Write the pointer to staterestorer so we can release its shmem later
core::ptr::write_volatile(
&mut data.staterestorer_ptr,
&mut staterestorer as *mut _ as *mut std::ffi::c_void,
);
data.allocator_pid = std::process::id() as usize;
data.shutdown_handler = shutdown_handler::<SP> as *const std::ffi::c_void;
}
// We setup signal handlers to clean up shmem segments used by state restorer
#[cfg(all(unix, not(miri)))]
if let Err(_e) = unsafe { setup_signal_handler(&mut SHUTDOWN_SIGHANDLER_DATA) } {
if let Err(_e) = unsafe { setup_signal_handler(&mut EVENTMGR_SIGHANDLER_STATE) } {
// We can live without a proper ctrl+c signal handler. Print and ignore.
log::error!("Failed to setup signal handlers: {_e}");
}
@ -1187,7 +1184,7 @@ where
panic!("Fuzzer-respawner: Storing state in crashed fuzzer instance did not work, no point to spawn the next client! This can happen if the child calls `exit()`, in that case make sure it uses `abort()`, if it got killed unrecoverable (OOM), or if there is a bug in the fuzzer itself. (Child exited with: {child_status})");
}
if staterestorer.wants_to_exit() {
if staterestorer.wants_to_exit() || Self::is_shutting_down() {
return Err(Error::shutting_down());
}

View File

@ -1977,7 +1977,7 @@ impl Handler for LlmpShutdownSignalHandler {
_context: Option<&mut ucontext_t>,
) {
unsafe {
ptr::write_volatile(&mut self.shutting_down, true);
ptr::write_volatile(ptr::addr_of_mut!(self.shutting_down), true);
}
}
@ -2245,7 +2245,7 @@ where
#[cfg(unix)]
#[allow(clippy::unused_self)]
fn is_shutting_down(&self) -> bool {
unsafe { ptr::read_volatile(&LLMP_SIGHANDLER_STATE.shutting_down) }
unsafe { ptr::read_volatile(ptr::addr_of!(LLMP_SIGHANDLER_STATE.shutting_down)) }
}
/// Always returns true on platforms, where no shutdown signal handlers are supported

View File

@ -1,56 +0,0 @@
#!/bin/bash
install_libpng() {
cd ./fuzzers/libfuzzer_libpng && wget https://deac-fra.dl.sourceforge.net/project/libpng/libpng16/1.6.37/libpng-1.6.37.tar.xz
tar -xvf libpng-1.6.37.tar.xz || echo "Failed to download libpng"
cd libpng-1.6.37 && ./configure --enable-shared=no --with-pic=yes --enable-hardware-optimizations=yes && cd ..
}
build_libpng(){
cargo build --release || echo "ERROR: Failed to build libfuzzer_libpng"
cd libpng-1.6.37 && make CC="$(pwd)/../target/release/libafl_cc" CXX="$(pwd)/../target/release/ libafl_cxx" -j "$(nproc)" && cd ..
}
git_checkout(){
git reset --hard HEAD^
}
build_run_fuzzer(){
./target/release/libafl_cxx ./harness.cc libpng-1.6.37/.libs/libpng16.a -I libpng-1.6.37/ -o fuzzer_libpng -lz -lm || exit 2
./fuzzer_libpng > log.txt &
# wait that fuzzer_libpng become the broker
sleep 1
timeout 5m ./fuzzer_libpng > /dev/null 2>&1 &
while true; do
if grep -q "Broker" log.txt ; then
pkill -9 "fuzzer_libpng"
executions=$(grep -m 1 "Broker" log.txt | awk '{print $14}')
rm -rf ./libafl_unix_shmem_server
echo "${executions%,}"
break
fi
done
}
main(){
install_libpng
build_libpng
echo "start to run the new fuzzer"
new_executions=$(build_run_fuzzer)
git_checkout
build_libpng
echo "start to run the last fuzzer"
last_executions=$(build_run_fuzzer)
echo "the execution count of the new fuzzer is $new_executions"
echo "the execution count of the last fuzzer is $last_executions"
}
main

View File

@ -15,6 +15,19 @@ else
export PROFILE_DIR=debug
fi
if [[ -z "${RUN_ON_CI}" ]]; then
:
else
if [[ -z "${RUN_QEMU_FUZZER}" ]]; then
fuzzers=$(echo "$fuzzers" | tr ' ' '\n' | grep -v "qemu")
backtrace_fuzzers=$(echo "$backtrace_fuzzers" | tr ' ' '\n' | grep "qemu")
else
fuzzers=$(echo "$fuzzers" | tr ' ' '\n' | grep "qemu")
backtrace_fuzzers=$(echo "$backtrace_fuzzers" | tr ' ' '\n' | grep -v "qemu")
fi
fi
libafl=$(pwd)
# build with a shared target dir for all fuzzers. this should speed up