1#![forbid(unsafe_code)]
10
11use std::sync::OnceLock;
12
13static IS_REPRO: OnceLock<bool> = OnceLock::new();
14
15pub fn is_repro() -> bool {
19 *IS_REPRO.get_or_init(|| std::env::var("XTASK_FUZZ_REPRO").is_ok())
20}
21
22pub fn init_tracing_if_repro() {
24 use std::sync::Once;
25 use tracing_subscriber::filter::LevelFilter;
26 use tracing_subscriber::filter::Targets;
27 use tracing_subscriber::fmt::format::FmtSpan;
28 use tracing_subscriber::layer::SubscriberExt;
29 use tracing_subscriber::util::SubscriberInitExt;
30
31 static INIT: Once = Once::new();
33
34 if is_repro() {
35 INIT.call_once(|| {
36 let targets = if let Ok(var) = std::env::var("OPENVMM_LOG") {
37 var.parse().unwrap()
38 } else {
39 Targets::new().with_default(LevelFilter::TRACE)
40 };
41
42 tracing_subscriber::fmt()
43 .compact()
44 .log_internal_errors(true)
45 .with_max_level(LevelFilter::TRACE)
46 .with_span_events(FmtSpan::NEW | FmtSpan::CLOSE)
47 .finish()
48 .with(targets)
49 .init();
50 });
51 }
52}
53
54#[macro_export]
56macro_rules! fuzz_eprintln {
57 ($($arg:tt)*) => {
58 if $crate::is_repro() {
59 eprintln!($($arg)*)
60 }
61 };
62}
63
64#[cfg(all(target_os = "linux", target_env = "gnu"))]
65pub use libfuzzer_sys::fuzz_target;
66
67#[cfg(not(all(target_os = "linux", target_env = "gnu")))]
68#[macro_export]
70macro_rules! fuzz_target {
71 ($($tt:tt)*) => {
72 fn main() {
75 let _ = do_fuzz;
76 }
77 };
78}