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 contract given with an address describes any frame that executes
it; when only one contract is given, 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 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.
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.
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.
Trait Implementations§
impl Eq for StepMap
impl StructuralPartialEq for StepMap
Auto Trait Implementations§
impl Freeze for StepMap
impl RefUnwindSafe for StepMap
impl Send for StepMap
impl Sync for StepMap
impl Unpin for StepMap
impl UnsafeUnpin for StepMap
impl UnwindSafe for StepMap
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.Source§impl<T> FmtForward for T
impl<T> FmtForward for T
Source§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self to use its Binary implementation when Debug-formatted.Source§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self to use its Display implementation when
Debug-formatted.Source§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self to use its LowerExp implementation when
Debug-formatted.Source§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self to use its LowerHex implementation when
Debug-formatted.Source§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self to use its Octal implementation when Debug-formatted.Source§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self to use its Pointer implementation when
Debug-formatted.Source§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self to use its UpperExp implementation when
Debug-formatted.Source§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self to use its UpperHex implementation when
Debug-formatted.Source§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
Source§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
Source§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read moreSource§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read moreSource§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
Source§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
Source§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
self, then passes self.as_ref() into the pipe function.Source§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
self, then passes self.as_mut() into the pipe
function.Source§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self, then passes self.deref() into the pipe function.Source§impl<T> Tap for T
impl<T> Tap for T
Source§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B> of a value. Read moreSource§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B> of a value. Read moreSource§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R> view of a value. Read moreSource§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R> view of a value. Read moreSource§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target of a value. Read moreSource§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target of a value. Read moreSource§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap() only in debug builds, and is erased in release builds.Source§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut() only in debug builds, and is erased in release
builds.Source§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.tap_borrow() only in debug builds, and is erased in release
builds.Source§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut() only in debug builds, and is erased in release
builds.Source§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.tap_ref() only in debug builds, and is erased in release
builds.Source§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut() only in debug builds, and is erased in release
builds.Source§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref() only in debug builds, and is erased in release
builds.