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§
- Contract
Debug Info - 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. - Function
Id - Identifies a parsed source function across every contract in a
StepMap. - LineKey
- Identifies a source line across every contract in a
StepMap. - Resolved
Function - A function breakpoint target resolved against the parsed sources.
- Resolved
Line - A line breakpoint target resolved against the loaded sources.
- Source
Listing - Lines of source around a step.
- Step
Location - Where one step is in the source, as a frontend shows it.
- StepMap
- Per-step source locations and frame depths over one trace.
Enums§
- Jump
Marker - 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
Nonefor 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
0xprefix, 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.