<?xml version="1.0" encoding="latin1" ?>
<!DOCTYPE erlref SYSTEM "erlref.dtd">
<erlref>
<header>
<copyright>
<year>1996</year><year>2013</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
The contents of this file are subject to the Erlang Public License,
Version 1.1, (the "License"); you may not use this file except in
compliance with the License. You should have received a copy of the
Erlang Public License along with this software. If not, it can be
retrieved online at http://www.erlang.org/.
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
the License for the specific language governing rights and limitations
under the License.
</legalnotice>
<title>dbg</title>
<prepared>Patrik Nyblom (Claes Wikstrom)</prepared>
<responsible></responsible>
<docno>1</docno>
<approved>ETX/B/SFP (Kenneth Lundin)</approved>
<checked></checked>
<date>96-11-07</date>
<rev>A</rev>
<file>dbg.sgml</file>
</header>
<module>dbg</module>
<modulesummary>The Text Based Trace Facility</modulesummary>
<description>
<p>This module implements a text based interface to the
<c>trace/3</c> and the <c>trace_pattern/2</c> BIFs. It makes it
possible to trace functions, processes and messages on text based
terminals. It can be used instead of, or as complement to, the
<c>pman</c> module.
</p>
<p>For some examples of how to use <c>dbg</c> from the Erlang
shell, see the <seealso marker="#simple_example">simple example</seealso> section.
</p>
<p>The utilities are also suitable to use in system testing on
large systems, where other tools have too much impact on the
system performance. Some primitive support for sequential tracing
is also included, see the <seealso marker="#advanced">advanced topics</seealso> section.
</p>
</description>
<funcs>
<func>
<name>fun2ms(LiteralFun) -> MatchSpec</name>
<fsummary>Pseudo function that transforms fun syntax to match_spec.</fsummary>
<type>
<v>LiteralFun = fun() literal</v>
<v>MatchSpec = term()</v>
</type>
<desc>
<p>Pseudo function that by means of a <c>parse_transform</c>
translates the <em>literal</em><c>fun()</c> typed as parameter in
the function call to a match specification as described in
the <c>match_spec</c> manual of <c>ERTS</c> users guide.
(with literal I mean that the <c>fun()</c> needs to
textually be written as the parameter of the function, it
cannot be held in a variable which in turn is passed to the
function). </p>
<p>The parse transform is implemented in the module
<c>ms_transform</c> and the source <em>must</em> include the
file <c>ms_transform.hrl</c> in STDLIB for this
pseudo function to work. Failing to include the hrl file in
the source will result in a runtime error, not a compile
time ditto. The include file is easiest included by adding
the line
<c>-include_lib("stdlib/include/ms_transform.hrl").</c> to
the source file.</p>
<p>The <c>fun()</c> is very restricted, it can take only a
single parameter (the parameter list to match), a sole variable or a
list. It needs to use the <c>is_</c>XXX guard tests and one
cannot use language constructs that have no representation
in a match_spec (like <c>if</c>, <c>case</c>,
<c>receive</c> etc). The return value from the fun will be
the return value of the resulting match_spec.</p>
<p>Example:</p>
<pre>
1> <input>dbg:fun2ms(fun([M,N]) when N > 3 -> return_trace() end).</input>
[{['$1','$2'],[{'>','$2',3}],[{return_trace}]}]</pre>
<p>Variables from the environment can be imported, so that this
works:</p>
<pre>
2> <input>X=3.</input>
3
3> <input>dbg:fun2ms(fun([M,N]) when N > X -> return_trace() end).</input>
[{['$1','$2'],[{'>','$2',{const,3}}],[{return_trace}]}]</pre>
<p>The imported variables will be replaced by match_spec
<c>const</c> expressions, which is consistent with the
static scoping for Erlang <c>fun()</c>s. Local or global
function calls can not be in the guard or body of the fun
however. Calls to builtin match_spec functions of course is
allowed:</p>
<pre>
4> <input>dbg:fun2ms(fun([M,N]) when N > X, is_atomm(M) -> return_trace() end).</input>
Error: fun containing local erlang function calls ('is_atomm' called in guard)\
cannot be translated into match_spec
{error,transform_error}
5> <input>dbg:fun2ms(fun([M,N]) when N > X, is_atom(M) -> return_trace() end).</input>
[{['$1','$2'],[{'>','$2',{const,3}},{is_atom,'$1'}],[{return_trace}]}]</pre>
<p>As you can see by the example, the function can be called from
the shell too. The <c>fun()</c> needs to be literally in the
call when used from the shell as well. Other means than the
parse_transform are used in the shell case, but more or less
the same restrictions apply (the exception being records,
as they are not handled by the shell).</p>
<warning>
<p>If the parse_transform is not applied to a module which calls this
pseudo function, the call will fail in runtime (with a
<c>badarg</c>). The module <c>dbg</c> actually exports a
function with this name, but it should never really be called
except for when using the function in the shell. If the
<c>parse_transform</c> is properly applied by including
the <c>ms_transform.hrl</c> header file, compiled code
will never call the function, but the function call is
replaced by a literal match_spec.</p>
</warning>
<p>More information is provided by the <c>ms_transform</c>
manual page in STDLIB.</p>
</desc>
</func>
<func>
<name>h() -> ok </name>
<fsummary>Give a list of available help items on standard output.</fsummary>
<desc>
<p>Gives a list of items for brief online help.</p>
</desc>
</func>
<func>
<name>h(Item) -> ok </name>
<fsummary>Give brief help for an item.</fsummary>
<type>
<v>Item = atom()</v>
</type>
<desc>
<p>Gives a brief help text for functions in the dbg module. The
available items can be listed with <c>dbg:h/0</c></p>
</desc>
</func>
<func>
<name>p(Item) -> {ok, MatchDesc} | {error, term()} </name>
<fsummary>Trace messages to and from Item.</fsummary>
<desc>
<p>Equivalent to <c>p(Item, [m])</c>.</p>
</desc>
</func>
<func>
<name>p(Item, Flags) -> {ok, MatchDesc} | {error, term()}</name>
<fsummary>Trace Item according to Flags.</fsummary>
<type>
<v>MatchDesc = [MatchNum]</v>
<v>MatchNum = {matched, node(), integer()} | {matched, node(), 0, RPCError}</v>
<v>RPCError = term()</v>
</type>
<desc>
<p>Traces <c>Item</c> in accordance to the value specified
by <c>Flags</c>. The variation of <c>Item</c> is listed below:</p>
<list type="bulleted">
<item>If the <c>Item</c> is a <c>pid()</c>, the corresponding
process is traced. The process may be a remote process
(on another Erlang node). The node must be in the list of
traced nodes (<seealso marker="#n">see</seealso><c>n/1</c> and <c>tracer/0/2/3</c>).</item>
<item>If the <c>Item</c> is the atom <c>all</c>, all processes in the
system as well as all processes created hereafter are
to be traced. This also affects all nodes added with the
<c>n/1</c> or <c>tracer/0/2/3</c> function.</item>
<item>If the <c>Item</c> is the atom <c>new</c>, no currently existing
processes are affected, but every process created after the
call is.This also affects all nodes added with the
<c>n/1</c> or <c>tracer/0/2/3</c> function.</item>
<item>If the <c>Item</c> is the atom <c>existing</c>, all
existing processes are traced, but new processes will not
be affected.This also affects all nodes added with the
<c>n/1</c> or <c>tracer/0/2/3</c> function.</item>
<item>If the <c>Item</c> is an atom other than <c>all</c>,
<c>new</c> or <c>existing</c>, the process with the
corresponding registered name is traced.The process may be a
remote process (on another Erlang node). The node must be added
with the <c>n/1</c> or <c>tracer/0/2/3</c> function.</item>
<item>If the <c>Item</c> is an integer, the process <c><![CDATA[<0.Item.0>]]></c> is
traced.</item>
<item>If the <c>Item</c> is a tuple <c>{X, Y, Z}</c>, the
process <c><![CDATA[<X.Y.Z>]]></c> is
traced. </item>
<item>If the <c>Item</c> is a string <![CDATA["<X.Y.Z>"]]>
as returned from <c>pid_to_list/1</c>, the process
<c><![CDATA[<X.Y.Z>]]></c> is traced. </item>
</list>
<p><c>Flags</c> can be a single atom,
or a list of flags. The available flags are:
</p>
<taglist>
<tag><c>s (send)</c></tag>
<item>
<p>Traces the messages the process sends.</p>
</item>
<tag><c>r (receive)</c></tag>
<item>
<p>Traces the messages the process receives.</p>
</item>
<tag><c>m (messages)</c></tag>
<item>
<p>Traces the messages the process receives and sends.</p>
</item>
<tag><c>c (call)</c></tag>
<item>
<p>Traces global function calls for the process
according to the trace patterns set in the system (see tp/2).</p>
</item>
<tag><c>p (procs)</c></tag>
<item>
<p>Traces process related events to the process.</p>
</item>
<tag><c>sos (set on spawn)</c></tag>
<item>
<p>Lets all processes created by the traced
process inherit the trace flags
of the traced process.</p>
</item>
<tag><c>sol (set on link)</c></tag>
<item>
<p>Lets another process, <c>P2</c>, inherit the
trace flags of the traced
process whenever the traced process links to <c>P2</c>.</p>
</item>
<tag><c>sofs (set on first spawn)</c></tag>
<item>
<p>This is the same as <c>sos</c>, but only
for the first process spawned by the traced process.</p>
</item>
<tag><c>sofl (set on first link)</c></tag>
<item>
<p>This is the same as <c>sol</c>, but only for
the first call to
<c>link/1</c> by the traced process.</p>
</item>
<tag><c>all</c></tag>
<item>
<p>Sets all flags except <c>silent</c>.</p>
</item>
<tag><c>clear</c></tag>
<item>
<p>Clears all flags.
</p>
</item>
</taglist>
<p>The list can also include any of the flags allowed in
<c>erlang:trace/3</c></p>
<p>The function returns either an error tuple or a tuple
<c>{ok, List}</c>. The <c>List</c> consists of
specifications of how many processes that matched (in the
case of a pure pid() exactly 1). The specification of
matched processes is <c>{matched, Node, N}</c>. If the
remote processor call,<c>rpc</c>, to a remote node fails,
the <c>rpc</c> error message is delivered as a fourth
argument and the number of matched processes are 0. Note
that the result {ok, List} may contain a list where
<c>rpc</c> calls to one, several or even all nodes failed.</p>
</desc>
</func>
<func>
<name>c(Mod, Fun, Args)</name>
<fsummary>Evaluate <c>apply(M,F,Args)</c>with <c>all</c>trace flags set.</fsummary>
<desc>
<p>Equivalent to <c>c(Mod, Fun, Args, all)</c>.</p>
</desc>
</func>
<func>
<name>c(Mod, Fun, Args, Flags)</name>
<fsummary>Evaluate <c>apply(M,F,Args)</c>with <c>Flags</c>trace flags set.</fsummary>
<desc>
<p>Evaluates the expression <c>apply(Mod, Fun, Args)</c> with the trace
flags in <c>Flags</c> set. This is a convenient way to trace processes
from the Erlang shell.</p>
</desc>
</func>
<func>
<name>i() -> ok</name>
<fsummary>Display information about all traced processes.</fsummary>
<desc>
<p>Displays information about all traced processes.</p>
</desc>
</func>
<func>
<name>tp(Module,MatchSpec)</name>
<fsummary>Set pattern for traced global function calls</fsummary>
<desc>
<p>Same as tp({Module, '_', '_'}, MatchSpec)</p>
</desc>
</func>
<func>
<name>tp(Module,Function,MatchSpec)</name>
<fsummary>Set pattern for traced global function calls</fsummary>
<desc>
<p>Same as tp({Module, Function, '_'}, MatchSpec)</p>
</desc>
</func>
<func>
<name>tp(Module, Function, Arity, MatchSpec)</name>
<fsummary>Set pattern for traced global function calls</fsummary>
<desc>
<p>Same as tp({Module, Function, Arity}, MatchSpec)</p>
</desc>
</func>
<func>
<name>tp({Module, Function, Arity}, MatchSpec) -> {ok, MatchDesc} | {error, term()}</name>
<fsummary>Set pattern for traced global function calls</fsummary>
<type>
<v>Module = atom() | '_'</v>
<v>Function = atom() | '_'</v>
<v>Arity = integer() |'_'</v>
<v>MatchSpec = integer() | Built-inAlias | [] | match_spec()</v>
<v>Built-inAlias = x | c | cx</v>
<v>MatchDesc = [MatchInfo]</v>
<v>MatchInfo = {saved, integer()} | MatchNum</v>
<v>MatchNum = {matched, node(), integer()} | {matched, node(), 0, RPCError}</v>
</type>
<desc>
<p>This function enables call trace for one or more
functions. All exported functions matching the <c>{Module, Function, Arity}</c> argument will be concerned, but the
<c>match_spec()</c> may further narrow down the set of function
calls generating trace messages.</p>
<p>For a description of the <c>match_spec()</c> syntax,
please turn to the
<em>User's guide</em> part of the online
documentation for the runtime system (<em>erts</em>). The
chapter <em>Match Specification in Erlang</em> explains the
general match specification "language".</p>
<p>The Module, Function and/or Arity parts of the tuple may
be specified as the atom <c>'_'</c> which is a "wild-card"
matching all modules/functions/arities. Note, if the
Module is specified as <c>'_'</c>, the Function and Arity
parts have to be specified as '_' too. The same holds for the
Functions relation to the Arity.</p>
<p>All nodes added with <c>n/1</c> or <c>tracer/0/2/3</c> will
be affected by this call, and if Module is not <c>'_'</c>
the module will be loaded on all nodes.</p>
<p>The function returns either an error tuple or a tuple
<c>{ok, List}</c>. The <c>List</c> consists of specifications of how
many functions that matched, in the same way as the processes
are presented in the return value of <c>p/2</c>. </p>
<p>There may be a tuple <c>{saved, N}</c> in the return value,
if the MatchSpec is other
than []. The integer <c>N</c> may then be used in
subsequent calls to this function and will stand as an
"alias" for the given expression. There are also a couple of
built-in aliases for common expressions, see <c>ltp/0</c> below
for details.</p>
<p>If an error is returned, it can be due to errors in
compilation of the match specification. Such errors are
presented as a list of tuples <c>{error, string()}</c> where
the string is a textual explanation of the compilation
error. An example:</p>
<pre>
(x@y)4> <input>dbg:tp({dbg,ltp,0},[{[],[],[{message, two, arguments}, {noexist}]}]).</input>
{error,
[{error,"Special form 'message' called with wrong number of
arguments in {message,two,arguments}."},
{error,"Function noexist/1 does_not_exist."}]}</pre>
</desc>
</func>
<func>
<name>tpl(Module,MatchSpec)</name>
<fsummary>Set pattern for traced local (as well as global) function calls</fsummary>
<desc>
<p>Same as tpl({Module, '_', '_'}, MatchSpec)</p>
</desc>
</func>
<func>
<name>tpl(Module,Function,MatchSpec)</name>
<fsummary>Set pattern for traced local (as well as global) function calls</fsummary>
<desc>
<p>Same as tpl({Module, Function, '_'}, MatchSpec)</p>
</desc>
</func>
<func>
<name>tpl(Module, Function, Arity, MatchSpec)</name>
<fsummary>Set pattern for traced local (as well as global) function calls</fsummary>
<desc>
<p>Same as tpl({Module, Function, Arity}, MatchSpec)</p>
</desc>
</func>
<func>
<name>tpl({Module, Function, Arity}, MatchSpec) -> {ok, MatchDesc} | {error, term()}</name>
<fsummary>Set pattern for traced local (as well as global) function calls</fsummary>
<desc>
<p>This function works as <c>tp/2</c>, but enables
tracing for local calls (and local functions) as well as for
global calls (and functions).</p>
</desc>
</func>
<func>
<name>ctp()</name>
<fsummary>Clear call trace pattern for the specified functions</fsummary>
<desc>
<p>Same as ctp({'_', '_', '_'})</p>
</desc>
</func>
<func>
<name>ctp(Module)</name>
<fsummary>Clear call trace pattern for the specified functions</fsummary>
<desc>
<p>Same as ctp({Module, '_', '_'})</p>
</desc>
</func>
<func>
<name>ctp(Module, Function)</name>
<fsummary>Clear call trace pattern for the specified functions</fsummary>
<desc>
<p>Same as ctp({Module, Function, '_'})</p>
</desc>
</func>
<func>
<name>ctp(Module, Function, Arity)</name>
<fsummary>Clear call trace pattern for the specified functions</fsummary>
<desc>
<p>Same as ctp({Module, Function, Arity})</p>
</desc>
</func>
<func>
<name>ctp({Module, Function, Arity}) -> {ok, MatchDesc} | {error, term()}</name>
<fsummary>Clear call trace pattern for the specified functions</fsummary>
<type>
<v>Module = atom() | '_'</v>
<v>Function = atom() | '_'</v>
<v>Arity = integer() | '_'</v>
<v>MatchDesc = [MatchNum]</v>
<v>MatchNum = {matched, node(), integer()} | {matched, node(), 0, RPCError}</v>
</type>
<desc>
<p>This function disables call tracing on the specified
functions. The semantics of the parameter is the same
as for the corresponding function specification in
<c>tp/2</c> or <c>tpl/2</c>. Both local and global call trace
is disabled. </p>
<p>The return value reflects how many functions that matched,
and is constructed as described in <c>tp/2</c>. No tuple
<c>{saved, N}</c> is however ever returned (for obvious reasons).</p>
</desc>
</func>
<func>
<name>ctpl()</name>
<fsummary>Clear call trace pattern for the specified functions</fsummary>
<desc>
<p>Same as ctpl({'_', '_', '_'})</p>
</desc>
</func>
<func>
<name>ctpl(Module)</name>
<fsummary>Clear call trace pattern for the specified functions</fsummary>
<desc>
<p>Same as ctpl({Module, '_', '_'})</p>
</desc>
</func>
<func>
<name>ctpl(Module, Function)</name>
<fsummary>Clear call trace pattern for the specified functions</fsummary>
<desc>
<p>Same as ctpl({Module, Function, '_'})</p>
</desc>
</func>
<func>
<name>ctpl(Module, Function, Arity)</name>
<fsummary>Clear call trace pattern for the specified functions</fsummary>
<desc>
<p>Same as ctpl({Module, Function, Arity})</p>
</desc>
</func>
<func>
<name>ctpl({Module, Function, Arity}) -> {ok, MatchDesc} | {error, term()}</name>
<fsummary>Clear call trace pattern for the specified functions</fsummary>
<desc>
<p>This function works as <c>ctp/1</c>, but only disables
tracing set up with <c>tpl/2</c> (not with <c>tp/2</c>).</p>
</desc>
</func>
<func>
<name>ctpg()</name>
<fsummary>Clear call trace pattern for the specified functions</fsummary>
<desc>
<p>Same as ctpg({'_', '_', '_'})</p>
</desc>
</func>
<func>
<name>ctpg(Module)</name>
<fsummary>Clear call trace pattern for the specified functions</fsummary>
<desc>
<p>Same as ctpg({Module, '_', '_'})</p>
</desc>
</func>
<func>
<name>ctpg(Module, Function)</name>
<fsummary>>Clear call trace pattern for the specified functions</fsummary>
<desc>
<p>Same as ctpg({Module, Function, '_'})</p>
</desc>
</func>
<func>
<name>ctpg(Module, Function, Arity)</name>
<fsummary>>Clear call trace pattern for the specified functions</fsummary>
<desc>
<p>Same as ctpg({Module, Function, Arity})</p>
</desc>
</func>
<func>
<name>ctpg({Module, Function, Arity}) -> {ok, MatchDesc} | {error, term()}</name>
<fsummary>Clear call trace pattern for the specified functions</fsummary>
<desc>
<p>This function works as <c>ctp/1</c>, but only disables
tracing set up with <c>tp/2</c> (not with <c>tpl/2</c>).</p>
</desc>
</func>
<func>
<name>ltp() -> ok</name>
<fsummary>List saved and built-in match specifications on the console.</fsummary>
<desc>
<p>Use this function to recall all match specifications previously
used in the session (i. e. previously saved during calls
to <c>tp/2</c>, and built-in match specifications.
This is very useful, as a complicated
match_spec can be quite awkward to write. Note that the
match specifications are lost if <c>stop/0</c> is called.</p>
<p>Match specifications used can be saved in a file (if a
read-write file system is present) for use in later
debugging sessions, see <c>wtp/1</c> and <c>rtp/1</c></p>
<p>There are three built-in trace patterns:
<c>exception_trace</c>, <c>caller_trace</c>
and <c>caller_exception_trace</c> (or <c>x</c>, <c>c</c> and
<c>cx</c> respectively).
Exception trace sets a trace which will show function names,
parameters, return values and exceptions thrown from functions.
Caller traces display function names, parameters and information
about which function called it. An example using a built-in alias:</p>
<pre>
(x@y)4> <input>dbg:tp(lists,sort,cx).</input>
{ok,[{matched,nonode@nohost,2},{saved,cx}]}
(x@y)4> <input>lists:sort([2,1]).</input>
(<0.32.0>) call lists:sort([2,1]) ({erl_eval,do_apply,5})
(<0.32.0>) returned from lists:sort/1 -> [1,2]
[1,2]</pre>
</desc>
</func>
<func>
<name>dtp() -> ok</name>
<fsummary>Delete all saved match specifications.</fsummary>
<desc>
<p>Use this function to "forget" all match specifications
saved during calls to <c>tp/2</c>.
This is useful when one wants to restore other match
specifications from a file with <c>rtp/1</c>. Use
<c>dtp/1</c> to delete specific saved match specifications. </p>
</desc>
</func>
<func>
<name>dtp(N) -> ok</name>
<fsummary>Delete a specific saved match_spec.</fsummary>
<type>
<v>N = integer()</v>
</type>
<desc>
<p>Use this function to "forget" a specific match specification
saved during calls to <c>tp/2</c>.</p>
</desc>
</func>
<func>
<name>wtp(Name) -> ok | {error, IOError}</name>
<fsummary>Write all saved and built-in match specifications to a file</fsummary>
<type>
<v>Name = string()</v>
<v>IOError = term()</v>
</type>
<desc>
<p>This function will save all match specifications saved
during the session (during calls to <c>tp/2</c>)
and built-in match specifications in a text
file with the name designated by <c>Name</c>. The format
of the file is textual, why it can be edited with an
ordinary text editor, and then restored with
<c>rtp/1</c>. </p>
<p>Each match spec in the file ends with a full stop
(<c>.</c>) and new (syntactically correct) match
specifications can be added to the file manually.</p>
<p>The function returns <c>ok</c> or an error tuple where the
second element contains the I/O error that made the
writing impossible.</p>
</desc>
</func>
<func>
<name>rtp(Name) -> ok | {error, Error}</name>
<fsummary>Read saved match specifications from file.</fsummary>
<type>
<v>Name = string()</v>
<v>Error = term()</v>
</type>
<desc>
<p>This function reads match specifications from a file
(possibly) generated by the <c>wtp/1</c> function. It checks
the syntax of all match specifications and verifies that
they are correct. The error handling principle is "all or
nothing", i. e. if some of the match specifications are
wrong, none of the specifications are added to the list of
saved match specifications for the running system. </p>
<p>The match specifications in the file are <em>merged</em>
with the current match specifications, so that no duplicates
are generated. Use <c>ltp/0</c> to see what numbers were
assigned to the specifications from the file.</p>
<p>The function will return an error, either due to I/O
problems (like a non existing or non readable file) or due
to file format problems. The errors from a bad format file
are in a more or less textual format, which will give a hint
to what's causing the problem. <marker id="n"></marker>
</p>
</desc>
</func>
<func>
<name>n(Nodename) -> {ok, Nodename} | {error, Reason}</name>
<fsummary>Add a remote node to the list of traced nodes</fsummary>
<type>
<v>Nodename = atom()</v>
<v>Reason = term()</v>
</type>
<desc>
<p>The <c>dbg</c> server keeps a list of nodes where tracing
should be performed. Whenever a <c>tp/2</c> call or a
<c>p/2</c> call is made, it is executed for all nodes in this
list including the local node (except for <c>p/2</c> with a
specific <c>pid()</c> as first argument, in which case the
command is executed only on the node where the designated
process resides).
</p>
<p>This function adds a remote node (<c>Nodename</c>) to the
list of nodes where tracing is performed. It starts a tracer
process on the remote node, which will send all trace messages
to the tracer process on the local node (via the Erlang
distribution). If no tracer process is running on the local
node, the error reason <c>no_local_tracer</c> is returned. The
tracer process on the local node must be started with the
<c>tracer/0/2</c> function.
</p>
<p>If <c>Nodename</c> is the local node, the error reason
<c>cant_add_local_node</c> is returned.
</p>
<p>If a trace port (<seealso marker="#trace_port">see</seealso><c>trace_port/2</c>) is
running on the local node, remote nodes can not be traced with
a tracer process. The error reason
<c>cant_trace_remote_pid_to_local_port</c> is returned. A
trace port can however be started on the remote node with the
<c>tracer/3</c> function.
</p>
<p>The function will also return an error if the node
<c>Nodename</c> is not reachable.</p>
</desc>
</func>
<func>
<name>cn(Nodename) -> ok</name>
<fsummary>Clear a node from the list of traced nodes.</fsummary>
<type>
<v>Nodename = atom()</v>
</type>
<desc>
<p>Clears a node from the list of traced nodes. Subsequent
calls to <c>tp/2</c> and <c>p/2</c> will not consider that
node, but tracing already activated on the node will continue
to be in effect.</p>
<p>Returns <c>ok</c>, cannot fail.</p>
</desc>
</func>
<func>
<name>ln() -> ok</name>
<fsummary>Show the list of traced nodes on the console.</fsummary>
<desc>
<p>Shows the list of traced nodes on the console.</p>
</desc>
</func>
<func>
<name>tracer() -> {ok, pid()} | {error, already_started}</name>
<fsummary>Start a tracer server that handles trace messages.</fsummary>
<desc>
<p>This function starts a server on the local node that will
be the recipient of all trace messages. All subsequent calls
to <c>p/2</c> will result in messages sent to the newly
started trace server.</p>
<p>A trace server started in this way will simply display the
trace messages in a formatted way in the Erlang shell
(i. e. use io:format). See <c>tracer/2</c> for a description
of how the trace message handler can be customized. <marker id="tracer2"></marker>
</p>
<p>To start a similar tracer on a remote node, use <c>n/1</c>.</p>
</desc>
</func>
<func>
<name>tracer(Type, Data) -> {ok, pid()} | {error, Error}</name>
<fsummary>Start a tracer server with additional parameters</fsummary>
<type>
<v>Type = port | process</v>
<v>Data = PortGenerator | HandlerSpec</v>
<v>HandlerSpec = {HandlerFun, InitialData}</v>
<v>HandlerFun = fun() (two arguments)</v>
<v>InitialData = term()</v>
<v>PortGenerator = fun() (no arguments)</v>
<v>Error = term()</v>
</type>
<desc>
<p>This function starts a tracer server with additional
parameters on the local node. The first parameter, the
<c>Type</c>, indicates if trace messages should be handled
by a receiving process (<c>process</c>) or by a tracer port
(<c>port</c>). For a description about tracer ports see
<c>trace_port/2</c>.
</p>
<p>If <c>Type</c> is a process, a message handler function can
be specified (<c>HandlerSpec</c>). The handler function, which
should be a <c>fun</c> taking two arguments, will be called
for each trace message, with the first argument containing the
message as it is and the second argument containing the return
value from the last invocation of the fun. The initial value
of the second parameter is specified in the <c>InitialData</c>
part of the <c>HandlerSpec</c>. The <c>HandlerFun</c> may
choose any appropriate action to take when invoked, and can
save a state for the next invocation by returning it.
</p>
<p>If <c>Type</c> is a port, then the second parameter should
be a <em>fun</em> which takes no arguments and returns a
newly opened trace port when called. Such a <em>fun</em> is
preferably generated by calling <c>trace_port/2</c>.
</p>
<p>If an error is returned, it can either be due to a tracer
server already running (<c>{error,already_started}</c>) or
due to the <c>HandlerFun</c> throwing an exception.
</p>
<p>To start a similar tracer on a remote node, use
<c>tracer/3</c>. <marker id="trace_port"></marker>
</p>
</desc>
</func>
<func>
<name>tracer(Nodename, Type, Data) -> {ok, Nodename} | {error, Reason}</name>
<fsummary>Start a tracer server on given node with additional parameters</fsummary>
<type>
<v>Nodename = atom()</v>
</type>
<desc>
<p>This function is equivalent to <c>tracer/2</c>, but acts on
the given node. A tracer is started on the node
(<c>Nodename</c>) and the node is added to the list of traced
nodes.
</p>
<note>
<p>This function is not equivalent to <c>n/1</c>. While
<c>n/1</c> starts a process tracer which redirects all trace
information to a process tracer on the local node (i.e. the
trace control node), <c>tracer/3</c> starts a tracer of any
type which is independent of the tracer on the trace control
node.</p>
</note>
<p>For details, <seealso marker="#tracer2">see</seealso><c>tracer/2</c>.</p>
</desc>
</func>
<func>
<name>trace_port(Type, Parameters) -> fun()</name>
<fsummary>Create and returns a trace port generating<em>fun</em></fsummary>
<type>
<v>Type = ip | file</v>
<v>Parameters = Filename | WrapFilesSpec | IPPortSpec</v>
<v>Filename = string() | [string()] | atom()</v>
<v>WrapFilesSpec = {Filename, wrap, Suffix} | {Filename, wrap, Suffix, WrapSize} | {Filename, wrap, Suffix, WrapSize, WrapCnt}</v>
<v>Suffix = string()</v>
<v>WrapSize = integer() >= 0 | {time, WrapTime}</v>
<v>WrapTime = integer() >= 1</v>
<v>WrapCnt = integer() >= 1</v>
<v>IpPortSpec = PortNumber | {PortNumber, QueSize}</v>
<v>PortNumber = integer()</v>
<v>QueSize = integer()</v>
</type>
<desc>
<p>This function creates a trace port generating <em>fun</em>.
The <em>fun</em> takes no arguments and returns a newly opened
trace port. The return value from this function is suitable as
a second parameter to tracer/2, i.e. <c>dbg:tracer(port, dbg:trace_port(ip, 4711))</c>. </p>
<p>A trace port is an
Erlang port to a dynamically linked in driver that handles
trace messages directly, without the overhead of sending them
as messages in the Erlang virtual machine.</p>
<p>Two trace drivers are currently implemented, the
<c>file</c> and the <c>ip</c> trace drivers. The file driver
sends all trace messages into one or several binary files,
from where they later can be fetched and processed with the
<c>trace_client/2</c> function. The ip driver opens a TCP/IP
port where it listens for connections. When a client
(preferably started by calling <c>trace_client/2</c> on
another Erlang node) connects, all trace messages are sent
over the IP network for further processing by the remote
client. </p>
<p>Using a trace port significantly lowers the overhead
imposed by using tracing.</p>
<p>The file trace driver expects a filename or a wrap files
specification as parameter. A file is written with a high
degree of buffering, why all trace messages are <em>not</em>
guaranteed to be saved in the file in case of a system
crash. That is the price to pay for low tracing overhead.</p>
<p>A wrap files specification is used to limit the disk
space consumed by the trace. The trace is written to a
limited number of files each with a limited size.
The actual filenames are <c>Filename ++ SeqCnt ++ Suffix</c>, where <c>SeqCnt</c> counts as a decimal string
from <c>0</c> to <c>WrapCnt</c> and then around again from
<c>0</c>. When a trace term written to
the current file makes it longer than <c>WrapSize</c>,
that file is closed, if the number of files in this
wrap trace is as many as <c>WrapCnt</c> the oldest file
is deleted then a new file is opened to become the current.
Thus, when a wrap trace has been stopped, there are at most
<c>WrapCnt</c> trace files saved with a size of at least
<c>WrapSize</c> (but not much bigger), except for
the last file that might even be empty. The default values
are <c>WrapSize = 128*1024</c> and <c>WrapCnt = 8</c>.</p>
<p>The <c>SeqCnt</c> values in the filenames are all in the
range <c>0</c> through <c>WrapCnt</c> with a gap in the
circular sequence. The gap is needed to find the end of the
trace.</p>
<p>If the <c>WrapSize</c> is specified as
<c>{time, WrapTime}</c>, the current file is closed when it
has been open more than <c>WrapTime</c> milliseconds,
regardless of it being empty or not.</p>
<p>The ip trace driver has a queue of <c>QueSize</c> messages
waiting to be delivered. If the driver cannot deliver messages
as fast as they are produced by the runtime system, a special
message is sent, which indicates how many messages that are
dropped. That message will arrive at the handler function
specified in <c>trace_client/3</c> as the tuple <c>{drop, N}</c> where <c>N</c> is the number of consecutive messages
dropped. In case of heavy tracing, drop's are likely to occur,
and they surely occur if no client is reading the trace
messages.</p>
</desc>
</func>
<func>
<name>flush_trace_port()</name>
<fsummary>Equivalent to flush_trace_port(node()).</fsummary>
<desc>
<p>Equivalent to <c>flush_trace_port(node())</c>.</p>
</desc>
</func>
<func>
<name>flush_trace_port(Nodename) -> ok | {error, Reason}</name>
<fsummary>Flush internal data buffers in a trace driver on the given node.</fsummary>
<desc>
<p>Equivalent to <c>trace_port_control(Nodename,flush)</c>.</p>
</desc>
</func>
<func>
<name>trace_port_control(Operation)</name>
<fsummary>Equivalent to trace_port_control(node(),Operation).</fsummary>
<desc>
<p>Equivalent to <c>trace_port_control(node(),Operation)</c>.</p>
</desc>
</func>
<func>
<name>trace_port_control(Nodename,Operation) -> ok | {ok, Result} | {error, Reason}</name>
<fsummary>Perform a control operation on the active trace port driver on the given node.</fsummary>
<type>
<v>Nodename = atom()</v>
</type>
<desc>
<p>This function is used to do a control operation on the
active trace port driver on the given node
(<c>Nodename</c>). Which operations are allowed as well
as their return values depend on which trace driver
is used.</p>
<p>Returns either <c>ok</c> or <c>{ok, Result}</c>
if the operation was successful, or <c>{error, Reason}</c>
if the current tracer is a process
or if it is a port not supporting the operation.</p>
<p>The allowed values for <c>Operation</c> are:</p>
<taglist>
<tag><c>flush</c></tag>
<item>
<p>This function is used to flush the internal buffers
held by a trace port driver. Currently only the
file trace driver supports this operation.
Returns <c>ok</c>.</p>
</item>
<tag><c>get_listen_port</c></tag>
<item>
<p>Returns <c>{ok, IpPort}</c> where <c>IpPort</c>is
the IP port number used by the driver listen socket.
Only the ip trace driver supports this operation.</p>
</item>
</taglist>
</desc>
</func>
<func>
<name>trace_client(Type, Parameters) -> pid()</name>
<fsummary>Start a trace client that reads messages created by a trace port driver</fsummary>
<type>
<v>Type = ip | file | follow_file</v>
<v>Parameters = Filename | WrapFilesSpec | IPClientPortSpec</v>
<v>Filename = string() | [string()] | atom()</v>
<v>WrapFilesSpec = see trace_port/2</v>
<v>Suffix = string()</v>
<v>IpClientPortSpec = PortNumber | {Hostname, PortNumber}</v>
<v>PortNumber = integer()</v>
<v>Hostname = string()</v>
</type>
<desc>
<p>This function starts a trace client that reads the output
created by a trace port driver and handles it in mostly the
same way as a tracer process created by the <c>tracer/0</c>
function.</p>
<p>If <c>Type</c> is <c>file</c>, the client reads all trace
messages stored in the file named <c>Filename</c> or
specified by <c>WrapFilesSpec</c> (must be the same as used
when creating the trace, see trace_port/2)
and let's the default handler function format the
messages on the console. This is one way to interpret the data
stored in a file by the file trace port driver.</p>
<p>If <c>Type</c> is <c>follow_file</c>, the client behaves as
in the <c>file</c> case, but keeps trying to read (and
process) more data
from the file until stopped by <c>stop_trace_client/1</c>.
<c>WrapFilesSpec</c> is not allowed as second argument
for this <c>Type</c>.</p>
<p>If <c>Type</c> is <c>ip</c>, the client connects to the
TCP/IP port <c>PortNumber</c> on the host <c>Hostname</c>,
from where it reads trace messages until the TCP/IP connection
is closed. If no <c>Hostname</c> is specified, the local host
is assumed.</p>
<p>As an example, one can let trace messages be sent over the
network to another Erlang node (preferably <em>not</em>
distributed), where the formatting occurs:</p>
<p>On the node <c>stack</c> there's an Erlang node
<c>ant@stack</c>, in the shell, type the following:</p>
<pre>
ant@stack> <input>dbg:tracer(port, dbg:trace_port(ip,4711)).</input>
<0.17.0>
ant@stack> <input>dbg:p(self(), send).</input>
{ok,1}</pre>
<p>All trace messages are now sent to the trace port driver,
which in turn listens for connections on the TCP/IP port
4711. If we want to see the messages on another node,
preferably on another host, we do like this:</p>
<pre>
-> <input>dbg:trace_client(ip, {"stack", 4711}).</input>
<0.42.0></pre>
<p>If we now send a message from the shell on the node
<c>ant@stack</c>, where all sends from the shell are traced:</p>
<pre>
ant@stack> <input>self() ! hello.</input>
hello</pre>
<p>The following will appear at the console on the node that
started the trace client:</p>
<pre>
(<0.23.0>) <0.23.0> ! hello
(<0.23.0>) <0.22.0> ! {shell_rep,<0.23.0>,{value,hello,[],[]}}</pre>
<p>The last line is generated due to internal message passing
in the Erlang shell. The process id's will vary.</p>
</desc>
</func>
<func>
<name>trace_client(Type, Parameters, HandlerSpec) -> pid()</name>
<fsummary>Start a trace client that reads messages created by a trace port driver, with a user defined handler</fsummary>
<type>
<v>Type = ip | file | follow_file</v>
<v>Parameters = Filename | WrapFilesSpec | IPClientPortSpec</v>
<v>Filename = string() | [string()] | atom()</v>
<v>WrapFilesSpec = see trace_port/2</v>
<v>Suffix = string()</v>
<v>IpClientPortSpec = PortNumber | {Hostname, PortNumber}</v>
<v>PortNumber = integer()</v>
<v>Hostname = string()</v>
<v>HandlerSpec = {HandlerFun, InitialData}</v>
<v>HandlerFun = fun() (two arguments)</v>
<v>InitialData = term()</v>
</type>
<desc>
<p>This function works exactly as <c>trace_client/2</c>, but
allows you to write your own handler function. The handler
function works mostly as the one described in
<c>tracer/2</c>, but will also have to be prepared to handle
trace messages of the form <c>{drop, N}</c>, where <c>N</c> is
the number of dropped messages. This pseudo trace message will
only occur if the ip trace driver is used.</p>
<p>For trace type <c>file</c>, the pseudo trace message
<c>end_of_trace</c> will appear at the end of the trace. The
return value from the handler function is in this case
ignored.</p>
</desc>
</func>
<func>
<name>stop_trace_client(Pid) -> ok</name>
<fsummary>Stop a trace client gracefully.</fsummary>
<type>
<v>Pid = pid()</v>
</type>
<desc>
<p>This function shuts down a previously started trace
client. The <c>Pid</c> argument is the process id returned
from the <c>trace_client/2</c> or <c>trace_client/3</c> call.</p>
</desc>
</func>
<func>
<name>get_tracer()</name>
<fsummary>Equivalent to get_tracer(node()).</fsummary>
<desc>
<p>Equivalent to <c>get_tracer(node())</c>.</p>
</desc>
</func>
<func>
<name>get_tracer(Nodename) -> {ok, Tracer}</name>
<fsummary>Return the process or port to which all trace messages are sent.</fsummary>
<type>
<v>Nodename = atom()</v>
<v>Tracer = port() | pid()</v>
</type>
<desc>
<p>Returns the process or port to which all trace
messages are sent. </p>
</desc>
</func>
<func>
<name>stop() -> stopped</name>
<fsummary>Stop the <c>dbg</c>server and the tracing of all processes.</fsummary>
<desc>
<p>Stops the <c>dbg</c> server and clears all trace flags for
all processes and all trace patterns for all functions. Also
shuts down all trace clients and closes all trace ports.</p>
<p>Note that no trace patterns are affected by this
function.</p>
</desc>
</func>
<func>
<name>stop_clear() -> stopped</name>
<fsummary>Stop the <c>dbg</c>server and the tracing of all processes, and clears trace patterns.</fsummary>
<desc>
<p>Same as stop/0, but also clears all trace patterns on local
and global functions calls.</p>
</desc>
</func>
</funcs>
<section>
<marker id="simple_example"></marker>
<title>Simple examples - tracing from the shell</title>
<p>The simplest way of tracing from the Erlang shell is to use
<c>dbg:c/3</c> or <c>dbg:c/4</c>, e.g. tracing the function
<c>dbg:get_tracer/0</c>:</p>
<pre>
(tiger@durin)84> <input>dbg:c(dbg,get_tracer,[]).</input>
(<0.154.0>) <0.152.0> ! {<0.154.0>,{get_tracer,tiger@durin}}
(<0.154.0>) out {dbg,req,1}
(<0.154.0>) << {dbg,{ok,<0.153.0>}}
(<0.154.0>) in {dbg,req,1}
(<0.154.0>) << timeout
{ok,<0.153.0>}
(tiger@durin)85></pre>
<p>Another way of tracing from the shell is to explicitly start a
<em>tracer</em> and then set the <em>trace flags</em> of your
choice on the processes you want to trace, e.g. trace messages and
process events:</p>
<pre>
(tiger@durin)66> <input>Pid = spawn(fun() -> receive {From,Msg} -> From ! Msg end end).</input>
<0.126.0>
(tiger@durin)67> <input>dbg:tracer().</input>
{ok,<0.128.0>}
(tiger@durin)68> <input>dbg:p(Pid,[m,procs]).</input>
{ok,[{matched,tiger@durin,1}]}
(tiger@durin)69> <input>Pid ! {self(),hello}.</input>
(<0.126.0>) << {<0.116.0>,hello}
{<0.116.0>,hello}
(<0.126.0>) << timeout
(<0.126.0>) <0.116.0> ! hello
(<0.126.0>) exit normal
(tiger@durin)70> <input>flush().</input>
Shell got hello
ok
(tiger@durin)71></pre>
<p>If you set the <c>call</c> trace flag, you also have to set a
<em>trace pattern</em> for the functions you want to trace:</p>
<pre>
(tiger@durin)77> <input>dbg:tracer().</input>
{ok,<0.142.0>}
(tiger@durin)78> <input>dbg:p(all,call).</input>
{ok,[{matched,tiger@durin,3}]}
(tiger@durin)79> <input>dbg:tp(dbg,get_tracer,0,[]).</input>
{ok,[{matched,tiger@durin,1}]}
(tiger@durin)80> <input>dbg:get_tracer().</input>
(<0.116.0>) call dbg:get_tracer()
{ok,<0.143.0>}
(tiger@durin)81> <input>dbg:tp(dbg,get_tracer,0,[{'_',[],[{return_trace}]}]).</input>
{ok,[{matched,tiger@durin,1},{saved,1}]}
(tiger@durin)82> <input>dbg:get_tracer().</input>
(<0.116.0>) call dbg:get_tracer()
(<0.116.0>) returned from dbg:get_tracer/0 -> {ok,<0.143.0>}
{ok,<0.143.0>}
(tiger@durin)83></pre>
</section>
<section>
<marker id="advanced"></marker>
<title>Advanced topics - combining with seq_trace</title>
<p>The <c>dbg</c> module is primarily targeted towards
tracing through the <c>erlang:trace/3</c> function. It is
sometimes desired to trace messages in a more delicate way, which
can be done with the help of the <c>seq_trace</c> module.
</p>
<p><c>seq_trace</c> implements sequential tracing (known in the
AXE10 world, and sometimes called "forlopp tracing"). <c>dbg</c>
can interpret messages generated from <c>seq_trace</c> and the
same tracer function for both types of tracing can be used. The
<c>seq_trace</c> messages can even be sent to a trace port for
further analysis.
</p>
<p>As a match specification can turn on sequential tracing, the
combination of <c>dbg</c> and <c>seq_trace</c> can be quite
powerful. This brief example shows a session where sequential
tracing is used:</p>
<pre>
1> <input>dbg:tracer().</input>
{ok,<0.30.0>}
2> <input>{ok, Tracer} = dbg:get_tracer().</input>
{ok,<0.31.0>}
3> <input>seq_trace:set_system_tracer(Tracer).</input>
false
4> <input>dbg:tp(dbg, get_tracer, 0, [{[],[],[{set_seq_token, send, true}]}]).</input>
{ok,[{matched,nonode@nohost,1},{saved,1}]}
5> <input>dbg:p(all,call).</input>
{ok,[{matched,nonode@nohost,22}]}
6> <input>dbg:get_tracer(), seq_trace:set_token([]).</input>
(<0.25.0>) call dbg:get_tracer()
SeqTrace [0]: (<0.25.0>) <0.30.0> ! {<0.25.0>,get_tracer} [Serial: {2,4}]
SeqTrace [0]: (<0.30.0>) <0.25.0> ! {dbg,{ok,<0.31.0>}} [Serial: {4,5}]
{1,0,5,<0.30.0>,4}</pre>
<p>This session sets the system_tracer to the same process as
the ordinary tracer process (i. e. <0.31.0>) and sets the
trace pattern for the function <c>dbg:get_tracer</c> to one that
has the action of setting a sequential token. When the function
is called by a traced process (all processes are traced in this
case), the process gets "contaminated" by the token and
<c>seq_trace</c> messages are sent both for the server request
and the response. The <c>seq_trace:set_token([])</c> after the
call clears the <c>seq_trace</c> token, why no messages are sent
when the answer propagates via the shell to the console port.
The output would otherwise have been more noisy.</p>
</section>
<section>
<title>Note of caution</title>
<p>When tracing function calls on a group leader process (an IO process), there is risk
of causing a deadlock. This will happen if a group leader process generates a trace
message and the tracer process, by calling the trace handler function, sends an IO
request to the same group leader. The problem can only occur if the trace handler
prints to tty using an <c>io</c> function such as <c>format/2</c>. Note that when
<c>dbg:p(all,call)</c> is called, IO processes are also traced.
Here's an example:</p>
<pre>
%% Using a default line editing shell
1> <input>dbg:tracer(process, {fun(Msg,_) -> io:format("~p~n", [Msg]), 0 end, 0}).</input>
{ok,<0.37.0>}
2> <input>dbg:p(all, [call]).</input>
{ok,[{matched,nonode@nohost,25}]}
3> <input>dbg:tp(mymod,[{'_',[],[]}]).</input>
{ok,[{matched,nonode@nohost,0},{saved,1}]}
4> <input>mymod:</input> % TAB pressed here
%% -- Deadlock --</pre>
<p>Here's another example:</p>
<pre>
%% Using a shell without line editing (oldshell)
1> <input>dbg:tracer(process).</input>
{ok,<0.31.0>}
2> <input>dbg:p(all, [call]).</input>
{ok,[{matched,nonode@nohost,25}]}
3> <input>dbg:tp(lists,[{'_',[],[]}]).</input>
{ok,[{matched,nonode@nohost,0},{saved,1}]}
% -- Deadlock --</pre>
<p>The reason we get a deadlock in the first example is because when TAB is pressed
to expand the function name, the group leader (which handles character input) calls
<c>mymod:module_info()</c>. This generates a trace message which, in turn, causes the
tracer process to send an IO request to the group leader (by calling <c>io:format/2</c>).
We end up in a deadlock.</p>
<p>In the second example we use the default trace handler function. This handler
prints to tty by sending IO requests to the <c>user</c> process. When Erlang is
started in oldshell mode, the shell process will have <c>user</c> as its
group leader and so will the tracer process in this example. Since <c>user</c> calls
functions in <c>lists</c> we end up in a deadlock as soon as the first IO request is sent.</p>
<p>Here are a few suggestions for how to avoid deadlock:</p>
<list type="bulleted">
<item>Don't trace the group leader of the tracer process. If tracing has been switched on
for all processes, call <c>dbg:p(TracerGLPid,clear)</c> to stop tracing the group leader
(<c>TracerGLPid</c>). <c>process_info(TracerPid,group_leader)</c> tells you
which process this is (<c>TracerPid</c> is returned from <c>dbg:get_tracer/0</c>).</item>
<item>Don't trace the <c>user</c> process if using the default trace handler function.</item>
<item>In your own trace handler function, call <c>erlang:display/1</c> instead of an
<c>io</c> function or, if <c>user</c> is not used as group leader, print to
<c>user</c> instead of the default group leader. Example:
<c>io:format(user,Str,Args)</c>.</item>
</list>
</section>
</erlref>