pub struct TraceState {
pub watchpoints: Vec<Watchpoint>,
pub sink: RefCell<Option<Box<dyn Write + Send>>>,
pub exec_on: bool,
pub last_eip: u32,
}Expand description
Per-sandbox trace state — owned by crate::emulator::Mmu so
the MMU’s hot path can consult watchpoints without an extra
indirection, and shared via &mut with the higher layers
(Cpu, Sandbox, Win32 dispatch) that emit their own probe
flavours.
Fields§
§watchpoints: Vec<Watchpoint>Active watchpoints. Linear-scan inside hot paths; we don’t expect more than a handful at a time per spec.
sink: RefCell<Option<Box<dyn Write + Send>>>Sink that JSONL events flush to. None ⇒ events are
silently dropped (per the design doc), even when the
feature is on.
Wrapped in RefCell so the immutable load paths in the
MMU (which take &self) can still emit a mem_read
event without forcing every caller in the crate onto a
&mut Mmu borrow.
exec_on: booltrue when the trace-exec sub-feature is on AND the
runtime has flipped the per-instruction trace on. The
feature flag alone gates compilation; this flag gates
emission per-step, so a sandbox can toggle exec trace mid
run when triaging a specific section.
last_eip: u32Mirror of cpu.regs.eip updated by crate::emulator::Cpu::step
before each MMU access — the MMU itself doesn’t have a
reference to the CPU, so we shadow the EIP into the trace
state on the slow probe path.
Implementations§
Source§impl TraceState
impl TraceState
Sourcepub fn new() -> Self
pub fn new() -> Self
Create a TraceState with an empty watchpoint set, the default sink (env-var) installed, and exec-trace off.
Sourcepub fn watch(&mut self, addr: u32, size: u32, mode: WatchMode)
pub fn watch(&mut self, addr: u32, size: u32, mode: WatchMode)
Install a watchpoint. Multiple watchpoints may overlap;
each fires independently. A duplicate
(addr, size, mode) is registered as a separate entry —
callers wanting de-dup can use Self::unwatch first.
Sourcepub fn unwatch(&mut self, addr: u32, size: u32)
pub fn unwatch(&mut self, addr: u32, size: u32)
Remove watchpoints whose (addr, size) exactly matches.
Mode is ignored for the match — the design doc treats a
(addr, size) pair as the watchpoint identity.
Sourcepub fn set_sink(&mut self, sink: Box<dyn Write + Send>)
pub fn set_sink(&mut self, sink: Box<dyn Write + Send>)
Override the sink at runtime. Use this from tests to
capture events into a Vec<u8>-backed Box<dyn Write>.
Sourcepub fn clear_sink(&mut self)
pub fn clear_sink(&mut self)
Convenience inverse — tear down the current sink so subsequent emits drop silently.
Sourcepub fn set_eip(&mut self, eip: u32)
pub fn set_eip(&mut self, eip: u32)
Set the per-step EIP shadow. Called by
crate::emulator::Cpu::step once per instruction so the
MMU’s mem_read / mem_write probes can include the
faulting EIP without taking another reference to the CPU.
Sourcepub fn matched_for_write(&self, addr: u32, size: u32) -> Option<&Watchpoint>
pub fn matched_for_write(&self, addr: u32, size: u32) -> Option<&Watchpoint>
Walk the watchpoint list — return the first watchpoint
whose mode + range matches the access, or None.
Sourcepub fn matched_for_read(&self, addr: u32, size: u32) -> Option<&Watchpoint>
pub fn matched_for_read(&self, addr: u32, size: u32) -> Option<&Watchpoint>
As above for reads.
Sourcepub fn emit_line(&self, line: &str)
pub fn emit_line(&self, line: &str)
Write one already-formatted JSONL line followed by \n.
Errors are silenced — the trace tape is a debugging
convenience, not part of any correctness contract.
Sourcepub fn has_sink(&self) -> bool
pub fn has_sink(&self) -> bool
True iff a sink is currently installed. Used by emit helpers to short-circuit the formatting work when the event would be dropped.
Sourcepub fn ev_win32_call(
&self,
dll: &str,
name: &str,
args: &[u32],
ret: u32,
eip: u32,
)
pub fn ev_win32_call( &self, dll: &str, name: &str, args: &[u32], ret: u32, eip: u32, )
Emit a kind=win32_call event.
args is captured from the guest stack at call time;
ret is the dword the stub put back into eax.
Sourcepub fn ev_mem_write(&self, addr: u32, size: u32, value: u64, eip: u32)
pub fn ev_mem_write(&self, addr: u32, size: u32, value: u64, eip: u32)
Emit a kind=mem_write event.
Sourcepub fn ev_mem_read(&self, addr: u32, size: u32, value: u64, eip: u32)
pub fn ev_mem_read(&self, addr: u32, size: u32, value: u64, eip: u32)
Emit a kind=mem_read event.