trace.rs
Overview
This file provides tracing and debugging utilities for the execution of a virtual machine engine, specifically designed to handle detailed runtime information during the execution of commands. It includes functionality to convert internal engine trace information into a serializable data structure and to output formatted trace logs based on configurable trace bits set on the engine. The file focuses on capturing and formatting information about command execution steps, gas usage, stack state, control states, and exceptions encountered during execution.
Components
Conversion Implementation: From<&EngineTraceInfo<'_>> for EngineTraceInfoData
This impl block implements a conversion from a borrowed reference of EngineTraceInfo to an owned EngineTraceInfoData struct. This conversion extracts and formats relevant fields from the raw EngineTraceInfo for easier inspection or serialization.
Details:
Input:
&EngineTraceInfo— a reference to the trace info produced by the execution engine.Output:
EngineTraceInfoData— a structured representation of the trace information with formatted strings and extracted values.
Extracted Fields:
info_type — Debug representation of the trace info type (
Start,Exception, etc.).step— The current execution step number.cmd_str— The string representation of the command being executed.stack— A vector of strings representing the stack contents, converted fromStackItemto human-readable strings.gas_used— Gas used so far, formatted as a string.gas_cmd— Gas cost for the current command, formatted as a string.cmd_code_rem_bits— Remaining bits in the current command code.cmd_code_hex— Hexadecimal string of the command code.cmd_code_cell_hash — Hexadecimal string of the command code's cell hash.
cmd_code_offset — Offset position within the command code.
Usage Example:
let trace_info_data: EngineTraceInfoData = (&engine_trace_info).into();
Function: simple_trace_callback
A callback function designed for logging trace information from the virtual machine engine during execution. It selectively logs messages depending on the trace info type and the trace bits enabled in the engine.
Parameters:
engine: &Engine— Reference to the virtual machine engine instance.info: &EngineTraceInfo— Reference to the current trace information.
Behavior:
Logs command strings on
Dumpinfo type.On
Startinfo type, conditionally logs control states, stack contents, and gas usage if corresponding trace bits are enabled.On
Exception, logs bad code messages, stack contents, control states, and gas usage.For other command-related trace info, logs command strings, stack, control states, and gas usage based on enabled trace bits.
Trace Bits Checked:
Engine::TRACE_CTRLS— Controls state dumping.Engine::TRACE_STACK— Stack state dumping.Engine::TRACE_GAS— Gas usage logging.Engine::TRACE_CODE— Command code logging.
Usage Example:
engine.set_trace_callback(simple_trace_callback);
Function: dump_stack_result
Converts the current stack state into a concise string representation for logging or debugging purposes.
Parameters:
stack: &Stack— Reference to the stack to be dumped.
Return:
String— A formatted string representing the stack contents.
Details:
Iterates over each
StackItemin the stack.Converts each
StackItemvariant to a short string:None=>"N"Integer=> decimal string if bitsize ≤ 230, else hexadecimal prefixed with0x, or fallback to a generic"I<bit-size>".Cell=>"C<bit_length>-<ref_count>".Continuation=>"T<size_in_bytes>".Builder=>"B<bit_length>-<num_references>".Slice=>"S<remaining_bits>-<remaining_references>".Tuple=>"[]"if empty, or"[@<length>]"if non-empty.
Implementation Notes:
Contains commented-out code for detecting repeated stack states to potentially optimize output by skipping unchanged items.
Designed for human-readable, compact stack snapshots useful during trace logging.
Usage Example:
let stack_str = dump_stack_result(&engine.current_stack());
println!("Stack: {}", stack_str);
Interaction with Other Components
Uses
EngineTraceInfoandEngineTraceInfoTypefrom thetvm_vm::executormodule to extract detailed runtime execution info.Interacts with the
Enginefrom the same executor module to query enabled trace bits and dump states.Utilizes the
StackandStackItemtypes fromtvm_vm::stackto interpret and format the stack contents.Converts and provides data for
EngineTraceInfoData(from the parent module) which may be used elsewhere for structured trace data handling or persistence.The
simple_trace_callbackfunction is designed to be set as a callback in the engine's tracing system, integrating tightly into the virtual machine runtime for debug output.
Implementation Details and Algorithms
Tracing Control via Bit Flags: Uses bit flags on the
Engineinstance (e.g.,TRACE_CTRLS,TRACE_STACK) to conditionally output different categories of trace information, allowing fine-grained control over logged data.Stack Dump Formatting: The stack dumper uses pattern matching on the enum variants of stack items to produce compact string representations. It accommodates large integers by switching to hexadecimal format and provides concise descriptions for complex types like cells, slices, and tuples.
TraceInfo Conversion: The conversion implementation extracts low-level binary details (like remaining bits and cell hashes) from the command code to enrich the trace data with both human-readable and technical identifiers.
Logging Macros: Uses the
tracingcrate macros (info!,trace!) targeted at specific logging targets such as"tvm"and"tvm_op"for categorizing output.
Diagram: Functional Flow of Trace Logging
flowchart TD
Engine -->|executes commands| EngineTraceInfo
EngineTraceInfo -->|converted to| EngineTraceInfoData
Engine -->|provides trace bits| simple_trace_callback
EngineTraceInfo -->|passes info| simple_trace_callback
simple_trace_callback -->|logs command string| Tracing[tracing::info! / trace!]
simple_trace_callback -->|calls| dump_stack_result
dump_stack_result -->|returns formatted stack string| simple_trace_callback
simple_trace_callback -->|logs stack info| Tracing
simple_trace_callback -->|logs control states| Tracing
simple_trace_callback -->|logs gas usage| Tracing
The diagram shows how the Engine produces EngineTraceInfo during execution, which is converted and passed to the simple_trace_callback. The callback checks engine trace bits to decide which aspects (command, stack, controls, gas) to log, using dump_stack_result to format the stack.
References
See
Enginefor trace bit management and control state dumping.See
EngineTraceInfofor the structure of execution trace data.See
StackandStackItemfor stack data structures used in trace formatting.EngineTraceInfoDatais defined in the parent module and is used as a serializable representation of trace info.