(&mut self, exit: VmExit)
| 703 | } |
| 704 | |
| 705 | pub fn check_exit_state(&mut self, exit: VmExit) -> anyhow::Result<()> { |
| 706 | if self.state.input.total_bytes() == 0 { |
| 707 | // Discard zero length inputs, these can sometimes occur as a result of trimming very |
| 708 | // small inputs. |
| 709 | self.state.mutation_kinds.clear(); |
| 710 | return Ok(()); |
| 711 | } |
| 712 | |
| 713 | let crash_kind = CrashKind::from(exit); |
| 714 | |
| 715 | self.state.new_bits = self.coverage.new_bits(&mut self.vm); |
| 716 | self.state.new_coverage = !self.state.new_bits.is_empty(); |
| 717 | if self.state.new_coverage { |
| 718 | let bits = self.coverage.get_bits(&mut self.vm); |
| 719 | self.state.coverage_bits = count_all_bits(bits); |
| 720 | self.state.hit_coverage = coverage::bit_iter(bits).map(|x| x as u32).collect(); |
| 721 | |
| 722 | if tracing::enabled!(tracing::Level::TRACE) { |
| 723 | self.trace_new_bits(); |
| 724 | } |
| 725 | } |
| 726 | |
| 727 | // Update coverage map if the input was non-crashing. |
| 728 | // |
| 729 | // Note: we intentionally save hangs here since we observe frequent hangs that reach new |
| 730 | // coverage due to the nature of the hang heuristics. |
| 731 | if !crash_kind.is_crash() { |
| 732 | if self.state.new_coverage { |
| 733 | if config::VALIDATE { |
| 734 | debugging::validate_last_exec(self, exit); |
| 735 | } |
| 736 | self.coverage.merge(&mut self.vm); |
| 737 | self.state |
| 738 | .hit_coverage |
| 739 | .iter() |
| 740 | .for_each(|bit| _ = self.crash_coverage_bits.remove(bit)); |
| 741 | tracing::debug!("{} bits set in coverage map", self.coverage.count()); |
| 742 | } |
| 743 | else if self.features.add_favored_inputs |
| 744 | && self.queue.new_inputs() == 0 |
| 745 | && self.stage != Stage::Trim |
| 746 | && self.rng.gen_bool(0.01) |
| 747 | { |
| 748 | // Occasionally check if the current input is favored over previous entries. |
| 749 | let bits = self.coverage.get_bits(&mut self.vm); |
| 750 | self.state.coverage_bits = count_all_bits(bits); |
| 751 | self.state.hit_coverage = coverage::bit_iter(bits).map(|x| x as u32).collect(); |
| 752 | if queue::current_state_is_favored(&mut self.state, &mut self.corpus) { |
| 753 | self.state.new_coverage = true; |
| 754 | } |
| 755 | } |
| 756 | |
| 757 | if let Some(input_id) = self.queue.add_if_interesting(&mut self.corpus, &self.state) { |
| 758 | self.update_input_metadata(input_id); |
| 759 | self.last_find = self.execs; |
| 760 | } |
| 761 | } |
| 762 | else { |
no test coverage detected