Skip to content

Commit f0908c1

Browse files
committed
refactor: extract shared finish_iteration helper for stop/solution paths
1 parent 92cdebc commit f0908c1

1 file changed

Lines changed: 94 additions & 159 deletions

File tree

src/haps/mod.rs

Lines changed: 94 additions & 159 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ use simics::{
2222
debug, get_processor_number, info, trace, warn,
2323
};
2424

25+
enum IterationControl {
26+
Continue,
27+
StopRequested,
28+
}
29+
2530
impl Tsffs {
2631
fn on_simulation_stopped_magic_start(&mut self, magic_number: MagicNumber) -> Result<()> {
2732
if !self.have_initial_snapshot() {
@@ -91,6 +96,73 @@ impl Tsffs {
9196
self.on_simulation_stopped_solution(SolutionKind::Manual)
9297
}
9398

99+
fn finish_iteration(
100+
&mut self,
101+
exit_kind: ExitKind,
102+
count_as_timeout: Option<bool>,
103+
missing_start_info_message: &str,
104+
) -> Result<IterationControl> {
105+
self.iterations += 1;
106+
107+
if self.iteration_limit != 0 && self.iterations >= self.iteration_limit {
108+
let duration = SystemTime::now().duration_since(
109+
*self
110+
.start_time
111+
.get()
112+
.ok_or_else(|| anyhow!("Start time was not set"))?,
113+
)?;
114+
115+
// Set the log level so this message always prints
116+
set_log_level(self.as_conf_object_mut(), LogLevel::Info)?;
117+
118+
info!(
119+
self.as_conf_object(),
120+
"Configured iteration count {} reached. Stopping after {} seconds ({} exec/s).",
121+
self.iterations,
122+
duration.as_secs_f32(),
123+
self.iterations as f32 / duration.as_secs_f32()
124+
);
125+
126+
self.send_shutdown()?;
127+
128+
if self.quit_on_iteration_limit {
129+
quit(0)?;
130+
} else {
131+
return Ok(IterationControl::StopRequested);
132+
}
133+
}
134+
135+
if let Some(is_timeout) = count_as_timeout {
136+
if is_timeout {
137+
self.timeouts += 1;
138+
} else {
139+
self.solutions += 1;
140+
}
141+
}
142+
143+
let fuzzer_tx = self
144+
.fuzzer_tx
145+
.get()
146+
.ok_or_else(|| anyhow!("No fuzzer tx channel"))?;
147+
148+
fuzzer_tx.send(exit_kind)?;
149+
150+
if self.should_restore_snapshot_this_iteration() {
151+
self.restore_initial_snapshot()?;
152+
}
153+
self.coverage_prev_loc = 0;
154+
155+
if self.start_info.get().is_some() {
156+
self.get_and_write_testcase()?;
157+
} else {
158+
debug!(self.as_conf_object(), "{missing_start_info_message}");
159+
}
160+
161+
self.post_timeout_event()?;
162+
163+
Ok(IterationControl::Continue)
164+
}
165+
94166
fn on_simulation_stopped_magic_stop(&mut self) -> Result<()> {
95167
if !self.have_initial_snapshot() {
96168
warn!(
@@ -117,58 +189,13 @@ impl Tsffs {
117189
return Ok(());
118190
}
119191

120-
self.iterations += 1;
121-
122-
if self.iteration_limit != 0 && self.iterations >= self.iteration_limit {
123-
let duration = SystemTime::now().duration_since(
124-
*self
125-
.start_time
126-
.get()
127-
.ok_or_else(|| anyhow!("Start time was not set"))?,
128-
)?;
129-
130-
// Set the log level so this message always prints
131-
set_log_level(self.as_conf_object_mut(), LogLevel::Info)?;
132-
133-
info!(
134-
self.as_conf_object(),
135-
"Configured iteration count {} reached. Stopping after {} seconds ({} exec/s).",
136-
self.iterations,
137-
duration.as_secs_f32(),
138-
self.iterations as f32 / duration.as_secs_f32()
139-
);
140-
141-
self.send_shutdown()?;
142-
143-
if self.quit_on_iteration_limit {
144-
quit(0)?;
145-
} else {
146-
return Ok(());
147-
}
148-
}
149-
150-
let fuzzer_tx = self
151-
.fuzzer_tx
152-
.get()
153-
.ok_or_else(|| anyhow!("No fuzzer tx channel"))?;
154-
155-
fuzzer_tx.send(ExitKind::Ok)?;
156-
157-
if self.should_restore_snapshot_this_iteration() {
158-
self.restore_initial_snapshot()?;
159-
}
160-
self.coverage_prev_loc = 0;
161-
162-
if self.start_info.get().is_some() {
163-
self.get_and_write_testcase()?;
164-
} else {
165-
debug!(
166-
self.as_conf_object(),
167-
"Missing start buffer or size, not writing testcase."
168-
);
192+
if let IterationControl::StopRequested = self.finish_iteration(
193+
ExitKind::Ok,
194+
None,
195+
"Missing start buffer or size, not writing testcase.",
196+
)? {
197+
return Ok(());
169198
}
170-
171-
self.post_timeout_event()?;
172199
}
173200

174201
if self.save_all_execution_traces {
@@ -330,58 +357,13 @@ impl Tsffs {
330357
return Ok(());
331358
}
332359

333-
self.iterations += 1;
334-
335-
if self.iteration_limit != 0 && self.iterations >= self.iteration_limit {
336-
let duration = SystemTime::now().duration_since(
337-
*self
338-
.start_time
339-
.get()
340-
.ok_or_else(|| anyhow!("Start time was not set"))?,
341-
)?;
342-
343-
// Set the log level so this message always prints
344-
set_log_level(self.as_conf_object_mut(), LogLevel::Info)?;
345-
346-
info!(
347-
self.as_conf_object(),
348-
"Configured iteration count {} reached. Stopping after {} seconds ({} exec/s).",
349-
self.iterations,
350-
duration.as_secs_f32(),
351-
self.iterations as f32 / duration.as_secs_f32()
352-
);
353-
354-
self.send_shutdown()?;
355-
356-
if self.quit_on_iteration_limit {
357-
quit(0)?;
358-
} else {
359-
return Ok(());
360-
}
361-
}
362-
363-
let fuzzer_tx = self
364-
.fuzzer_tx
365-
.get()
366-
.ok_or_else(|| anyhow!("No fuzzer tx channel"))?;
367-
368-
fuzzer_tx.send(ExitKind::Ok)?;
369-
370-
if self.should_restore_snapshot_this_iteration() {
371-
self.restore_initial_snapshot()?;
372-
}
373-
self.coverage_prev_loc = 0;
374-
375-
if self.start_info.get().is_some() {
376-
self.get_and_write_testcase()?;
377-
} else {
378-
debug!(
379-
self.as_conf_object(),
380-
"Missing start buffer or size, not writing testcase. This may be due to using manual no-buffer harnessing."
381-
);
360+
if let IterationControl::StopRequested = self.finish_iteration(
361+
ExitKind::Ok,
362+
None,
363+
"Missing start buffer or size, not writing testcase. This may be due to using manual no-buffer harnessing.",
364+
)? {
365+
return Ok(());
382366
}
383-
384-
self.post_timeout_event()?;
385367
}
386368

387369
if self.save_all_execution_traces {
@@ -428,67 +410,20 @@ impl Tsffs {
428410
return Ok(());
429411
}
430412

431-
self.iterations += 1;
432-
433-
if self.iteration_limit != 0 && self.iterations >= self.iteration_limit {
434-
let duration = SystemTime::now().duration_since(
435-
*self
436-
.start_time
437-
.get()
438-
.ok_or_else(|| anyhow!("Start time was not set"))?,
439-
)?;
440-
441-
// Set the log level so this message always prints
442-
set_log_level(self.as_conf_object_mut(), LogLevel::Info)?;
443-
444-
info!(
445-
self.as_conf_object(),
446-
"Configured iteration count {} reached. Stopping after {} seconds ({} exec/s).",
447-
self.iterations,
448-
duration.as_secs_f32(),
449-
self.iterations as f32 / duration.as_secs_f32()
450-
);
451-
452-
self.send_shutdown()?;
453-
454-
if self.quit_on_iteration_limit {
455-
quit(0)?;
456-
} else {
457-
return Ok(());
458-
}
459-
}
460-
461-
let fuzzer_tx = self
462-
.fuzzer_tx
463-
.get()
464-
.ok_or_else(|| anyhow!("No fuzzer tx channel"))?;
465-
466-
match kind {
467-
SolutionKind::Timeout => {
468-
self.timeouts += 1;
469-
fuzzer_tx.send(ExitKind::Timeout)?
470-
}
413+
let (exit_kind, count_as_timeout) = match kind {
414+
SolutionKind::Timeout => (ExitKind::Timeout, true),
471415
SolutionKind::Exception | SolutionKind::Breakpoint | SolutionKind::Manual => {
472-
self.solutions += 1;
473-
fuzzer_tx.send(ExitKind::Crash)?
416+
(ExitKind::Crash, false)
474417
}
475-
}
476-
477-
if self.should_restore_snapshot_this_iteration() {
478-
self.restore_initial_snapshot()?;
479-
}
480-
self.coverage_prev_loc = 0;
418+
};
481419

482-
if self.start_info.get().is_some() {
483-
self.get_and_write_testcase()?;
484-
} else {
485-
debug!(
486-
self.as_conf_object(),
487-
"Missing start buffer or size, not writing testcase."
488-
);
420+
if let IterationControl::StopRequested = self.finish_iteration(
421+
exit_kind,
422+
Some(count_as_timeout),
423+
"Missing start buffer or size, not writing testcase.",
424+
)? {
425+
return Ok(());
489426
}
490-
491-
self.post_timeout_event()?;
492427
}
493428

494429
if self.save_all_execution_traces {

0 commit comments

Comments
 (0)