The Erlang interpreter provides mechanisms for breakpoints and
stepwise execution of code. It is mainly intended to be used by
the Debugger, see Debugger User's Guide and
debugger(3)
.
From the shell, it is possible to:
By attaching to a process executing interpreted code, it
is possible to examine variable bindings and order stepwise execution.
This is done by sending and receiving information to/from the process
via a third process, called the meta process. It is possible, but not
recommended, to implement your own attached process. See int.erl
for available functions and dbg_ui_trace.erl
for possible
messages.
Breakpoints are specified on a line basis. When a process executing code in an interpreted module reaches a breakpoint, it will stop. This means that that a breakpoint must be set at an executable line, i.e. a line of code containing an executable expression.
A breakpoint have a status, a trigger action and may have a condition
associated with it. The status is either active or
inactive. An inactive breakpoint is ignored.
When a breakpoint is reached, the trigger action specifies if
the breakpoint should continue to be active (enable), if it
should become inactive (disable), or if it should be
removed (delete). A condition is a tuple {Module,Name}
.
When the breakpoint is reached, Module:Name(Bindings)
is
called. If this evaluates to true
, execution will stop. If
this evaluates to false
, the breakpoint is ignored.
Bindings
contains the current variable bindings, use
get_binding
to retrieve the value for a given variable.
By default, a breakpoint is active, has trigger action enable and has no condition associated with it. For more detailed information about breakpoints, refer to Debugger User's Guide.
i(AbsModule) -> {module,Module} | error
ni(AbsModule) -> {module,Module} | error
Types:
AbsModule = Module | File | [Module | File]
Module = atom()
File = string()
Options = term()
Interprets the specified module. i/1,2
interprets
the module only at the current node. ni/1,2
interprets
the module at all known nodes.
A module may be given by its module name (atom) or by its file
name. If given by its module name, the object code
Module.beam
is searched for in the current path. The source
code Module.erl
is searched for first in the same directory
as the object code, then in a src
directory next to it.
If given by its file name, the file name may include a path and
the .erl
extension may be omitted. The object code
Module.beam
is searched for first in the same directory as
the source code, then in an ebin
directory next to it, and
then in the current path.
The interpreter needs both the source code and the object code,
and the object code must include debug information.
That is, only modules compiled with the option |
n(AbsModule) -> ok
nn(AbsModule) -> ok
Types:
AbsModule = Module | File | [Module | File]
Module = atom()
File = string()
Stops interpreting the specified module. n/1
stops
interpreting the node only at the current node. nn/1
stops
interpreting the module at all known nodes.
As for i/1
and ni/1
, a module may be given by
either its module name or its file name.
Types:
Module = atom()
Returns a list with all interpreted modules.
file(Module) -> File | {error,not_loaded}
Types:
Module = atom()
File = string()
Returns the source code file name File
for an interpreted
module Module
.
interpretable(AbsModule) -> true | {error,Reason}
Types:
AbsModule = Module | File
Module = atom()
File = string()
Reason = no_src | no_beam | no_debug_info | badarg
Checks if a module is possible to interpret. The module can be
given by its module name Module
or its file name
File
.
The function returns true
if both source code and object
code for the module is found, and the module has been compiled
with the option debug_info
set.
The function returns {error,Reason}
where Reason
is
no_src
if no source code is found, no_beam
if no
object code is found, no_debug_info
if the module has not
been compiled with the option debug_info
set, or
badarg
if AbsModule
does not exist.
auto_attach() -> false | {Flags,Function}
auto_attach(false)
auto_attach(Flags, Function)
Types:
Flags = [init | break | exit]
Function = {Module,Name,Args}
Module = Name = atom()
Args = [term()]
Get and set when and how to automatically attach to a process
executing code in interpreted modules. false
means never
attach, this is the default. Otherwise automatic attach is
defined by a list of flags and a function. The following flags
may be specified:
init
- attach when a process for the very first time
calls an interpreted function.
break
- attach whenever a process reaches a
breakpoint.
exit
- attach when a process terminates.
When the specified event occurs, the function Function
will be called as:
spawn(Module, Name, [Pid | Args])
The resulting process can attach to, i.e. send commands to and receive messages from, the interpreted process, see above.
stack_trace() -> Flag
stack_trace(Flag)
Types:
Flag = all | no_tail | false
Get and set how to save call frames in the stack. This makes it possible to inspect the call chain of a process.
all
- save all call frames. This is the default.
no_tail
- save all call frames, except for tail
recursive calls. This option consumes less memory and may be
necessary to use for processes with long lifetimes and many
tail recursive calls.
false
- do not save call frames.
break(Module, Line) -> ok | {error,break_exists}
Types:
Module = atom()
Line = integer()
Creates a breakpoint at Line
in Module
.
delete_break(Module, Line) -> ok
Types:
Module = atom()
Line = integer()
Deletes the breakpoint located at Line
in Module
.
break_in(Module, Name, Arity) -> ok
| {error,function_not_found}
Types:
Module = Name = atom()
Function = atom()
Arity = integer()
Create a breakpoint at the first line of every clause of
the Module:Function/Arity
function.
del_break_in(Module, Name, Arity) -> ok
| {error,function_not_found}
Types:
Module = Name = atom()
Arity = integer()
Delete the breakpoints at the first line of every clause of
the Module:Function/Arity
function.
no_break() -> ok
no_break(Module) -> ok
Deletes all breakpoints, or all breakpoints in Module
.
disable_break(Module, Line) -> ok
Types:
Module = atom()
Line = integer()
Makes the breakpoint at Line
in Module
inactive.
enable_break(Module, Line) -> ok
Types:
Module = atom()
Line = integer()
Makes the breakpoint at Line
in Module
active.
action_at_break(Module, Line, Action) -> ok
Types:
Module = atom()
Line = integer()
Action = enable | disable | delete
Set the trigger action of the breakpoint at Line
in
Module
to Action
.
test_at_break(Module, Line, Function) -> ok
Types:
Module = atom()
Line = integer()
Function = {Module,Name}
Module = Name = atom()
Set the condition of the breakpoint at Line
in
Module
to Function
.
get_binding(Var, Bindings) -> {value,Value} | unbound
Types:
Var = atom()
Bindings = term()
Value = term()
Retrieve the binding of Variable
. This function is
intended to be used by a breakpoint condition function.
all_breaks() -> [Break]
all_breaks(Module) -> [Break]
Types:
Break = {Point,Options}
Point = {Module,Line}
Module = atom()
Line = int()
Options = [Status,Trigger,null,Cond|]
Status = active | inactive
Trigger = enable | disable | delete
Cond = null | Function
Function = {Module,Name}
Name = atom()
Gets all breakpoints, or all breakpoints in Module
.
Types:
Snapshot = {Pid, Function, Status, Info}
Pid = pid()
Function = {Module,Name,Args}
Module = Name = atom()
Args = [term()]
Status = idle | running | waiting | break | exit
| no_conn
Info = {} | {Module,Line} | ExitReason
Line = integer()
ExitReason = term()
Gets information about all processes executing interpreted code.
Pid
- process identifier.
Function
- first interpreted function called by
the process.
Status
- current status of the process.
Info
- additional information.
Status
is one of:
idle
- the process is no longer executing interpreted
code. Info={}
.
running
- the process is running. Info={}
.
waiting
- the process is waiting at a receive
.
Info={}
.
break
- process execution has been stopped, normally
at a breakpoint. Info={Module,Line}
.
exit
- the process has terminated.
Info=ExitReason
.
no_conn
- the connection is down to the node where
the process is running. Info={}
.
Clears information about processes executing interpreted code by removing all information about terminated processes.
continue(Pid) -> ok | {error,not_interpreted}
continue(X,Y,Z) -> ok | {error,not_interpreted}
Types:
Pid = pid()
X = Y = Z = integer()
Resume process execution for Pid
, or for
c:pid(X,Y,Z)
.