Skip to main content

Module stepping

Module stepping 

Source
Expand description

Source-level stepping over a recorded trace.

A trace is a list of EVM instructions. A source-level debugger needs to know, for each of them, which source line it belongs to and how deep in the call structure it runs, and then answer questions such as “where does the next line start?” in both directions. StepMap computes that once, in one pass over the trace, and every frontend asks it the same questions, so next means the same thing in the terminal and in an editor.

Depth has two parts. The EVM depth changes on CALL and friends; the code address a frame executes is read off the caller’s stack at the call, which is how steps inside another contract map through that contract’s debug info. Inside one contract, Solidity’s internal calls are plain jumps, so the map keeps a virtual stack of the source functions a frame passes through. A jump is a call when the artifact marks it as one (legacy source maps mark calls and returns; ETHDebug’s invoke and return context does the same once a compiler emits it) or when it lands on a parsed function’s entry point, and that holds even when the function is already active, so recursion and mutual recursion count. A marked return pops the frame. Otherwise the function a span lands in decides: one not on the stack is entered, one on the stack is returned to.

Two habits of solc’s output shape the model. Generated helpers (checked arithmetic, require reverts, storage updates) carry the whole-contract span, the same one the dispatcher has, so a step outside every function is read as generated code belonging to the statement that was executing, unless no function follows it in its frame, in which case it is the dispatcher finishing up and the frame’s functions have returned. And a lone instruction attributed to another line between two runs of one line is treated as part of that line, so next does not stop on it.

Everything here is a search over the recording. Nothing re-executes.

Structs§

ContractDebugInfo
One contract’s debug information, prepared for stepping: the ETHDebug metadata, the source text, the functions parsed from it, and the indexes that make per-step lookups constant time.
Frame
One frame of the call structure at a step, innermost first in StepMap::frames.
FunctionId
Identifies a parsed source function across every contract in a StepMap.
LineKey
Identifies a source line across every contract in a StepMap.
ResolvedFunction
A function breakpoint target resolved against the parsed sources.
ResolvedLine
A line breakpoint target resolved against the loaded sources.
SourceListing
Lines of source around a step.
StepLocation
Where one step is in the source, as a frontend shows it.
StepMap
Per-step source locations and frame depths over one trace.

Enums§

JumpMarker
What an artifact says about the jump an instruction makes.

Functions§

address_from_word
The address in the low 20 bytes of a stack word, or None for the zero address or a word that is not hex.
call_target
The code address a call instruction targets, read off its stack.
normalize_address
Lowercases an address and gives it a 0x prefix, so addresses from the command line, from a manifest, and from the stack compare equal.
source_path_matches
Whether a source path from the compiler matches what a user or an editor asked for: the whole path, a trailing part of either (an editor sends absolute paths where the compiler recorded relative ones), or just the file name.