| 201 | } |
| 202 | |
| 203 | fn fuzzing_loop(mut fuzzer: Fuzzer, run_for: Option<Duration>) -> anyhow::Result<()> { |
| 204 | let start_time = std::time::Instant::now(); |
| 205 | |
| 206 | let span = tracing::span!(tracing::Level::INFO, "fuzz", id = fuzzer.global.id); |
| 207 | let _guard = span.enter(); |
| 208 | |
| 209 | let mut stats = monitor::LocalStats::default(); |
| 210 | while !fuzzer.vm.interrupt_flag.load(std::sync::atomic::Ordering::Relaxed) |
| 211 | && run_for.map_or(true, |t| start_time.elapsed() < t) |
| 212 | { |
| 213 | fuzzer.state.reset(); |
| 214 | fuzzer.input_id = fuzzer.queue.next_input(&fuzzer.corpus); |
| 215 | |
| 216 | // Default to a very high length extension probability for randomly generated inputs. This |
| 217 | // is overwritten if we are using an input from the corpus. |
| 218 | let mut length_ext_prob = 0.9; |
| 219 | |
| 220 | if let Some(id) = fuzzer.input_id { |
| 221 | let input = &mut fuzzer.corpus[id]; |
| 222 | |
| 223 | let is_import = input.is_import; |
| 224 | let has_unique_edge = input.has_unique_edge; |
| 225 | |
| 226 | // Skip non-favoured inputs with a certain probability. |
| 227 | if !input.favored && fuzzer.rng.gen_bool(0.95) { |
| 228 | continue; |
| 229 | } |
| 230 | |
| 231 | if let std::collections::hash_map::Entry::Vacant(slot) = |
| 232 | fuzzer.corpus[id].stage_data.entry(Stage::Trim) |
| 233 | { |
| 234 | slot.insert(Box::new(())); |
| 235 | fuzzer.stage = Stage::Trim; |
| 236 | if fuzzer.features.smart_trim && !is_import { |
| 237 | trim::TrimStage::run(&mut fuzzer, &mut stats)?; |
| 238 | |
| 239 | // After trimming the input, send it to other workers. |
| 240 | if has_unique_edge { |
| 241 | fuzzer.global.add_new(fuzzer.state.input.clone()); |
| 242 | } |
| 243 | } |
| 244 | } |
| 245 | |
| 246 | if fuzzer.features.cmplog && !is_import { |
| 247 | if let std::collections::hash_map::Entry::Vacant(slot) = |
| 248 | fuzzer.corpus[id].stage_data.entry(Stage::InputToState) |
| 249 | { |
| 250 | slot.insert(Box::new(())); |
| 251 | |
| 252 | if fuzzer.features.colorization { |
| 253 | tracing::debug!("[{id}] running colorization stage"); |
| 254 | fuzzer.stage = Stage::Colorization; |
| 255 | i2s::ColorizationStage::run(&mut fuzzer, &mut stats)?; |
| 256 | } |
| 257 | |
| 258 | tracing::debug!("[{id}] running I2S stage"); |
| 259 | fuzzer.stage = Stage::InputToState; |
| 260 | i2s::I2SReplaceStage::run(&mut fuzzer, &mut stats)?; |