@@ -39,14 +39,15 @@ use indoc::indoc;
3939use libafl:: { inputs:: HasBytesVec , prelude:: ExitKind } ;
4040use libafl_bolts:: prelude:: OwnedMutSlice ;
4141use libafl_targets:: AFLppCmpLogMap ;
42+ use log:: LogMessage ;
4243use magic:: MagicNumber ;
4344use num_traits:: FromPrimitive as _;
4445use serde:: { Deserialize , Serialize } ;
4546use serde_json:: to_writer;
4647use simics:: {
4748 break_simulation, class, debug, error, free_attribute, get_class, get_interface,
48- get_processor_number, info , lookup_file, object_clock, run_command, run_python, simics_init,
49- trace , version_base, AsConfObject , BreakpointId , ClassCreate , ClassObjectsFinalize , ConfObject ,
49+ get_processor_number, lookup_file, object_clock, run_command, run_python, simics_init, trace ,
50+ version_base, AsConfObject , BreakpointId , ClassCreate , ClassObjectsFinalize , ConfObject ,
5051 CoreBreakpointMemopHap , CoreExceptionHap , CoreMagicInstructionHap , CoreSimulationStoppedHap ,
5152 CpuInstrumentationSubscribeInterface , Event , EventClassFlag , FromConfObject , HapHandle ,
5253 Interface , IntoAttrValueDict ,
@@ -381,6 +382,9 @@ pub(crate) struct Tsffs {
381382 /// Whether to quit on iteration limit
382383 pub quit_on_iteration_limit : bool ,
383384 #[ class( attribute( optional, default = false ) ) ]
385+ /// Whether to save execution traces of test cases which result in a timeout
386+ pub save_timeout_execution_traces : bool ,
387+ #[ class( attribute( optional, default = false ) ) ]
384388 /// Whether to save execution traces of test cases which result in a solution
385389 pub save_solution_execution_traces : bool ,
386390 #[ class( attribute( optional, default = false ) ) ]
@@ -399,6 +403,12 @@ pub(crate) struct Tsffs {
399403 #[ class( attribute( optional, default = false ) ) ]
400404 /// Whether execution traces should include just PC (vs instruction text and bytes)
401405 pub execution_trace_pc_only : bool ,
406+ #[ class( attribute( optional, default = true ) ) ]
407+ /// Whether a heartbeat message should be emitted every `heartbeat_interval` seconds
408+ pub heartbeat : bool ,
409+ #[ class( attribute( optional, default = 60 ) ) ]
410+ /// The interval in seconds between heartbeat messages
411+ pub heartbeat_interval : u64 ,
402412
403413 #[ attr_value( skip) ]
404414 /// Handle for the core simulation stopped hap
@@ -489,6 +499,10 @@ pub(crate) struct Tsffs {
489499 // #[builder(default = SystemTime::now())]
490500 /// The time the fuzzer was started at
491501 start_time : OnceCell < SystemTime > ,
502+ #[ attr_value( skip) ]
503+ // #[builder(default = SystemTime::now())]
504+ /// The time the fuzzer was started at
505+ last_heartbeat_time : Option < SystemTime > ,
492506
493507 #[ attr_value( skip) ]
494508 log : OnceCell < File > ,
@@ -521,6 +535,12 @@ pub(crate) struct Tsffs {
521535 #[ attr_value( skip) ]
522536 /// Whether snapshots are used. Snapshots are used on Simics 7.0.0 and later.
523537 use_snapshots : bool ,
538+ #[ attr_value( skip) ]
539+ /// The number of timeouts so far
540+ timeouts : usize ,
541+ #[ attr_value( skip) ]
542+ /// The number of solutions so far
543+ solutions : usize ,
524544}
525545
526546impl ClassObjectsFinalize for Tsffs {
@@ -705,6 +725,8 @@ impl Tsffs {
705725 return Ok ( ( ) ) ;
706726 }
707727
728+ self . log ( LogMessage :: startup ( ) ) ?;
729+
708730 #[ cfg( simics_version_7) ]
709731 {
710732 if self . checkpoint_path . exists ( ) {
@@ -845,9 +867,8 @@ impl Tsffs {
845867 start_processor_cpu,
846868 start_processor_clock,
847869 self . timeout ,
848- move |obj | {
870+ move |_obj | {
849871 let tsffs: & ' static mut Tsffs = tsffs_ptr. into ( ) ;
850- info ! ( tsffs. as_conf_object_mut( ) , "timeout({:#x})" , obj as usize ) ;
851872 tsffs
852873 . stop_simulation ( StopReason :: Solution {
853874 kind : SolutionKind :: Timeout ,
0 commit comments