(&self, binary: &Path, corpus: &Path)
| 293 | } |
| 294 | |
| 295 | pub fn execute_pool(&self, binary: &Path, corpus: &Path) -> Option<ProgramError> { |
| 296 | let cpu_count = max_cpu_count(); |
| 297 | let corpus_files = crate::deopt::utils::read_all_files_in_dir(corpus).unwrap(); |
| 298 | |
| 299 | let pool = ThreadPool::new(cpu_count); |
| 300 | let (tx, rx) = channel(); |
| 301 | let error_occurred = Arc::new(AtomicBool::new(false)); |
| 302 | |
| 303 | for corpus_file in &corpus_files { |
| 304 | let tx = tx.clone(); |
| 305 | let binary = binary.to_path_buf(); |
| 306 | let corpus_file = corpus_file.to_path_buf(); |
| 307 | let error_occurred = Arc::clone(&error_occurred); |
| 308 | let executor = self.clone(); |
| 309 | |
| 310 | pool.execute(move || { |
| 311 | // If an error has occurred in another thread, stop this one |
| 312 | if error_occurred.load(Ordering::SeqCst) { |
| 313 | return; |
| 314 | } |
| 315 | |
| 316 | let args = vec![corpus_file.as_os_str()]; |
| 317 | let has_err = executor |
| 318 | .execute(&binary, args, vec![], None, None, false) |
| 319 | .unwrap(); |
| 320 | if has_err.is_some() { |
| 321 | error_occurred.store(true, Ordering::SeqCst); |
| 322 | } |
| 323 | tx.send(has_err) |
| 324 | .expect("channel will be there waiting for the pool"); |
| 325 | }); |
| 326 | } |
| 327 | pool.join(); |
| 328 | |
| 329 | for _ in 0..corpus_files.len() { |
| 330 | let has_err = rx.recv().unwrap_or(None); |
| 331 | if let Some(err) = has_err { |
| 332 | return Some(err); |
| 333 | } |
| 334 | } |
| 335 | None |
| 336 | } |
| 337 | |
| 338 | pub fn execute_fuzzer(&self, fuzzer: &Path, corpus: Vec<&Path>) -> Result<()> { |
| 339 | // make up corpus for each standalone fuzzer. |
no test coverage detected