evm v0.1.14 EVM.Debugger.Breakpoint

Breakpoints allow us to break execution of a given contract based on a set of conditions.

Link to this section Summary

Functions

Clears the pc so that this breakpoint doesn’t continue breaking

Describes a breakpoint’s trigger conditions

Disables a given breakpoint

Enables a given breakpoint

Gets a breakpoint by id. This will raise if no such breakpoint is found

Returns all active breakpoints

Initializes the debugger. Must be called prior to getting or checking breakpoints

Returns true if a given breakpoint matches the current execution environment

Adds a global breakpoint condition

Sets the pc to next so that this breakpoint will likely break on the next run

Link to this section Types

Link to this type conditions()
conditions() :: [:address]
Link to this type id()
id() :: integer
Link to this type t()
t() :: %EVM.Debugger.Breakpoint{conditions: keyword(conditions), enabled: boolean, id: id, pc: nil | :start | :next | integer}

Link to this section Functions

Link to this function break_on_next_pc?(breakpoint, pc)
break_on_next_pc?(t, EVM.MachineState.program_counter) :: boolean
Link to this function clear_pc_if_one_time_break(breakpoint_id)
clear_pc_if_one_time_break(id) :: Breakpoint.t

Clears the pc so that this breakpoint doesn’t continue breaking.

Examples

iex> id = EVM.Debugger.Breakpoint.set_breakpoint(%EVM.Debugger.Breakpoint{conditions: [address: <<1::160>>], pc: :next})
iex> EVM.Debugger.Breakpoint.clear_pc_if_one_time_break(id) |> Map.put(:id, nil)
%EVM.Debugger.Breakpoint{conditions: [address: <<1::160>>], pc: nil}

iex> id = EVM.Debugger.Breakpoint.set_breakpoint(%EVM.Debugger.Breakpoint{conditions: [address: <<1::160>>], pc: :start})
iex> EVM.Debugger.Breakpoint.clear_pc_if_one_time_break(id) |> Map.put(:id, nil)
%EVM.Debugger.Breakpoint{conditions: [address: <<1::160>>], pc: nil}

iex> id = EVM.Debugger.Breakpoint.set_breakpoint(%EVM.Debugger.Breakpoint{conditions: [address: <<1::160>>], pc: 5})
iex> EVM.Debugger.Breakpoint.clear_pc_if_one_time_break(id) |> Map.put(:id, nil)
%EVM.Debugger.Breakpoint{conditions: [address: <<1::160>>], pc: 5}
Link to this function describe(breakpoint)
describe(t) :: String.t

Describes a breakpoint’s trigger conditions.

Examples

iex> %EVM.Debugger.Breakpoint{conditions: [address: <<20::160>>], pc: :next} |> EVM.Debugger.Breakpoint.describe
"contract address 0x0000000000000000000000000000000000000014 (next)"

iex> %EVM.Debugger.Breakpoint{conditions: [address: <<20::160>>], pc: :start} |> EVM.Debugger.Breakpoint.describe
"contract address 0x0000000000000000000000000000000000000014 (start)"

iex> %EVM.Debugger.Breakpoint{conditions: [address: <<20::160>>], pc: nil} |> EVM.Debugger.Breakpoint.describe
"contract address 0x0000000000000000000000000000000000000014 (waiting)"

iex> %EVM.Debugger.Breakpoint{conditions: [], pc: nil} |> EVM.Debugger.Breakpoint.describe
"(waiting)"
Link to this function disable_breakpoint(breakpoint_id)
disable_breakpoint(id) :: Breakpoint.t

Disables a given breakpoint.

Examples

iex> id = EVM.Debugger.Breakpoint.set_breakpoint(%EVM.Debugger.Breakpoint{conditions: [address: <<1::160>>]})
iex> EVM.Debugger.Breakpoint.disable_breakpoint(id) |> Map.put(:id, nil)
%EVM.Debugger.Breakpoint{conditions: [address: <<1::160>>], enabled: false}
Link to this function enable_breakpoint(breakpoint_id)
enable_breakpoint(id) :: Breakpoint.t

Enables a given breakpoint.

Examples

iex> id = EVM.Debugger.Breakpoint.set_breakpoint(%EVM.Debugger.Breakpoint{conditions: [address: <<1::160>>], enabled: false})
iex> EVM.Debugger.Breakpoint.enable_breakpoint(id) |> Map.put(:id, nil)
%EVM.Debugger.Breakpoint{conditions: [address: <<1::160>>], enabled: true}
Link to this function get_breakpoint(breakpoint_id)
get_breakpoint(id) :: t

Gets a breakpoint by id. This will raise if no such breakpoint is found.

Examples

iex> id = EVM.Debugger.Breakpoint.set_breakpoint(%EVM.Debugger.Breakpoint{conditions: [address: <<20::160>>]})
iex> EVM.Debugger.Breakpoint.get_breakpoint(id) |> Map.put(:id, nil)
%EVM.Debugger.Breakpoint{conditions: [address: <<20::160>>]}

iex> EVM.Debugger.Breakpoint.get_breakpoint(999)
** (CaseClauseError) no case clause matching: []
Link to this function get_breakpoints()
get_breakpoints() :: [Breakpoint.t]

Returns all active breakpoints.

Examples

iex> id = EVM.Debugger.Breakpoint.set_breakpoint(%EVM.Debugger.Breakpoint{conditions: [address: <<1::160>>]})
iex> breakpoint = EVM.Debugger.Breakpoint.get_breakpoint(id)
iex> breakpoints = EVM.Debugger.Breakpoint.get_breakpoints()
iex> breakpoints |> Enum.count > 0
true
iex> breakpoints |> Enum.member?(breakpoint)
true
Link to this function init()
init() :: :ok

Initializes the debugger. Must be called prior to getting or checking breakpoints.

Link to this function matches?(breakpoint, machine_state, sub_state, exec_env)

Returns true if a given breakpoint matches the current execution environment.

Note: we currently only support address matching.

Examples

iex> breakpoint = %EVM.Debugger.Breakpoint{conditions: [address: <<20::160>>], pc: :next}
iex> machine_state = %EVM.MachineState{}
iex> sub_state = %EVM.SubState{}
iex> exec_env = %EVM.ExecEnv{address: <<20::160>>}
iex> EVM.Debugger.Breakpoint.matches?(breakpoint, machine_state, sub_state, exec_env)
true

iex> breakpoint = %EVM.Debugger.Breakpoint{conditions: [address: <<20::160>>], pc: 999}
iex> machine_state = %EVM.MachineState{}
iex> sub_state = %EVM.SubState{}
iex> exec_env = %EVM.ExecEnv{address: <<20::160>>}
iex> EVM.Debugger.Breakpoint.matches?(breakpoint, machine_state, sub_state, exec_env)
false

iex> breakpoint = %EVM.Debugger.Breakpoint{conditions: [address: <<20::160>>], pc: 999}
iex> machine_state = %EVM.MachineState{program_counter: 999}
iex> sub_state = %EVM.SubState{}
iex> exec_env = %EVM.ExecEnv{address: <<20::160>>}
iex> EVM.Debugger.Breakpoint.matches?(breakpoint, machine_state, sub_state, exec_env)
true

iex> breakpoint = %EVM.Debugger.Breakpoint{conditions: [address: <<20::160>>], pc: nil}
iex> machine_state = %EVM.MachineState{program_counter: 999}
iex> sub_state = %EVM.SubState{}
iex> exec_env = %EVM.ExecEnv{address: <<20::160>>}
iex> EVM.Debugger.Breakpoint.matches?(breakpoint, machine_state, sub_state, exec_env)
false

iex> breakpoint = %EVM.Debugger.Breakpoint{conditions: [address: <<20::160>>], enabled: false, pc: :next}
iex> machine_state = %EVM.MachineState{}
iex> sub_state = %EVM.SubState{}
iex> exec_env = %EVM.ExecEnv{address: <<20::160>>}
iex> EVM.Debugger.Breakpoint.matches?(breakpoint, machine_state, sub_state, exec_env)
false

iex> breakpoint = %EVM.Debugger.Breakpoint{conditions: [address: <<20::160>>], pc: :next}
iex> machine_state = %EVM.MachineState{}
iex> sub_state = %EVM.SubState{}
iex> exec_env = %EVM.ExecEnv{address: <<21::160>>}
iex> EVM.Debugger.Breakpoint.matches?(breakpoint, machine_state, sub_state, exec_env)
false
Link to this function set_breakpoint(breakpoint)
set_breakpoint(t) :: id

Adds a global breakpoint condition.

We can set the following types of breakpoints: …

Examples

iex> id = EVM.Debugger.Breakpoint.set_breakpoint(%EVM.Debugger.Breakpoint{conditions: [address: <<15::160>>]})
iex> EVM.Debugger.Breakpoint.get_breakpoint(id) |> Map.put(:id, nil)
%EVM.Debugger.Breakpoint{conditions: [address: <<15::160>>]}
Link to this function set_next(breakpoint_id)
set_next(id) :: Breakpoint.t

Sets the pc to next so that this breakpoint will likely break on the next run.

Examples

iex> id = EVM.Debugger.Breakpoint.set_breakpoint(%EVM.Debugger.Breakpoint{conditions: [address: <<1::160>>]})
iex> EVM.Debugger.Breakpoint.set_next(id) |> Map.put(:id, nil)
%EVM.Debugger.Breakpoint{conditions: [address: <<1::160>>], pc: :next}