Documentation ¶
Overview ¶
Package evmdebug provides debugging mechanisms for EVM contracts, intercepting opcode-level execution and allowing for inspection of data such as the VM's stack and memory.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type CapturedState ¶
type CapturedState struct {
PC, GasLeft, GasCost uint64
Op vm.OpCode
Context tracing.OpContext // contains memory and stack ;)
ReturnData []byte
Err error
}
CapturedState carries all values passed to the debugger.
N.B. See ownership note in Debugger.State() documentation.
func (*CapturedState) StackBack ¶
func (s *CapturedState) StackBack(n int) uint256.Int
StackBack returns the n'th item in the captured stack; equivalent to vm.Stack.Back.
type Context ¶
type Context struct {
Bytecode, CallData []byte
Results func() (*core.ExecutionResult, error)
}
Context describes the debugging context.
type Debugger ¶
type Debugger struct {
// contains filtered or unexported fields
}
A Debugger intercepts EVM opcode execution to allow inspection of the stack, memory, etc. The value returned by its Tracer() method should be placed inside a vm.Config before execution commences.
Currently only a single frame is supported (i.e. no *CALL methods). This requires execution with a vm.EVMInterpreter.
func NewDebugger ¶
func NewDebugger() *Debugger
NewDebugger constructs a new Debugger.
Execution SHOULD be advanced until Debugger.Done() returns true otherwise resources will be leaked. Best practice is to always call FastForward(), usually in a deferred function.
Debugger.State().Err SHOULD be checked once Debugger.Done() returns true.
NOTE: see the limitations described in the Debugger comments.
func (*Debugger) FastForward ¶
func (d *Debugger) FastForward()
FastForward executes all remaining opcodes, effectively the same as calling Step() in a loop until Done() returns true.
Unlike Step(), calling FastForward() when Done() returns true is acceptable. This allows it to be called in a deferred manner, which is best practice to avoid leaking resources:
dbg := evmdebug.NewDebugger() defer dbg.FastForward()
func (*Debugger) RunTerminalUI ¶
RunTerminalUI starts a UI that controls the Debugger and displays opcodes, memory, stack etc. Because of the current Debugger limitation of a single call frame, only that exact Contract can be displayed. The callData is assumed to be the same as passed to the execution environment.
As the Debugger only has access via a vm.EVMLogger, it can't retrieve the final result. The `results` argument MUST return the returned buffer / error after d.Done() returns true.
func (*Debugger) State ¶
func (d *Debugger) State() *CapturedState
State returns the last-captured state, which will be modified upon each call to Step(). It is expected that State() only be called once, at any time after construction of the Debugger, and its result retained for inspection at each Step(). The CapturedState is, however, only valid after the first call to Step().
Ownership of pointers is retained by the EVM instance that created them; modify with caution!
func (*Debugger) Step ¶
func (d *Debugger) Step()
Step advances the execution by one opcode. Step MUST NOT be called concurrently with any other Debugger methods. The first opcode is only executed upon the first call to Step(), allowing initial state to be inspected beforehand; see Wait() for this purpose.
Step blocks until the opcode execution completes and the next opcode is being blocked.
Step MUST NOT be called after Done() returns true.