pub struct StepMap { /* private fields */ }Expand description
Per-step source locations and frame depths over one trace.
Implementations§
Source§impl StepMap
impl StepMap
Sourcepub fn new(trace: &TransactionTrace, contracts: Vec<ContractDebugInfo>) -> Self
pub fn new(trace: &TransactionTrace, contracts: Vec<ContractDebugInfo>) -> Self
Maps every step of trace through the contracts’ debug info.
The root frame executes the transaction’s target, or the created contract for a
deployment; a trace with several top-level calls has a root frame for each. A
contract given with an address describes any frame that executes it; when only one
contract is given and the trace has one root, it also describes the root whatever
address it names, so a single --ethdebug-dir applies to the transaction it was
passed for.
Sourcepub fn for_debug_diff(
trace: &TransactionTrace,
contracts: Vec<ContractDebugInfo>,
) -> Self
pub fn for_debug_diff( trace: &TransactionTrace, contracts: Vec<ContractDebugInfo>, ) -> Self
Keeps single-instruction source stops when testing compiler debug information.
Interactive stepping smooths brief line excursions. A compiler regression test
must observe them: an optimized getter can map its entire body to one SLOAD.
pub fn contracts(&self) -> &[ContractDebugInfo]
Sourcepub fn contract_at_step(&self, step: usize) -> Option<&ContractDebugInfo>
pub fn contract_at_step(&self, step: usize) -> Option<&ContractDebugInfo>
The contract whose code the step executes, when its debug info was loaded.
pub fn step_count(&self) -> usize
Sourcepub fn has_source(&self) -> bool
pub fn has_source(&self) -> bool
Whether any step maps to a source line at all.
Sourcepub fn line_key(&self, step: usize) -> Option<LineKey>
pub fn line_key(&self, step: usize) -> Option<LineKey>
The line a step counts as for stepping and breakpoints.
pub fn frame_depth(&self, step: usize) -> Option<u32>
pub fn is_line_start(&self, step: usize) -> bool
pub fn is_frame_entry(&self, step: usize) -> bool
Sourcepub fn function_id(&self, step: usize) -> Option<FunctionId>
pub fn function_id(&self, step: usize) -> Option<FunctionId>
The function the step runs in, including generated code for one of its statements.
Sourcepub fn executing_address(&self, step: usize) -> Option<&str>
pub fn executing_address(&self, step: usize) -> Option<&str>
The address whose code the step executes, when it could be determined.
Sourcepub fn storage_address(&self, step: usize) -> Option<&str>
pub fn storage_address(&self, step: usize) -> Option<&str>
The account whose storage the step reads and writes: the executing address, or
the caller’s under a DELEGATECALL.
Sourcepub fn storage_context_index(&self, step: usize) -> Option<usize>
pub fn storage_context_index(&self, step: usize) -> Option<usize>
An opaque identifier for that account, for indexing storage by context.
Sourcepub fn reverted_spans(&self) -> &[(usize, usize)]
pub fn reverted_spans(&self) -> &[(usize, usize)]
Every EVM frame that reverted, as the step it was entered at and the step it reverted on. A frame’s writes, and its callees’, do not survive it.
Sourcepub fn argument_layout(&self, contract: usize) -> Option<ArgumentLayout>
pub fn argument_layout(&self, contract: usize) -> Option<ArgumentLayout>
What this trace proved about where a contract’s compiler leaves function
parameters on the stack. None when the trace carried no frame that could show
it, or when a frame contradicted it.
Sourcepub fn locals_at(&self, step: usize) -> LocalsStatus<'_>
pub fn locals_at(&self, step: usize) -> LocalsStatus<'_>
The variables of the function executing at step, inferred from the stack, or why
none can be.
Inference follows solc’s legacy code generator, which keeps every variable at a
fixed stack slot: the parameters below the entry height, and each return parameter
and local at the slot the frame had when its declaration executed. A contract known
to come from the via-IR pipeline, or whose trace shows that pipeline’s calling
convention, is not inferred. The result is a reading of the stack, not of compiler
variable locations, and a frontend should say so; see INFERRED_LOCALS_WARNING.
Sourcepub fn calldata_at<'a>(
&self,
trace: &'a TransactionTrace,
step: usize,
) -> &'a str
pub fn calldata_at<'a>( &self, trace: &'a TransactionTrace, step: usize, ) -> &'a str
The calldata of the frame executing step; empty in a nested frame whose call the
backend did not record.
Sourcepub fn local_path(
&self,
trace: &TransactionTrace,
step: usize,
words: Option<&StorageWords<'_>>,
path: &str,
) -> Option<Result<DebugVariable, String>>
pub fn local_path( &self, trace: &TransactionTrace, step: usize, words: Option<&StorageWords<'_>>, path: &str, ) -> Option<Result<DebugVariable, String>>
The value of path at step: a local variable in scope, or a member, element,
mapping entry, or length reached from one, such as item.tags[1] or
stored.owners[0xabc]. None when no local in scope has the path’s first name,
so the caller can look it up as a state variable instead; Some(Err) says why a
local’s path could not be followed.
Sourcepub fn local_condition_value(
&self,
trace: &TransactionTrace,
step: usize,
words: Option<&StorageWords<'_>>,
path: &str,
) -> Option<Result<Value, String>>
pub fn local_condition_value( &self, trace: &TransactionTrace, step: usize, words: Option<&StorageWords<'_>>, path: &str, ) -> Option<Result<Value, String>>
The value of path as a breakpoint condition compares it; see
StepMap::local_path.
Sourcepub fn inferred_variables(
&self,
trace: &TransactionTrace,
step: usize,
words: Option<&StorageWords<'_>>,
) -> Vec<DebugVariable>
pub fn inferred_variables( &self, trace: &TransactionTrace, step: usize, words: Option<&StorageWords<'_>>, ) -> Vec<DebugVariable>
The inferred variables at step, read off its stack and decoded by type: a value
type from its word, a reference type through the memory, storage, or calldata its
word points into. words are the storage words known at the step, for storage
pointers; without them a storage pointer is shown as its slot.
A variable whose slot is not known, or lies above the stack, is reported as unavailable rather than as a wrong word.
Sourcepub fn frame_arguments(
&self,
frame: &Frame,
state: FrameState<'_>,
) -> Vec<FrameArgument>
pub fn frame_arguments( &self, frame: &Frame, state: FrameState<'_>, ) -> Vec<FrameArgument>
The arguments frame was entered with, given the stack at its entry step.
Only a frame entered at its function’s entry point carries them, and only once
this trace has shown that the compiler leaves them there: which word is which
parameter depends on the code generator, and a legacy public function is entered
through a dispatcher wrapper that has not decoded them yet. See
StepMap::argument_layout.
pub fn location(&self, step: usize) -> Option<StepLocation>
Sourcepub fn next_source(&self, step: usize) -> Option<usize>
pub fn next_source(&self, step: usize) -> Option<usize>
The step where the next source line begins at this frame or a caller’s, stepping
over calls. None when the recording ends first.
Steps the compiler attached no source to, such as generated helper code, never stop a line step at the same depth: they belong to whatever line is executing.
From code outside every function, such as the dispatcher, this enters the function it jumps to instead of stepping over it: there is no caller to come back to, and a user at the first step wants to reach the first line, not the last.
Sourcepub fn step_into(&self, step: usize) -> Option<usize>
pub fn step_into(&self, step: usize) -> Option<usize>
The step where the next source line begins anywhere, entering calls. A call into code without source stops at its first step, so the user sees where they are.
Sourcepub fn finish(&self, step: usize) -> Option<usize>
pub fn finish(&self, step: usize) -> Option<usize>
The step where the current frame has returned to its caller. A root frame returns where the next top-level call starts.
Sourcepub fn previous_source(&self, step: usize) -> Option<usize>
pub fn previous_source(&self, step: usize) -> Option<usize>
The start of the previous source line at this frame or a caller’s, skipping the
calls it made. From the middle of a line this is the start of that line. From code
outside every function it enters the function that just returned, the mirror of
StepMap::next_source.
Sourcepub fn reverse_step_into(&self, step: usize) -> Option<usize>
pub fn reverse_step_into(&self, step: usize) -> Option<usize>
The start of the previous source line anywhere, entering the calls it made.
Sourcepub fn reverse_finish(&self, step: usize) -> Option<usize>
pub fn reverse_finish(&self, step: usize) -> Option<usize>
The step in the caller that entered the current frame. A root frame was entered where its top-level call starts.
Sourcepub fn resolve_line(
&self,
file: Option<&str>,
line: u64,
) -> Result<Vec<ResolvedLine>, String>
pub fn resolve_line( &self, file: Option<&str>, line: u64, ) -> Result<Vec<ResolvedLine>, String>
Resolves a file:line breakpoint against every loaded source. With no file, the
line must be unambiguous across the loaded sources.
Sourcepub fn resolve_function(
&self,
name: &str,
) -> Result<Vec<ResolvedFunction>, String>
pub fn resolve_function( &self, name: &str, ) -> Result<Vec<ResolvedFunction>, String>
Resolves a function breakpoint by name, optionally qualified as
Contract.function.
Sourcepub fn frames(&self, step: usize) -> Vec<Frame>
pub fn frames(&self, step: usize) -> Vec<Frame>
The call structure at step, innermost frame first.
Sourcepub fn source_listing(&self, step: usize, radius: u64) -> Option<SourceListing>
pub fn source_listing(&self, step: usize, radius: u64) -> Option<SourceListing>
The source around step: radius lines on each side of its line.