Runs the VM until it exits or executs `limit` number of instructions and update the current fuzzing state.
(&mut self, limit: u64)
| 661 | /// Runs the VM until it exits or executs `limit` number of instructions and update the current |
| 662 | /// fuzzing state. |
| 663 | pub fn execute_with_limit(&mut self, limit: u64) -> Option<VmExit> { |
| 664 | let exec_start = std::time::Instant::now(); |
| 665 | |
| 666 | let old_limit = self.vm.icount_limit; |
| 667 | self.vm.icount_limit = limit; |
| 668 | if let Some(cmplog) = self.cmplog { |
| 669 | cmplog.clear_data(&mut self.vm.cpu); |
| 670 | } |
| 671 | let exit = self.target.run(&mut self.vm).unwrap(); |
| 672 | self.vm.icount_limit = old_limit; |
| 673 | self.execs += 1; |
| 674 | |
| 675 | self.state.exec_time = exec_start.elapsed(); |
| 676 | self.state.instructions = self.vm.cpu.icount(); |
| 677 | self.state.exit = exit; |
| 678 | self.state.exit_address = self.vm.cpu.read_pc(); |
| 679 | |
| 680 | if matches!(exit, VmExit::Interrupted) { |
| 681 | return None; |
| 682 | } |
| 683 | |
| 684 | if self.global.is_main_instance() { |
| 685 | let new_blocks = self.seen_blocks.add_new(&self.vm.code, self.corpus.inputs() as u64); |
| 686 | if self.features.dump_jit_mapping && new_blocks { |
| 687 | if let Err(e) = self |
| 688 | .vm |
| 689 | .jit |
| 690 | .dump_jit_mapping("jit_table.txt".as_ref(), self.vm.env.debug_info().unwrap()) |
| 691 | { |
| 692 | tracing::warn!("Failed to dump JIT table: {e}") |
| 693 | } |
| 694 | } |
| 695 | |
| 696 | if let Err(e) = self.seen_blocks.maybe_save(&self.workdir.join("cur_coverage.txt")) { |
| 697 | tracing::error!("error saving coverage file: {e:?}"); |
| 698 | } |
| 699 | let _ = self.corpus.maybe_save(&self.workdir); |
| 700 | } |
| 701 | |
| 702 | Some(exit) |
| 703 | } |
| 704 | |
| 705 | pub fn check_exit_state(&mut self, exit: VmExit) -> anyhow::Result<()> { |
| 706 | if self.state.input.total_bytes() == 0 { |
no test coverage detected