ser-hex
Serialization tracing and visualization tools.
Attempts to answer the question "where did these bytes come from??" when examining opaque binary blobs of data.
ser-hex-tui
cargo run --release --bin ser-hex-tui examples/bson/trace.json
trace format
The trace output contains the binary data and a tree of stream actions (Read/Seek/Span).
capturing a trace
There are two methods of capturing trace data from rust:
rust Tracing instrumentation
Builds spans by listening to tracing::instrument'd functions. This results
in accurately nested spans but requires manual annotation of functions.
let mut input = new;
read_incremental?;
backtrace captures
The second option is to construct spans from backtrace captures. This does not require sprinkling instrumentation annotations all over the serialization code, but can result in lower quality trace data. Since backtraces are captured only on read/seek events, it's impossible to know how far up the stack control flow went between reads, which can lead to inaccurately reconstructed spans.
In theory, if stack frame push/pop events could be hooked at the hardware level or via emulation, they could be made accurate, but I have not explored this route yet. Still with this limitation, it provides useful data with little effort.
let mut input = new;
let mut tracer = new_options;
let res = read;
tracer.trace.save.unwrap;
tracing other streams or non-rust code
It is possible to trace arbitrary native code by hooking the necessary stream
functions and calling the corresponding functions on your Tracer object. See
trace_factorio and trace_drg
for examples of tracing data streams implemented in C++.