Using multi-process to run a fixed size of batch of programs, and check the program correctness.
(
&self,
programs: &[PathBuf],
)
| 195 | |
| 196 | /// Using multi-process to run a fixed size of batch of programs, and check the program correctness. |
| 197 | pub fn concurrent_check_batch( |
| 198 | &self, |
| 199 | programs: &[PathBuf], |
| 200 | ) -> Result<Vec<Option<ProgramError>>> { |
| 201 | let mut childs = Vec::new(); |
| 202 | for program in programs { |
| 203 | let child = Command::new("cargo") |
| 204 | .env("RUST_BACKTRACE", "full") |
| 205 | .arg("run") |
| 206 | .arg("-q") |
| 207 | .arg("--bin") |
| 208 | .arg("harness") |
| 209 | .arg("--") |
| 210 | .arg(get_library_name()) |
| 211 | .arg("check") |
| 212 | .arg(program) |
| 213 | .stdout(Stdio::null()) |
| 214 | .stderr(Stdio::piped()) |
| 215 | .spawn() |
| 216 | .expect("failed to execute the concurrent transform process"); |
| 217 | childs.push(child); |
| 218 | } |
| 219 | let mut has_errs: Vec<Option<ProgramError>> = Vec::new(); |
| 220 | // for each child process, wait output and log the error reason. |
| 221 | for (i, child) in childs.into_iter().enumerate() { |
| 222 | let output = child.wait_with_output().expect("command wasn't running"); |
| 223 | let program = programs.get(i).unwrap(); |
| 224 | if !output.status.success() { |
| 225 | let err_msg = String::from_utf8_lossy(&output.stderr).to_string(); |
| 226 | let p_err = serde_json::from_str::<ProgramError>(&err_msg); |
| 227 | if let Ok(err) = p_err { |
| 228 | has_errs.push(Some(err)); |
| 229 | } else { |
| 230 | has_errs.push(Some(ProgramError::Fuzzer(err_msg))); |
| 231 | } |
| 232 | log::trace!("error: {program:?}"); |
| 233 | } else { |
| 234 | has_errs.push(None); |
| 235 | log::trace!("correct: {program:?}"); |
| 236 | } |
| 237 | } |
| 238 | Ok(has_errs) |
| 239 | } |
| 240 | |
| 241 | |
| 242 | // Evolving the fuzzing corpus by finding the new coverage corpus files and merge them in shared corpus. |