si_trace_print
A rust library to print messages indented to stack depth optionally preceded by the function name.
Useful for trace printing function flows.
Use
Add si_trace_print
entry to the project Cargo.toml
section [dependencies]
.
Trace-printing example
The most common use will likely be debug-only printing to stderr with a precding function name.
use ;
This printed
$ cargo run
→hello from main
main will be doing stuff...
→func1: (3)
func1: doing even more stuff...
←func1: (3)
main is done doing stuff...
←goodbye from main
If built with --release
then the statements are not compiled and nothing would
be printed.
An example using a variety of the available eprintln macros.
extern crate si_trace_print;
use ;
should print
→hello from main
→main: hello again from main
→main: hello again from main!
→main: HELLO AGAIN FROM MAIN!!!
main will be doing stuff...
→mod2::func1: (3)
mod2::func1: func1 calling func2...
→mod1::mod2::func2: (4)
mod1::mod2::func2: calling func3...
→func3:
↔func4 is a short function.
↔func4: func4 is a short function.
↔mod2::func4: func4 is a short function.
↔mod1::mod2::func4: func4 is a short function.
func3: almost complete...
←func3:
←mod1::mod2::func2: (4)
←mod2::func1: (3)
main is done doing stuff...
←goodbye from main
Manually setting the indentation
The first use of a library macro will set the "original" stack depth. This is later used to calculate indentation offsets. If the first use of this library is several functions into a program then later printing may be lose indentation.
use ;
prints poorly indented output
→func2: (3)
func2: stack_depth 15, stack_offset 0
←func2: (3)
↔func1: (3) (this is not indented!)
←main: goodbye from main (this is not indented!)
Explictly call stack_offset_set
near the beginning of the thread.
use ;
this printed
→func2: (3)
func2: stack_depth 15, stack_offset 2
←func2: (3)
↔func1: stack_depth 14, stack_offset 1
←main: goodbye from main
The indentation is improved but is too far indented.
The indentation amount to pass to stack_offset_set
can be somewhat unpredictable.
It depends on build settings and which thread is running, among other things.
In this case, experimentation revealed value -1
to be best:
// ...
this printed
→func2: (3)
func2: stack_depth 15, stack_offset 1
←func2: (3)
↔func1: stack_depth 14, stack_offset 0
←main: goodbye from main
Shortcomings
Slow
This trace function may significantly slow a program. It is recommended to use the debug version of provided macros.
Release builds
The calculation of function depth depends on stack frames counted by
backtrace::trace
. In --release
builds or under other optimization profiles, some functions may be optimized inline.
The count of stack frames may not change among function calls.
This means the printed indentation will not reflect function call depth.
This can be forcibly avoided by adding attribute #[inline(never)]
to such
functions.