CI: Run miri tests (#1130)

* Fixes/ignores for miri support

* linux

* fix doctest for miri

* fix docs

* fix UB in baby_fuzzer

* no custom allocator in miri
This commit is contained in:
Dominik Maier 2023-03-08 19:21:17 +01:00 committed by GitHub
parent e8838ebebe
commit 2ed6583041
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 78 additions and 29 deletions

View File

@ -68,7 +68,7 @@ jobs:
- name: get clang version - name: get clang version
run: command -v llvm-config && clang -v run: command -v llvm-config && clang -v
- name: Add nightly rustfmt and clippy - name: Add nightly rustfmt and clippy
run: rustup toolchain install nightly --component rustfmt --component clippy --allow-downgrade run: rustup toolchain install nightly --component rustfmt --component clippy --component miri --allow-downgrade
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- uses: Swatinem/rust-cache@v2 - uses: Swatinem/rust-cache@v2
@ -99,6 +99,10 @@ jobs:
- name: Build examples - name: Build examples
run: cargo build --examples --verbose run: cargo build --examples --verbose
# --- miri undefined behavior test --
- name: Run miri tests
run: RUST_BACKTRACE=1 MIRIFLAGS="-Zmiri-disable-isolation" cargo +nightly miri test
ubuntu-check: ubuntu-check:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
steps: steps:

1
.gitignore vendored
View File

@ -21,6 +21,7 @@ vendor
*.obj *.obj
.cur_input .cur_input
.cur_input_*
.venv .venv
crashes crashes

View File

@ -1,6 +1,6 @@
use std::path::PathBuf;
#[cfg(windows)] #[cfg(windows)]
use std::ptr::write_volatile; use std::ptr::write_volatile;
use std::{path::PathBuf, ptr::write};
#[cfg(feature = "tui")] #[cfg(feature = "tui")]
use libafl::monitors::tui::TuiMonitor; use libafl::monitors::tui::TuiMonitor;
@ -24,10 +24,11 @@ use libafl::{
/// Coverage map with explicit assignments due to the lack of instrumentation /// Coverage map with explicit assignments due to the lack of instrumentation
static mut SIGNALS: [u8; 16] = [0; 16]; static mut SIGNALS: [u8; 16] = [0; 16];
static mut SIGNALS_PTR: *mut u8 = unsafe { SIGNALS.as_mut_ptr() };
/// Assign a signal to the signals map /// Assign a signal to the signals map
fn signals_set(idx: usize) { fn signals_set(idx: usize) {
unsafe { SIGNALS[idx] = 1 }; unsafe { write(SIGNALS_PTR.add(idx), 1) };
} }
#[allow(clippy::similar_names, clippy::manual_assert)] #[allow(clippy::similar_names, clippy::manual_assert)]
@ -60,8 +61,7 @@ pub fn main() {
}; };
// Create an observation channel using the signals map // Create an observation channel using the signals map
let observer = let observer = unsafe { StdMapObserver::from_mut_ptr("signals", SIGNALS_PTR, SIGNALS.len()) };
unsafe { StdMapObserver::from_mut_ptr("signals", SIGNALS.as_mut_ptr(), SIGNALS.len()) };
// Feedback to rate the interestingness of an input // Feedback to rate the interestingness of an input
let mut feedback = MaxMapFeedback::new(&observer); let mut feedback = MaxMapFeedback::new(&observer);

View File

@ -25,9 +25,11 @@ use libafl::{
state::{HasSolutions, StdState}, state::{HasSolutions, StdState},
}; };
use libafl_targets::{DifferentialAFLMapSwapObserver, MAX_EDGES_NUM}; use libafl_targets::{DifferentialAFLMapSwapObserver, MAX_EDGES_NUM};
#[cfg(not(miri))]
use mimalloc::MiMalloc; use mimalloc::MiMalloc;
#[global_allocator] #[global_allocator]
#[cfg(not(miri))]
static GLOBAL: MiMalloc = MiMalloc; static GLOBAL: MiMalloc = MiMalloc;
// bindings to the functions defined in the target // bindings to the functions defined in the target

View File

@ -5,14 +5,15 @@
//! This example shows how create a thread for each available processor and pin each thread to its corresponding processor. //! This example shows how create a thread for each available processor and pin each thread to its corresponding processor.
//! //!
//! ```rust //! ```rust
//! # use std::thread;
//! use libafl::bolts::core_affinity; //! use libafl::bolts::core_affinity;
//! //!
//! use std::thread;
//!
//! // Retrieve the IDs of all active CPU cores. //! // Retrieve the IDs of all active CPU cores.
//! # #[cfg(not(miri))]
//! let core_ids = core_affinity::get_core_ids().unwrap(); //! let core_ids = core_affinity::get_core_ids().unwrap();
//! //!
//! // Create a thread for each active CPU core. //! // Create a thread for each active CPU core.
//! # #[cfg(not(miri))]
//! let handles = core_ids.into_iter().map(|id| { //! let handles = core_ids.into_iter().map(|id| {
//! thread::spawn(move || { //! thread::spawn(move || {
//! // Pin this thread to a single CPU core. //! // Pin this thread to a single CPU core.
@ -21,6 +22,7 @@
//! }) //! })
//! }).collect::<Vec<_>>(); //! }).collect::<Vec<_>>();
//! //!
//! # #[cfg(not(miri))]
//! for handle in handles.into_iter() { //! for handle in handles.into_iter() {
//! handle.join().unwrap(); //! handle.join().unwrap();
//! } //! }
@ -307,11 +309,13 @@ mod linux {
use super::*; use super::*;
#[test] #[test]
#[cfg_attr(miri, ignore)]
fn test_linux_get_affinity_mask() { fn test_linux_get_affinity_mask() {
get_affinity_mask().unwrap(); get_affinity_mask().unwrap();
} }
#[test] #[test]
#[cfg_attr(miri, ignore)]
fn test_linux_set_for_current() { fn test_linux_set_for_current() {
let ids = get_core_ids().unwrap(); let ids = get_core_ids().unwrap();
@ -558,7 +562,7 @@ mod apple {
thread_policy_flavor_t, thread_policy_t, thread_t, KERN_SUCCESS, THREAD_AFFINITY_POLICY, thread_policy_flavor_t, thread_policy_t, thread_t, KERN_SUCCESS, THREAD_AFFINITY_POLICY,
THREAD_AFFINITY_POLICY_COUNT, THREAD_AFFINITY_POLICY_COUNT,
}; };
#[cfg(target_arch = "aarch64")] #[cfg(all(target_arch = "aarch64", not(miri)))]
use libc::{pthread_set_qos_class_self_np, qos_class_t::QOS_CLASS_USER_INITIATED}; use libc::{pthread_set_qos_class_self_np, qos_class_t::QOS_CLASS_USER_INITIATED};
use super::CoreId; use super::CoreId;
@ -622,6 +626,7 @@ mod apple {
// //
// Furthermore, this seems to fail on background threads, so we ignore errors (result != 0). // Furthermore, this seems to fail on background threads, so we ignore errors (result != 0).
#[cfg(not(miri))]
unsafe { unsafe {
let _result = pthread_set_qos_class_self_np(QOS_CLASS_USER_INITIATED, 0); let _result = pthread_set_qos_class_self_np(QOS_CLASS_USER_INITIATED, 0);
} }
@ -902,12 +907,14 @@ mod tests {
use super::*; use super::*;
#[test] #[test]
#[cfg_attr(miri, ignore)]
fn test_get_core_ids() { fn test_get_core_ids() {
let set = get_core_ids().unwrap(); let set = get_core_ids().unwrap();
assert_eq!(set.len(), usize::from(available_parallelism().unwrap())); assert_eq!(set.len(), usize::from(available_parallelism().unwrap()));
} }
#[test] #[test]
#[cfg_attr(miri, ignore)]
fn test_set_affinity() { fn test_set_affinity() {
let ids = get_core_ids().unwrap(); let ids = get_core_ids().unwrap();

View File

@ -96,10 +96,10 @@ use serde::{Deserialize, Serialize};
#[cfg(feature = "std")] #[cfg(feature = "std")]
use crate::bolts::current_time; use crate::bolts::current_time;
#[cfg(all(unix, not(miri)))]
use crate::bolts::os::unix_signals::setup_signal_handler;
#[cfg(unix)] #[cfg(unix)]
use crate::bolts::os::unix_signals::{ use crate::bolts::os::unix_signals::{siginfo_t, ucontext_t, Handler, Signal};
setup_signal_handler, siginfo_t, ucontext_t, Handler, Signal,
};
use crate::{ use crate::{
bolts::{ bolts::{
shmem::{ShMem, ShMemDescription, ShMemId, ShMemProvider}, shmem::{ShMem, ShMemDescription, ShMemId, ShMemProvider},
@ -2190,7 +2190,7 @@ where
{ {
use super::current_milliseconds; use super::current_milliseconds;
#[cfg(unix)] #[cfg(all(unix, not(miri)))]
if let Err(_e) = unsafe { setup_signal_handler(&mut LLMP_SIGHANDLER_STATE) } { if let Err(_e) = unsafe { setup_signal_handler(&mut LLMP_SIGHANDLER_STATE) } {
// We can live without a proper ctrl+c signal handler. Print and ignore. // We can live without a proper ctrl+c signal handler. Print and ignore.
log::info!("Failed to setup signal handlers: {_e}"); log::info!("Failed to setup signal handlers: {_e}");
@ -2254,7 +2254,7 @@ where
where where
F: FnMut(ClientId, Tag, Flags, &[u8]) -> Result<LlmpMsgHookResult, Error>, F: FnMut(ClientId, Tag, Flags, &[u8]) -> Result<LlmpMsgHookResult, Error>,
{ {
#[cfg(unix)] #[cfg(all(unix, not(miri)))]
if let Err(_e) = unsafe { setup_signal_handler(&mut LLMP_SIGHANDLER_STATE) } { if let Err(_e) = unsafe { setup_signal_handler(&mut LLMP_SIGHANDLER_STATE) } {
// We can live without a proper ctrl+c signal handler. Print and ignore. // We can live without a proper ctrl+c signal handler. Print and ignore.
log::info!("Failed to setup signal handlers: {_e}"); log::info!("Failed to setup signal handlers: {_e}");
@ -3100,6 +3100,7 @@ mod tests {
#[test] #[test]
#[serial] #[serial]
#[cfg_attr(miri, ignore)]
pub fn test_llmp_connection() { pub fn test_llmp_connection() {
#[allow(unused_variables)] #[allow(unused_variables)]
let shmem_provider = StdShMemProvider::new().unwrap(); let shmem_provider = StdShMemProvider::new().unwrap();

View File

@ -635,6 +635,7 @@ mod tests {
use crate::bolts::{minibsod::dump_registers, os::unix_signals::ucontext}; use crate::bolts::{minibsod::dump_registers, os::unix_signals::ucontext};
#[test] #[test]
#[cfg_attr(miri, ignore)]
pub fn test_dump_registers() { pub fn test_dump_registers() {
let ucontext = ucontext().unwrap(); let ucontext = ucontext().unwrap();
let mut writer = BufWriter::new(stdout()); let mut writer = BufWriter::new(stdout());

View File

@ -380,7 +380,9 @@ unsafe fn handle_signal(sig: c_int, info: siginfo_t, void: *mut c_void) {
/// This will allocate a signal stack and set the signal handlers accordingly. /// This will allocate a signal stack and set the signal handlers accordingly.
/// It is, for example, used in the [`type@crate::executors::InProcessExecutor`] to restart the fuzzer in case of a crash, /// It is, for example, used in the [`type@crate::executors::InProcessExecutor`] to restart the fuzzer in case of a crash,
/// or to handle `SIGINT` in the broker process. /// or to handle `SIGINT` in the broker process.
///
/// # Safety /// # Safety
///
/// The signal handlers will be called on any signal. They should (tm) be async safe. /// The signal handlers will be called on any signal. They should (tm) be async safe.
/// A lot can go south in signal handling. Be sure you know what you are doing. /// A lot can go south in signal handling. Be sure you know what you are doing.
pub unsafe fn setup_signal_handler<T: 'static + Handler>(handler: &mut T) -> Result<(), Error> { pub unsafe fn setup_signal_handler<T: 'static + Handler>(handler: &mut T) -> Result<(), Error> {

View File

@ -1472,6 +1472,7 @@ mod tests {
#[test] #[test]
#[serial] #[serial]
#[cfg_attr(miri, ignore)]
fn test_shmem_service() { fn test_shmem_service() {
let mut provider = StdShMemProvider::new().unwrap(); let mut provider = StdShMemProvider::new().unwrap();
let mut map = provider.new_shmem(1024).unwrap(); let mut map = provider.new_shmem(1024).unwrap();

View File

@ -301,6 +301,7 @@ mod tests {
#[test] #[test]
#[serial] #[serial]
#[cfg_attr(miri, ignore)]
fn test_state_restore() { fn test_state_restore() {
const TESTMAP_SIZE: usize = 1024; const TESTMAP_SIZE: usize = 1024;

View File

@ -22,6 +22,8 @@ use super::{CustomBufEventResult, CustomBufHandlerFn};
use crate::bolts::core_affinity::CoreId; use crate::bolts::core_affinity::CoreId;
#[cfg(all(feature = "std", any(windows, not(feature = "fork"))))] #[cfg(all(feature = "std", any(windows, not(feature = "fork"))))]
use crate::bolts::os::startable_self; use crate::bolts::os::startable_self;
#[cfg(all(unix, feature = "std", not(miri)))]
use crate::bolts::os::unix_signals::setup_signal_handler;
#[cfg(all(feature = "std", feature = "fork", unix))] #[cfg(all(feature = "std", feature = "fork", unix))]
use crate::bolts::os::{fork, ForkResult}; use crate::bolts::os::{fork, ForkResult};
#[cfg(feature = "llmp_compression")] #[cfg(feature = "llmp_compression")]
@ -32,10 +34,7 @@ use crate::bolts::{
#[cfg(feature = "std")] #[cfg(feature = "std")]
use crate::bolts::{llmp::LlmpConnection, shmem::StdShMemProvider, staterestore::StateRestorer}; use crate::bolts::{llmp::LlmpConnection, shmem::StdShMemProvider, staterestore::StateRestorer};
#[cfg(all(unix, feature = "std"))] #[cfg(all(unix, feature = "std"))]
use crate::{ use crate::events::{shutdown_handler, SHUTDOWN_SIGHANDLER_DATA};
bolts::os::unix_signals::setup_signal_handler,
events::{shutdown_handler, SHUTDOWN_SIGHANDLER_DATA},
};
use crate::{ use crate::{
bolts::{ bolts::{
llmp::{self, LlmpClient, LlmpClientDescription, Tag}, llmp::{self, LlmpClient, LlmpClientDescription, Tag},
@ -992,7 +991,7 @@ where
} }
// We setup signal handlers to clean up shmem segments used by state restorer // We setup signal handlers to clean up shmem segments used by state restorer
#[cfg(unix)] #[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 SHUTDOWN_SIGHANDLER_DATA) } {
// We can live without a proper ctrl+c signal handler. Print and ignore. // We can live without a proper ctrl+c signal handler. Print and ignore.
log::error!("Failed to setup signal handlers: {_e}"); log::error!("Failed to setup signal handlers: {_e}");
@ -1474,6 +1473,7 @@ mod tests {
#[test] #[test]
#[serial] #[serial]
#[cfg_attr(miri, ignore)]
fn test_mgr_state_restore() { fn test_mgr_state_restore() {
let rand = StdRand::with_seed(0); let rand = StdRand::with_seed(0);

View File

@ -19,13 +19,12 @@ use serde::{de::DeserializeOwned, Serialize};
use super::{CustomBufEventResult, CustomBufHandlerFn, HasCustomBufHandlers, ProgressReporter}; use super::{CustomBufEventResult, CustomBufHandlerFn, HasCustomBufHandlers, ProgressReporter};
#[cfg(all(feature = "std", any(windows, not(feature = "fork"))))] #[cfg(all(feature = "std", any(windows, not(feature = "fork"))))]
use crate::bolts::os::startable_self; use crate::bolts::os::startable_self;
#[cfg(all(unix, feature = "std", not(miri)))]
use crate::bolts::os::unix_signals::setup_signal_handler;
#[cfg(all(feature = "std", feature = "fork", unix))] #[cfg(all(feature = "std", feature = "fork", unix))]
use crate::bolts::os::{fork, ForkResult}; use crate::bolts::os::{fork, ForkResult};
#[cfg(all(unix, feature = "std"))] #[cfg(all(unix, feature = "std"))]
use crate::{ use crate::events::{shutdown_handler, SHUTDOWN_SIGHANDLER_DATA};
bolts::os::unix_signals::setup_signal_handler,
events::{shutdown_handler, SHUTDOWN_SIGHANDLER_DATA},
};
use crate::{ use crate::{
bolts::ClientId, bolts::ClientId,
events::{ events::{
@ -472,7 +471,7 @@ where
} }
// We setup signal handlers to clean up shmem segments used by state restorer // We setup signal handlers to clean up shmem segments used by state restorer
#[cfg(unix)] #[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 SHUTDOWN_SIGHANDLER_DATA) } {
// We can live without a proper ctrl+c signal handler. Print and ignore. // We can live without a proper ctrl+c signal handler. Print and ignore.
log::error!("Failed to setup signal handlers: {_e}"); log::error!("Failed to setup signal handlers: {_e}");

View File

@ -656,6 +656,7 @@ mod tests {
#[test] #[test]
#[cfg(unix)] #[cfg(unix)]
#[cfg_attr(miri, ignore)]
fn test_builder() { fn test_builder() {
let mut mgr = SimpleEventManager::new(SimpleMonitor::new(|status| { let mut mgr = SimpleEventManager::new(SimpleMonitor::new(|status| {
log::info!("{status}"); log::info!("{status}");
@ -680,6 +681,7 @@ mod tests {
#[test] #[test]
#[cfg(unix)] #[cfg(unix)]
#[cfg_attr(miri, ignore)]
fn test_parse_afl_cmdline() { fn test_parse_afl_cmdline() {
use alloc::string::ToString; use alloc::string::ToString;

View File

@ -1283,6 +1283,7 @@ mod tests {
#[test] #[test]
#[serial] #[serial]
#[cfg_attr(miri, ignore)]
fn test_forkserver() { fn test_forkserver() {
const MAP_SIZE: usize = 65536; const MAP_SIZE: usize = 65536;
let bin = OsString::from("echo"); let bin = OsString::from("echo");

View File

@ -35,7 +35,7 @@ use nix::{
#[cfg(windows)] #[cfg(windows)]
use windows::Win32::System::Threading::SetThreadStackGuarantee; use windows::Win32::System::Threading::SetThreadStackGuarantee;
#[cfg(unix)] #[cfg(all(unix, not(miri)))]
use crate::bolts::os::unix_signals::setup_signal_handler; use crate::bolts::os::unix_signals::setup_signal_handler;
#[cfg(all(feature = "std", unix))] #[cfg(all(feature = "std", unix))]
use crate::bolts::os::unix_signals::{ucontext_t, Handler, Signal}; use crate::bolts::os::unix_signals::{ucontext_t, Handler, Signal};
@ -348,10 +348,12 @@ impl InProcessHandlers {
Z: HasObjective<Objective = OF, State = E::State>, Z: HasObjective<Objective = OF, State = E::State>,
{ {
#[cfg(unix)] #[cfg(unix)]
#[cfg_attr(miri, allow(unused_variables))]
unsafe { unsafe {
let data = &mut GLOBAL_STATE; let data = &mut GLOBAL_STATE;
#[cfg(feature = "std")] #[cfg(feature = "std")]
unix_signal_handler::setup_panic_hook::<E, EM, OF, Z>(); unix_signal_handler::setup_panic_hook::<E, EM, OF, Z>();
#[cfg(not(miri))]
setup_signal_handler(data)?; setup_signal_handler(data)?;
compiler_fence(Ordering::SeqCst); compiler_fence(Ordering::SeqCst);
Ok(Self { Ok(Self {
@ -1284,9 +1286,11 @@ impl InChildProcessHandlers {
where where
E: HasObservers, E: HasObservers,
{ {
#[cfg_attr(miri, allow(unused_variables))]
unsafe { unsafe {
let data = &mut FORK_EXECUTOR_GLOBAL_DATA; let data = &mut FORK_EXECUTOR_GLOBAL_DATA;
// child_signal_handlers::setup_child_panic_hook::<E, I, OT, S>(); // child_signal_handlers::setup_child_panic_hook::<E, I, OT, S>();
#[cfg(not(miri))]
setup_signal_handler(data)?; setup_signal_handler(data)?;
compiler_fence(Ordering::SeqCst); compiler_fence(Ordering::SeqCst);
Ok(Self { Ok(Self {
@ -1301,9 +1305,11 @@ impl InChildProcessHandlers {
where where
E: HasObservers, E: HasObservers,
{ {
#[cfg_attr(miri, allow(unused_variables))]
unsafe { unsafe {
let data = &mut FORK_EXECUTOR_GLOBAL_DATA; let data = &mut FORK_EXECUTOR_GLOBAL_DATA;
// child_signal_handlers::setup_child_panic_hook::<E, I, OT, S>(); // child_signal_handlers::setup_child_panic_hook::<E, I, OT, S>();
#[cfg(not(miri))]
setup_signal_handler(data)?; setup_signal_handler(data)?;
compiler_fence(Ordering::SeqCst); compiler_fence(Ordering::SeqCst);
Ok(Self { Ok(Self {
@ -2075,6 +2081,7 @@ mod tests {
#[test] #[test]
#[serial] #[serial]
#[cfg_attr(miri, ignore)]
#[cfg(all(feature = "std", feature = "fork", unix))] #[cfg(all(feature = "std", feature = "fork", unix))]
fn test_inprocessfork_exec() { fn test_inprocessfork_exec() {
use crate::{ use crate::{

View File

@ -519,6 +519,9 @@ mod tests {
fuzzer fuzzer
.fuzz_one(&mut stages, &mut executor, &mut state, &mut event_manager) .fuzz_one(&mut stages, &mut executor, &mut state, &mut event_manager)
.unwrap_or_else(|_| panic!("Error in iter {i}")); .unwrap_or_else(|_| panic!("Error in iter {i}"));
if cfg!(miri) {
break;
}
} }
let state_serialized = postcard::to_allocvec(&state).unwrap(); let state_serialized = postcard::to_allocvec(&state).unwrap();

View File

@ -1253,6 +1253,7 @@ mod tests {
} }
#[test] #[test]
#[cfg_attr(miri, ignore)] // testing all mutators would be good but is way too slow. :/
fn test_mutators() { fn test_mutators() {
let mut inputs = vec![ let mut inputs = vec![
BytesInput::new(vec![0x13, 0x37]), BytesInput::new(vec![0x13, 0x37]),
@ -1267,6 +1268,7 @@ mod tests {
let mut state = test_state(); let mut state = test_state();
let mut mutations = test_mutations(); let mut mutations = test_mutations();
for _ in 0..2 { for _ in 0..2 {
let mut new_testcases = vec![]; let mut new_testcases = vec![];
for idx in 0..(mutations.len()) { for idx in 0..(mutations.len()) {
@ -1294,7 +1296,10 @@ mod tests {
let mut state = test_state(); let mut state = test_state();
let mut mutator = BytesDeleteMutator::new(); let mut mutator = BytesDeleteMutator::new();
for _ in 0..100000 { // If we're running in miri, we have to make this test a _lot_ shorter.
let iters = if cfg!(miri) { 100 } else { 100_000 };
for _ in 0..iters {
let mut mutated = base.clone(); let mut mutated = base.clone();
if mutator.mutate(&mut state, &mut mutated, 0)? == MutationResult::Skipped { if mutator.mutate(&mut state, &mut mutated, 0)? == MutationResult::Skipped {
continue; continue;
@ -1345,7 +1350,10 @@ mod tests {
let mut state = test_state(); let mut state = test_state();
let mut mutator = BytesExpandMutator::new(); let mut mutator = BytesExpandMutator::new();
for _ in 0..100000 { // If we're running in miri, we have to make this test a _lot_ shorter.
let iters = if cfg!(miri) { 100 } else { 100_000 };
for _ in 0..iters {
let mut mutated = base.clone(); let mut mutated = base.clone();
if mutator.mutate(&mut state, &mut mutated, 0)? == MutationResult::Skipped { if mutator.mutate(&mut state, &mut mutated, 0)? == MutationResult::Skipped {
continue; continue;
@ -1390,7 +1398,10 @@ mod tests {
let mut state = test_state(); let mut state = test_state();
let mut mutator = BytesInsertMutator::new(); let mut mutator = BytesInsertMutator::new();
for _ in 0..100000 { // If we're running in miri, we have to make this test a _lot_ shorter.
let iters = if cfg!(miri) { 100 } else { 100_000 };
for _ in 0..iters {
let mut mutated = base.clone(); let mut mutated = base.clone();
if mutator.mutate(&mut state, &mut mutated, 0)? == MutationResult::Skipped { if mutator.mutate(&mut state, &mut mutated, 0)? == MutationResult::Skipped {
continue; continue;
@ -1436,7 +1447,10 @@ mod tests {
let mut state = test_state(); let mut state = test_state();
let mut mutator = BytesRandInsertMutator::new(); let mut mutator = BytesRandInsertMutator::new();
for _ in 0..100000 { // If we're running in miri, we have to make this test a _lot_ shorter.
let iters = if cfg!(miri) { 100 } else { 100_000 };
for _ in 0..iters {
let mut mutated = base.clone(); let mut mutated = base.clone();
if mutator.mutate(&mut state, &mut mutated, 0)? == MutationResult::Skipped { if mutator.mutate(&mut state, &mut mutated, 0)? == MutationResult::Skipped {
continue; continue;

View File

@ -362,6 +362,7 @@ mod tests {
const TEST_GRAPH_STR: &str = "$$main+41864\n$$_ZN7MyClass1VEi+50306\n%%_ZN7MyClass1VEi+50306\n->19123\n%%main+41864\n->52706\n->26911\n%%main+52706\n%%main+26911\n->52706\n->41925\n"; const TEST_GRAPH_STR: &str = "$$main+41864\n$$_ZN7MyClass1VEi+50306\n%%_ZN7MyClass1VEi+50306\n->19123\n%%main+41864\n->52706\n->26911\n%%main+52706\n%%main+26911\n->52706\n->41925\n";
#[test] #[test]
#[cfg_attr(miri, ignore)] // Testcase takes long in miri.
fn test_basic_cfg_from_str() { fn test_basic_cfg_from_str() {
let cfg: ControlFlowGraph<TestMetaData> = ControlFlowGraph::from_content(TEST_GRAPH_STR); let cfg: ControlFlowGraph<TestMetaData> = ControlFlowGraph::from_content(TEST_GRAPH_STR);
let entry = cfg.get_entry("main").unwrap(); let entry = cfg.get_entry("main").unwrap();
@ -391,6 +392,7 @@ mod tests {
} }
#[test] #[test]
#[cfg_attr(miri, ignore)] // Testcase takes too long in miri. :/
fn test_shortest_path() { fn test_shortest_path() {
let cfg: ControlFlowGraph<TestMetaData> = ControlFlowGraph::from_content(TEST_GRAPH_STR); let cfg: ControlFlowGraph<TestMetaData> = ControlFlowGraph::from_content(TEST_GRAPH_STR);
let distances = cfg.calculate_distances_to_all_edges((41864 >> 1) ^ 26911); let distances = cfg.calculate_distances_to_all_edges((41864 >> 1) ^ 26911);

View File

@ -470,6 +470,7 @@ mod tests {
use crate::{ClangWrapper, CompilerWrapper}; use crate::{ClangWrapper, CompilerWrapper};
#[test] #[test]
#[cfg_attr(miri, ignore)]
fn test_clang_version() { fn test_clang_version() {
if let Err(res) = ClangWrapper::new() if let Err(res) = ClangWrapper::new()
.parse_args(&["my-clang", "-v"]) .parse_args(&["my-clang", "-v"])