enter_trace_span

Macro enter_trace_span 

Source
macro_rules! enter_trace_span {
    ($machine:ty, $name:ident :: $subname:ident $($tt:tt)*) => { ... };
    ($machine:ty, $($tt:tt)*) => { ... };
}
Expand description

Shortand for calling crate::interpret::Machine::enter_trace_span on a tracing::info_span!. This is supposed to be compiled out when crate::interpret::Machine::enter_trace_span has the default implementation (i.e. when it does not actually enter the span but instead returns ()). This macro takes a type implementing the crate::interpret::Machine trait as its first argument and otherwise accepts the same syntax as tracing::span! (see some tips below). Note: the result of this macro must be used because the span is exited when it’s dropped.

§Syntax accepted by this macro

The full documentation for the tracing::span! syntax can be found at tracing under “Using the Macros”. A few possibly confusing syntaxes are listed here:

// logs a span named "hello" with a field named "arg" of value 42 (works only because
// 42 implements the tracing::Value trait, otherwise use one of the options below)
let _trace = enter_trace_span!(M, "hello", arg = 42);
// logs a field called "my_display_var" using the Display implementation
let _trace = enter_trace_span!(M, "hello", %my_display_var);
// logs a field called "my_debug_var" using the Debug implementation
let _trace = enter_trace_span!(M, "hello", ?my_debug_var);

§NAME::SUBNAME syntax

In addition to the syntax accepted by tracing::span!, this macro optionally allows passing the span name (i.e. the first macro argument) in the form NAME::SUBNAME (without quotes) to indicate that the span has name “NAME” (usually the name of the component) and has an additional more specific name “SUBNAME” (usually the function name). The latter is passed to the tracing infrastructure as a span field with the name “NAME”. This allows not being distracted by subnames when looking at the trace in https://ui.perfetto.dev, but when deeper introspection is needed within a component, it’s still possible to view the subnames directly in the UI by selecting a span, clicking on the “NAME” argument on the right, and clicking on “Visualize argument values”.

// for example, the first will expand to the second
let _trace = enter_trace_span!(M, borrow_tracker::on_stack_pop, /* ... */);
let _trace = enter_trace_span!(M, "borrow_tracker", borrow_tracker = "on_stack_pop", /* ... */);

§tracing_separate_thread parameter

This macro was introduced to obtain better traces of Miri without impacting release performance. Miri saves traces using the the tracing_chrome tracing::Layer so that they can be visualized in https://ui.perfetto.dev. To instruct tracing_chrome to put some spans on a separate trace thread/line than other spans when viewed in https://ui.perfetto.dev, you can pass tracing_separate_thread = tracing::field::Empty to the tracing macros. This is useful to separate out spans which just indicate the current step or program frame being processed by the interpreter. You should use a value of tracing::field::Empty so that other tracing layers (e.g. the logger) will ignore the tracing_separate_thread field. For example:

let _trace = enter_trace_span!(M, step::eval_statement, tracing_separate_thread = tracing::field::Empty);

§Executing something else when tracing is disabled

crate::interpret::Machine::enter_trace_span returns EnteredTraceSpan, on which you can call EnteredTraceSpan::or_if_tracing_disabled, to e.g. log a line as an alternative to the tracing span for when tracing is disabled. For example:

let _trace = enter_trace_span!(M, step::eval_statement)
    .or_if_tracing_disabled(|| tracing::info!("eval_statement"));