Skip to content

Commit ca7e94b

Browse files
committed
refactor tracing options: run-input --trace=func/line/instr
1 parent 72d9eb1 commit ca7e94b

6 files changed

Lines changed: 91 additions & 35 deletions

File tree

src/cli/mod.rs

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@ use std::{
1010
use crate::{
1111
fuzzer::opts::{FlagBool, InstrumentationOpts},
1212
ir::ModuleSpec,
13-
jit::{FeedbackOptions, JitFuzzingSession, Stats, TracingOptions, module::TrapKind},
13+
jit::{
14+
DebugTrace, FeedbackOptions, JitFuzzingSession, Stats, TracingOptions, module::TrapKind,
15+
},
1416
};
1517

1618
mod cmin;
@@ -47,8 +49,14 @@ pub(crate) enum Subcommand {
4749
RunInput {
4850
program: PathBuf,
4951
inputs: Vec<String>,
50-
#[clap(long)]
51-
trace: bool,
52+
#[clap(
53+
long,
54+
value_enum,
55+
require_equals = true,
56+
num_args = 0..=1,
57+
default_missing_value = "instr"
58+
)]
59+
trace: Option<DebugTrace>,
5260
#[clap(long)]
5361
verbose_jit: bool,
5462
#[clap(long, default_value = "true")]
@@ -161,6 +169,7 @@ pub(crate) enum Subcommand {
161169
#[clap(long, default_value = "10000")]
162170
iters: usize,
163171
},
172+
/// Extract embedded sources from the debug info.
164173
#[clap(hide = true)]
165174
DumpEmbeddedSources {
166175
program: PathBuf,
@@ -246,13 +255,14 @@ pub(crate) fn main() {
246255
let mod_spec = parse_program(&program);
247256
let mut stats = Stats::default();
248257
let mut sess = JitFuzzingSession::builder(mod_spec)
258+
.debug_trace(trace.unwrap_or(DebugTrace::Disabled))
249259
// .feedback(i.to_feedback_opts())
250260
.feedback(FeedbackOptions::nothing())
251261
.tracing(TracingOptions {
252262
stdout: *print_stdout,
253263
..TracingOptions::default()
254264
})
255-
.debug(trace, verbose_jit)
265+
.verbose(verbose_jit)
256266
.instruction_limit(Some(2_000_000_000))
257267
.optimize_for_compilation_time(inputs.len() <= 10)
258268
.run_from_snapshot(*run_from_snapshot)
@@ -315,13 +325,18 @@ pub(crate) fn main() {
315325
let mod_spec = parse_program(&program);
316326
let mut stats = Stats::default();
317327
let mut sess = JitFuzzingSession::builder(mod_spec)
328+
.debug_trace(if trace {
329+
DebugTrace::Instruction
330+
} else {
331+
DebugTrace::Disabled
332+
})
318333
.feedback(i.to_feedback_opts())
319334
.feedback(FeedbackOptions::nothing())
320335
.tracing(TracingOptions {
321336
stdout: true,
322337
..TracingOptions::default()
323338
})
324-
.debug(trace, verbose)
339+
.verbose(verbose)
325340
.run_from_snapshot(*run_from_snapshot)
326341
.build();
327342
sess.initialize(&mut stats);

src/fuzzer/orc.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,8 @@ pub(crate) struct Orchestrator {
319319
impl Orchestrator {
320320
fn new(module: Arc<ModuleSpec>, opts: CliOpts, corpus: Arc<RwLock<SharedCorpus>>) -> Self {
321321
let now = Instant::now();
322-
let mut codecov_sess = JitFuzzingSessionBuilder::new(module.clone())
322+
let mut codecov_sess =
323+
JitFuzzingSessionBuilder::new(module.clone())
323324
.feedback(FeedbackOptions {
324325
live_funcs: true,
325326
live_bbs: true,

src/jit/control.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,7 @@ pub(crate) fn translate_control<'a, 'b, 's>(
308308
rvals.extend_from_slice(&concolic_vars);
309309
}
310310

311-
if state.options.debug_trace {
311+
if state.options.debug_trace.enabled() {
312312
let s = format!("returning from {} by explicit return", state.fspec().symbol);
313313
super::builtins::translate_debug_log(s, state, bcx);
314314
}

src/jit/function.rs

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,7 @@ impl<'a, 's> FuncTranslator<'a, 's> {
371371
}
372372

373373
pub(crate) fn undef(&mut self, ty: Type, bcx: &mut FunctionBuilder) -> ir::Value {
374-
if self.options.debug_trace {
374+
if self.options.debug_trace.enabled() {
375375
super::builtins::translate_debug_log(
376376
"!!! using undefined value !!!".to_string(),
377377
self,
@@ -458,16 +458,8 @@ impl<'a, 's> FuncTranslator<'a, 's> {
458458
}
459459
}
460460

461-
if self.options.debug_trace
462-
&& !std::env::var("JITTRACE")
463-
.map(|s| s == "thin")
464-
.unwrap_or(false)
465-
{
466-
let is_line = std::env::var("JITTRACE")
467-
.map(|s| s == "line")
468-
.unwrap_or(false);
469-
470-
if is_line {
461+
if self.options.debug_trace.include_instructions() {
462+
if self.options.debug_trace.include_source_line() {
471463
let addr = self.fspec().operators_wasm_bin_offset_base as u64
472464
+ self.fspec().operator_offset_rel[self.ip.i()] as u64;
473465
let line = crate::ir::debuginfo_helper::resolve_source_location(

src/jit/mod.rs

Lines changed: 63 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -441,26 +441,61 @@ pub(crate) struct CompilationOptions {
441441
pub tracing: TracingOptions,
442442
pub swarm: SwarmConfig, // is `scope` a better name?
443443
pub verbose: bool,
444-
pub debug_trace: bool,
444+
pub debug_trace: DebugTrace,
445445
pub kind: CompilationKind,
446446
pub optimize_for_compilation_time: bool,
447447
}
448448

449+
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, Default, clap::ValueEnum)]
450+
pub(crate) enum DebugTrace {
451+
#[default]
452+
Disabled,
453+
Function,
454+
Instruction,
455+
Line,
456+
}
457+
458+
impl DebugTrace {
459+
fn from_str(s: &str) -> Option<Self> {
460+
match s {
461+
"thin" | "func" | "function" => Some(Self::Function),
462+
"full" | "instr" | "instruction" | "1" => Some(Self::Instruction),
463+
"line" => Some(Self::Line),
464+
_ => None,
465+
}
466+
}
467+
fn from_env() -> Option<Self> {
468+
match std::env::var("JITTRACE").ok().as_deref() {
469+
Some(s) => Self::from_str(s),
470+
_ => None,
471+
}
472+
}
473+
474+
pub(crate) fn enabled(self) -> bool {
475+
!matches!(self, Self::Disabled)
476+
}
477+
478+
pub(crate) fn include_instructions(self) -> bool {
479+
matches!(self, Self::Instruction | Self::Line)
480+
}
481+
482+
pub(crate) fn include_source_line(self) -> bool {
483+
matches!(self, Self::Line)
484+
}
485+
}
486+
449487
impl CompilationOptions {
450488
pub fn new(
451489
tracking: &TrackingOptions,
452490
tracing: &TracingOptions,
453491
swarm: &SwarmConfig,
454492
kind: CompilationKind,
455-
debug_trace: bool,
493+
debug_trace: DebugTrace,
456494
verbose: bool,
457495
optimize_for_compilation_time: bool,
458496
) -> Self {
459497
Self {
460-
debug_trace: debug_trace
461-
|| std::env::var("JITTRACE")
462-
.map(|el| el == "1" || el == "thin" || el == "line")
463-
.unwrap_or_default(),
498+
debug_trace: DebugTrace::from_env().unwrap_or(debug_trace),
464499
verbose: verbose
465500
|| std::env::var("JITDEBUG")
466501
.map(|el| el == "1")
@@ -708,8 +743,14 @@ impl JitStage {
708743
if let Some(instance) = &mut self.instance
709744
&& instance.vmctx.tainted
710745
{
711-
// eprintln!("resetting vmctx because it's tainted");
712-
self.inp_ptr = None;
746+
if self.run_from_snapshot {
747+
// `snapshot()` after init sets `heap_snapshot_is_initial = false`, so `reset()`
748+
// cannot run. Any trap (including OutOfFuel) marks tainted; restore to the
749+
// post-init snapshot and keep `inp_ptr` — `run()` also restores before each exec.
750+
instance.vmctx.restore();
751+
} else {
752+
self.inp_ptr = None;
753+
}
713754
}
714755

715756
if self.inp_ptr.is_none() {
@@ -774,9 +815,12 @@ impl JitStage {
774815
.expect("malloc shouldn't trap");
775816
self.inp_ptr = Some(inp_ptr);
776817
instance.vmctx.fuel_init = opts.swarm.instruction_limit.unwrap_or(u32::MAX as u64);
777-
instance.vmctx.heap_pages_limit_soft =
778-
opts.swarm.memory_limit_pages.unwrap_or(u32::MAX);
779-
instance.vmctx.heap_pages_limit_hard = crate::MEMORY_PAGES_LIMIT;
818+
let mem_pages = opts.swarm.memory_limit_pages;
819+
instance.vmctx.heap_pages_limit_soft = mem_pages.unwrap_or(u32::MAX);
820+
// Honor `--memory-limit-pages` for the hard cap too (default remains MEMORY_PAGES_LIMIT).
821+
instance.vmctx.heap_pages_limit_hard = mem_pages
822+
.unwrap_or(crate::MEMORY_PAGES_LIMIT)
823+
.max(crate::MEMORY_PAGES_LIMIT);
780824
if self.run_from_snapshot {
781825
instance.vmctx.snapshot();
782826
}
@@ -833,7 +877,7 @@ impl JitStage {
833877
pub(crate) struct JitFuzzingSessionBuilder {
834878
mod_spec: Arc<ModuleSpec>,
835879
tracing: TracingOptions,
836-
debug_trace: bool,
880+
debug_trace: DebugTrace,
837881
verbose: bool,
838882
swarm: SwarmConfig,
839883
passes_generator: Arc<dyn PassesGen>,
@@ -852,7 +896,7 @@ impl JitFuzzingSessionBuilder {
852896
};
853897
Self {
854898
tracing: TracingOptions::default(),
855-
debug_trace: false,
899+
debug_trace: DebugTrace::Disabled,
856900
verbose: false,
857901
swarm,
858902
passes_generator: Arc::new(FullFeedbackPasses {
@@ -882,8 +926,12 @@ impl JitFuzzingSessionBuilder {
882926
self
883927
}
884928

885-
pub(crate) fn debug(mut self, debug_trace: bool, verbose: bool) -> Self {
929+
pub(crate) fn debug_trace(mut self, debug_trace: DebugTrace) -> Self {
886930
self.debug_trace = debug_trace;
931+
self
932+
}
933+
934+
pub(crate) fn verbose(mut self, verbose: bool) -> Self {
887935
self.verbose = verbose;
888936
self
889937
}
@@ -933,7 +981,7 @@ pub(crate) struct JitFuzzingSession {
933981
pub(crate) tracing_stage: JitStage,
934982
reusable_exec_history: Vec<Vec<u8>>,
935983
run_from_snapshot: bool,
936-
debug_trace: bool,
984+
debug_trace: DebugTrace,
937985
verbose: bool,
938986
optimize_for_compilation_time: bool,
939987
pub(crate) swarm: SwarmConfig,

src/jit/module.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ impl<'s> ModuleTranslator<'s> {
402402
println!("/ {}", func.symbol);
403403
}
404404

405-
if options.debug_trace {
405+
if options.debug_trace.enabled() {
406406
super::builtins::translate_debug_log(
407407
format!(
408408
"entering {} ({})",
@@ -443,7 +443,7 @@ impl<'s> ModuleTranslator<'s> {
443443
rvals.extend_from_slice(&concolic_vars);
444444
}
445445

446-
if options.debug_trace {
446+
if options.debug_trace.enabled() {
447447
super::builtins::translate_debug_log(
448448
format!("returning from {} via function end", func.symbol),
449449
&mut functrans,

0 commit comments

Comments
 (0)