dbg(3)



dbg(3erl)                  Erlang Module Definition                  dbg(3erl)

NAME
       dbg - The Text Based Trace Facility

DESCRIPTION
       This  module  implements  a text based interface to the trace/3 and the
       trace_pattern/2 BIFs. It makes it possible  to  trace  functions,  pro-
       cesses, ports and messages.

       To  quickly  get started on tracing function calls you can use the fol-
       lowing code in the Erlang shell:

       1> dbg:tracer(). %% Start the default trace message receiver
       {ok,<0.36.0>}
       2> dbg:p(all, c). %% Setup call (c) tracing on all processes
       {ok,[{matched,nonode@nohost,26}]}
       3> dbg:tp(lists, seq, x). %% Setup an exception return trace (x) on lists:seq
       {ok,[{matched,nonode@nohost,2},{saved,x}]}
       4> lists:seq(1,10).
       (<0.34.0>) call lists:seq(1,10)
       (<0.34.0>) returned from lists:seq/2 -> [1,2,3,4,5,6,7,8,9,10]
       [1,2,3,4,5,6,7,8,9,10]

       For more examples of how to use dbg from the Erlang shell, see the sim-
       ple example section.

       The  utilities are also suitable to use in system testing on large sys-
       tems, where other tools have too much impact on the system performance.
       Some primitive support for sequential tracing is also included, see the
       advanced topics section.

EXPORTS
       fun2ms(LiteralFun) -> MatchSpec

              Types:

                 LiteralFun = fun() literal
                 MatchSpec = term()

              Pseudo function that by means of  a  parse_transform  translates
              the  literalfun()  typed  as parameter in the function call to a
              match specification as described in  the  match_spec  manual  of
              ERTS  users  guide. (with literal I mean that the fun() 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).

              The  parse  transform  is implemented in the module ms_transform
              and the source must include the file ms_transform.hrl 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  -include_lib("stdlib/include/ms_transform.hrl").  to   the
              source file.

              The  fun() is very restricted, it can take only a single parame-
              ter (the parameter list to match), a sole variable or a list. It
              needs  to use the is_XXX guard tests and one cannot use language
              constructs that have no representation in a match_spec (like if,
              case,  receive  etc).  The return value from the fun will be the
              return value of the resulting match_spec.

              Example:

              1> dbg:fun2ms(fun([M,N]) when N > 3 -> return_trace() end).
              [{['$1','$2'],[{'>','$2',3}],[{return_trace}]}]

              Variables from the environment can be  imported,  so  that  this
              works:

              2> X=3.
              3
              3> dbg:fun2ms(fun([M,N]) when N > X -> return_trace() end).
              [{['$1','$2'],[{'>','$2',{const,3}}],[{return_trace}]}]

              The  imported variables will be replaced by match_spec const ex-
              pressions, which is consistent with the static scoping  for  Er-
              lang  fun()s.  Local  or  global function calls cannot be in the
              guard or body of the fun however. Calls  to  builtin  match_spec
              functions of course is allowed:

              4> dbg:fun2ms(fun([M,N]) when N > X, is_atomm(M) -> return_trace() end).
              Error: fun containing local erlang function calls ('is_atomm' called in guard)\
               cannot be translated into match_spec
              {error,transform_error}
              5> dbg:fun2ms(fun([M,N]) when N > X, is_atom(M) -> return_trace() end).
              [{['$1','$2'],[{'>','$2',{const,3}},{is_atom,'$1'}],[{return_trace}]}]

              As  you  can see by the example, the function can be called from
              the shell too. The fun() needs to be literally in the call  when
              used  from  the shell as well. Other means than the parse_trans-
              form are used in the shell case, but more or less the  same  re-
              strictions  apply  (the exception being records, as they are not
              handled by the shell).

          Warning:
              If the parse_transform is not applied to a  module  which  calls
              this  pseudo  function,  the  call  will fail in runtime (with a
              badarg). The module dbg 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  parse_transform  is  properly
              applied  by including the ms_transform.hrl header file, compiled
              code will never call the function, but the function call is  re-
              placed by a literal match_spec.

              More  information is provided by the ms_transform manual page in
              STDLIB.

       h() -> ok

              Gives a list of items for brief online help.

       h(Item) -> ok

              Types:

                 Item = atom()

              Gives a brief help text for functions in  the  dbg  module.  The
              available items can be listed with dbg:h/0

       p(Item) -> {ok, MatchDesc} | {error, term()}

              Equivalent to p(Item, [m]).

       p(Item, Flags) -> {ok, MatchDesc} | {error, term()}

              Types:

                 MatchDesc = [MatchNum]
                 MatchNum  =  {matched, node(), integer()} | {matched, node(),
                 0, RPCError}
                 RPCError = term()

              Traces Item in accordance to the value specified by  Flags.  The
              variation of Item is listed below:

                pid() or port():
                  The  corresponding process or port is traced. The process or
                  port may be a remote process  or  port  (on  another  Erlang
                  node). The node must be in the list of traced nodes (see n/1
                  and tracer/3).

                all:
                  All processes and ports in the system as well  as  all  pro-
                  cesses and ports created hereafter are to be traced.

                processes:
                  All processes in the system as well as all processes created
                  hereafter are to be traced.

                ports:
                  All ports in the system as well as all ports  created  here-
                  after are to be traced.

                new:
                  All  processes and ports created after the call is are to be
                  traced.

                new_processes:
                  All processes created after the call is are to be traced.

                new_ports:
                  All ports created after the call is are to be traced.

                existing:
                  All existing processes and ports are traced.

                existing_processes:
                  All existing processes are traced.

                existing_ports:
                  All existing ports are traced.

                atom():
                  The process or port with the corresponding  registered  name
                  is  traced.  The process or port may be a remote process (on
                  another Erlang node). The node must be added with the n/1 or
                  tracer/3 function.

                integer():
                  The process <0.Item.0> is traced.

                {X, Y, Z}:
                  The process <X.Y.Z> is traced.

                string():
                  If   the  Item  is  a  string  "<X.Y.Z>"  as  returned  from
                  pid_to_list/1, the process <X.Y.Z> is traced.

              When enabling an Item that represents a group of processes,  the
              Item  is  enabled  on  all  nodes added with the n/1 or tracer/3
              function.

              Flags can be a single atom, or a list of  flags.  The  available
              flags are:

                s (send):
                  Traces the messages the process or port sends.

                r (receive):
                  Traces the messages the process or port receives.

                m (messages):
                  Traces the messages the process or port receives and sends.

                c (call):
                  Traces  global  function  calls for the process according to
                  the trace patterns set in the system (see tp/2).

                p (procs):
                  Traces process related events to the process.

                ports:
                  Traces port related events to the port.

                sos (set on spawn):
                  Lets all processes created by the traced process inherit the
                  trace flags of the traced process.

                sol (set on link):
                  Lets  another  process,  P2,  inherit the trace flags of the
                  traced process whenever the traced process links to P2.

                sofs (set on first spawn):
                  This is the same as sos, but  only  for  the  first  process
                  spawned by the traced process.

                sofl (set on first link):
                  This  is  the  same  as  sol, but only for the first call to
                  link/1 by the traced process.

                all:
                  Sets all flags except silent.

                clear:
                  Clears all flags.

              The list can also include  any  of  the  flags  allowed  in  er-
              lang:trace/3

              The  function  returns  either  an  error  tuple or a tuple {ok,
              List}. The List consists of specifications of how many processes
              and  ports that matched (in the case of a pure pid() exactly 1).
              The specification of matched processes is {matched, Node, N}. If
              the  remote processor call, rpc, to a remote node fails, the rpc
              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 rpc calls to one, several or even all nodes
              failed.

       c(Mod, Fun, Args)

              Equivalent to c(Mod, Fun, Args, all).

       c(Mod, Fun, Args, Flags)

              Evaluates  the  expression  apply(Mod, Fun, Args) with the trace
              flags in Flags set. This is a convenient way to trace  processes
              from the Erlang shell.

       i() -> ok

              Displays information about all traced processes and ports.

       tp(Module,MatchSpec)

              Same as tp({Module, '_', '_'}, MatchSpec)

       tp(Module,Function,MatchSpec)

              Same as tp({Module, Function, '_'}, MatchSpec)

       tp(Module, Function, Arity, MatchSpec)

              Same as tp({Module, Function, Arity}, MatchSpec)

       tp({Module,  Function,  Arity}, MatchSpec) -> {ok, MatchDesc} | {error,
       term()}

              Types:

                 Module = atom() | '_'
                 Function = atom() | '_'
                 Arity = integer() |'_'
                 MatchSpec = integer() | Built-inAlias | [] | match_spec()
                 Built-inAlias = x | c | cx
                 MatchDesc = [MatchInfo]
                 MatchInfo = {saved, integer()} | MatchNum
                 MatchNum = {matched, node(), integer()} |  {matched,  node(),
                 0, RPCError}

              This  function enables call trace for one or more functions. All
              exported functions matching the {Module, Function, Arity}  argu-
              ment  will be concerned, but the match_spec() may further narrow
              down the set of function calls generating trace messages.

              For a description of the match_spec() syntax, please turn to the
              User's  guide  part  of the online documentation for the runtime
              system (erts). The chapter Match Specifications  in  Erlang  ex-
              plains the general match specification "language". The most com-
              mon generic match specifications used can be found as Built-inA-
              lias', see ltp/0 below for details.

              The  Module,  Function  and/or  Arity  parts of the tuple may be
              specified as the atom '_' which is a  "wild-card"  matching  all
              modules/functions/arities.  Note,  if the Module is specified as
              '_', the Function and Arity parts have to be  specified  as  '_'
              too. The same holds for the Functions relation to the Arity.

              All  nodes  added  with n/1 or tracer/3 will be affected by this
              call, and if Module is not '_' the module will be loaded on  all
              nodes.

              The  function  returns  either  an  error  tuple or a tuple {ok,
              List}. The List consists of specifications of how many functions
              that  matched,  in  the  same way as the processes and ports are
              presented in the return value of p/2.

              There may be a tuple {saved, N} in  the  return  value,  if  the
              MatchSpec  is  other  than []. The integer N 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 ltp/0 below for details.

              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 {error, string()} where the string is a textual expla-
              nation of the compilation error. An example:

              (x@y)4> dbg:tp({dbg,ltp,0},[{[],[],[{message, two, arguments}, {noexist}]}]).
              {error,
               [{error,"Special form 'message' called with wrong number of
                        arguments in {message,two,arguments}."},
                {error,"Function noexist/1 does_not_exist."}]}

       tpl(Module,MatchSpec)

              Same as tpl({Module, '_', '_'}, MatchSpec)

       tpl(Module,Function,MatchSpec)

              Same as tpl({Module, Function, '_'}, MatchSpec)

       tpl(Module, Function, Arity, MatchSpec)

              Same as tpl({Module, Function, Arity}, MatchSpec)

       tpl({Module,  Function, Arity}, MatchSpec) -> {ok, MatchDesc} | {error,
       term()}

              This function works as tp/2, but enables tracing for local calls
              (and  local  functions)  as  well as for global calls (and func-
              tions).

       tpe(Event, MatchSpec) -> {ok, MatchDesc} | {error, term()}

              Types:

                 Event = send | 'receive'
                 MatchSpec = integer() | Built-inAlias | [] | match_spec()
                 Built-inAlias = x | c | cx
                 MatchDesc = [MatchInfo]
                 MatchInfo = {saved, integer()} | MatchNum
                 MatchNum = {matched, node(), 1} | {matched, node(), 0, RPCEr-
                 ror}

              This  function associates a match specification with trace event
              send or 'receive'. By default all executed  send  and  'receive'
              events  are  traced if enabled for a process. A match specifica-
              tion can be used to filter traced events based  on  sender,  re-
              ceiver and/or message content.

              For a description of the match_spec() syntax, please turn to the
              User's guide part of the online documentation  for  the  runtime
              system  (erts).  The  chapter Match Specifications in Erlang ex-
              plains the general match specification "language".

              For send, the matching is done on the list [Receiver, Msg].  Re-
              ceiver  is  the process or port identity of the receiver and Msg
              is the message term. The pid of the sending process can  be  ac-
              cessed with the guard function self/0.

              For  'receive',  the matching is done on the list [Node, Sender,
              Msg]. Node is the node name of the sender. Sender is the process
              or  port  identity  of  the sender, or the atom undefined if the
              sender is not known (which may be the case for remote  senders).
              Msg is the message term. The pid of the receiving process can be
              accessed with the guard function self/0.

              All nodes added with n/1 or tracer/3 will be  affected  by  this
              call.

              The  return value is the same as for tp/2. The number of matched
              events are never larger than 1 as tpe/2 does not accept any form
              of wildcards for argument Event.

       ctp()

              Same as ctp({'_', '_', '_'})

       ctp(Module)

              Same as ctp({Module, '_', '_'})

       ctp(Module, Function)

              Same as ctp({Module, Function, '_'})

       ctp(Module, Function, Arity)

              Same as ctp({Module, Function, Arity})

       ctp({Module, Function, Arity}) -> {ok, MatchDesc} | {error, term()}

              Types:

                 Module = atom() | '_'
                 Function = atom() | '_'
                 Arity = integer() | '_'
                 MatchDesc = [MatchNum]
                 MatchNum  =  {matched, node(), integer()} | {matched, node(),
                 0, RPCError}

              This function disables call tracing on the specified  functions.
              The  semantics  of  the  parameter is the same as for the corre-
              sponding function specification in tp/2 or tpl/2. Both local and
              global call trace is disabled.

              The  return  value reflects how many functions that matched, and
              is constructed as described in tp/2. No tuple {saved, N} is how-
              ever ever returned (for obvious reasons).

       ctpl()

              Same as ctpl({'_', '_', '_'})

       ctpl(Module)

              Same as ctpl({Module, '_', '_'})

       ctpl(Module, Function)

              Same as ctpl({Module, Function, '_'})

       ctpl(Module, Function, Arity)

              Same as ctpl({Module, Function, Arity})

       ctpl({Module, Function, Arity}) -> {ok, MatchDesc} | {error, term()}

              This  function  works as ctp/1, but only disables tracing set up
              with tpl/2 (not with tp/2).

       ctpg()

              Same as ctpg({'_', '_', '_'})

       ctpg(Module)

              Same as ctpg({Module, '_', '_'})

       ctpg(Module, Function)

              Same as ctpg({Module, Function, '_'})

       ctpg(Module, Function, Arity)

              Same as ctpg({Module, Function, Arity})

       ctpg({Module, Function, Arity}) -> {ok, MatchDesc} | {error, term()}

              This function works as ctp/1, but only disables tracing  set  up
              with tp/2 (not with tpl/2).

       ctpe(Event) -> {ok, MatchDesc} | {error, term()}

              Types:

                 Event = send | 'receive'
                 MatchDesc = [MatchNum]
                 MatchNum = {matched, node(), 1} | {matched, node(), 0, RPCEr-
                 ror}

              This function clears  match  specifications  for  the  specified
              trace  event (send or 'receive'). It will revert back to the de-
              fault behavior of tracing all triggered events.

              The return value follow the same style as for ctp/1.

       ltp() -> ok

              Use this function to recall all match specifications  previously
              used  in  the  session  (i.  e. previously saved during calls to
              tp/2, 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 stop/0 is called.

              Match specifications used can be saved in a  file  (if  a  read-
              write  file  system  is present) for use in later debugging ses-
              sions, see wtp/1 and rtp/1

              There  are  three  built-in  trace  patterns:   exception_trace,
              caller_trace  and caller_exception_trace (or x, c and cx respec-
              tively). 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:

              (x@y)4> dbg:tp(lists,sort,cx).
              {ok,[{matched,nonode@nohost,2},{saved,cx}]}
              (x@y)4> lists:sort([2,1]).
              (<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]

       dtp() -> ok

              Use this function to "forget"  all  match  specifications  saved
              during  calls  to tp/2. This is useful when one wants to restore
              other match specifications from a file with rtp/1. Use dtp/1  to
              delete specific saved match specifications.

       dtp(N) -> ok

              Types:

                 N = integer()

              Use  this  function  to  "forget" a specific match specification
              saved during calls to tp/2.

       wtp(Name) -> ok | {error, IOError}

              Types:

                 Name = string()
                 IOError = term()

              This function will save all match  specifications  saved  during
              the session (during calls to tp/2) and built-in match specifica-
              tions in a text file with the name designated by Name. The  for-
              mat  of  the file is textual, why it can be edited with an ordi-
              nary text editor, and then restored with rtp/1.

              Each match spec in the file ends with a full stop  (.)  and  new
              (syntactically correct) match specifications can be added to the
              file manually.

              The function returns ok or an error tuple where the second  ele-
              ment contains the I/O error that made the writing impossible.

       rtp(Name) -> ok | {error, Error}

              Types:

                 Name = string()
                 Error = term()

              This  function reads match specifications from a file (possibly)
              generated by the wtp/1 function. It checks  the  syntax  of  all
              match specifications and verifies that they are correct. The er-
              ror 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.

              The match specifications in the file are merged with the current
              match specifications, so that no duplicates are  generated.  Use
              ltp/0  to  see  what numbers were assigned to the specifications
              from the file.

              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.

       n(Nodename) -> {ok, Nodename} | {error, Reason}

              Types:

                 Nodename = atom()
                 Reason = term()

              The dbg server keeps a list of nodes  where  tracing  should  be
              performed. Whenever a tp/2 call or a p/2 call is made, it is ex-
              ecuted for all nodes in this list including the local node  (ex-
              cept  for p/2 with a specific pid() or port() as first argument,
              in which case the command is executed only on the node where the
              designated process or port resides).

              This function adds a remote node (Nodename) 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
              no_local_tracer is returned. The tracer  process  on  the  local
              node must be started with the tracer/0/2 function.

              If  Nodename  is  the  local node, the error reason cant_add_lo-
              cal_node is returned.

              If a trace port (see trace_port/2) is running on the local node,
              remote  nodes  cannot be traced with a tracer process. The error
              reason cant_trace_remote_pid_to_local_port is returned. A  trace
              port can however be started on the remote node with the tracer/3
              function.

              The function will also return an error if the node  Nodename  is
              not reachable.

       cn(Nodename) -> ok

              Types:

                 Nodename = atom()

              Clears a node from the list of traced nodes. Subsequent calls to
              tp/2 and p/2 will not consider that node,  but  tracing  already
              activated on the node will continue to be in effect.

              Returns ok, cannot fail.

       ln() -> ok

              Shows the list of traced nodes on the console.

       tracer() -> {ok, pid()} | {error, already_started}

              This function starts a server on the local node that will be the
              recipient of all trace messages. All  subsequent  calls  to  p/2
              will result in messages sent to the newly started trace server.

              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 tracer/2 for a description of how the trace mes-
              sage handler can be customized.

              To start a similar tracer on a remote node, use n/1.

       tracer(Type, Data) -> {ok, pid()} | {error, Error}

              Types:

                 Type = port | process | module
                 Data = PortGenerator | HandlerSpec | ModuleSpec
                 PortGenerator = fun() (no arguments)
                 Error = term()
                 HandlerSpec = {HandlerFun, InitialData}
                 HandlerFun = fun() (two arguments)
                 ModuleSpec = fun() (no arguments)  |  {TracerModule,  Tracer-
                 State}
                 TracerModule = atom()
                 InitialData = TracerState = term()

              This  function starts a tracer server with additional parameters
              on the local node. The first parameter, the Type,  indicates  if
              trace   messages  should  be  handled  by  a  receiving  process
              (process), by a tracer port (port) or by a tracer  module  (mod-
              ule).  For a description about tracer ports see trace_port/2 and
              for a tracer modules see erl_tracer.

              If Type is process, a message handler function can be  specified
              (HandlerSpec).  The handler function, which should be a fun tak-
              ing two arguments, will be called for each trace  message,  with
              the  first argument containing the message as it is and the sec-
              ond argument containing the return value from the  last  invoca-
              tion  of  the  fun. The initial value of the second parameter is
              specified in the InitialData part of the HandlerSpec.  The  Han-
              dlerFun  may choose any appropriate action to take when invoked,
              and can save a state for the next invocation by returning it.

              If Type is port, then the second parameter should be a fun which
              takes  no  arguments  and returns a newly opened trace port when
              called.  Such  a  fun  is  preferably   generated   by   calling
              trace_port/2.

              if  Type is module, then the second parameter should be either a
              tuple describing the erl_tracer module to be  used  for  tracing
              and the state to be used for that tracer module or a fun return-
              ing the same tuple.

              If an error is returned, it can either be due to a tracer server
              already running ({error,already_started}) or due to the Handler-
              Fun throwing an exception.

              To start a similar tracer on a remote node, use tracer/3.

       tracer(Nodename, Type, Data) -> {ok, Nodename} | {error, Reason}

              Types:

                 Nodename = atom()

              This function is equivalent to tracer/2, but acts on  the  given
              node. A tracer is started on the node (Nodename) and the node is
              added to the list of traced nodes.

          Note:
              This function is not equivalent  to  n/1.  While  n/1  starts  a
              process  tracer  which  redirects  all  trace  information  to a
              process tracer on the local node (i.e. the trace control  node),
              tracer/3 starts a tracer of any type which is independent of the
              tracer on the trace control node.

              For details, see tracer/2.

       trace_port(Type, Parameters) -> fun()

              Types:

                 Type = ip | file
                 Parameters = Filename | WrapFilesSpec | IPPortSpec
                 Filename = string() | [string()] | atom()
                 WrapFilesSpec = {Filename, wrap, Suffix} |  {Filename,  wrap,
                 Suffix,   WrapSize}  |  {Filename,  wrap,  Suffix,  WrapSize,
                 WrapCnt}
                 Suffix = string()
                 WrapSize = integer() >= 0 | {time, WrapTime}
                 WrapTime = integer() >= 1
                 WrapCnt = integer() >= 1
                 IpPortSpec = PortNumber | {PortNumber, QueSize}
                 PortNumber = integer()
                 QueSize = integer()

              This function creates a trace port generating fun. The fun 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. dbg:tracer(port, dbg:trace_port(ip, 4711)).

              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.

              Two trace drivers are currently implemented, the file and the ip
              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 trace_client/2 function.  The  ip  driver
              opens  a  TCP/IP  port  where it listens for connections. When a
              client (preferably started by calling trace_client/2 on  another
              Erlang  node)  connects, all trace messages are sent over the IP
              network for further processing by the remote client.

              Using a trace port significantly lowers the overhead imposed  by
              using tracing.

              The  file trace driver expects a filename or a wrap files speci-
              fication as parameter. A file is written with a high  degree  of
              buffering, why all trace messages are not guaranteed to be saved
              in the file in case of a system crash. That is the price to  pay
              for low tracing overhead.

              A  wrap files specification is used to limit the disk space con-
              sumed by the trace. The trace is written to a limited number  of
              files  each  with a limited size. The actual filenames are File-
              name ++ SeqCnt ++ Suffix,  where  SeqCnt  counts  as  a  decimal
              string  from  0  to WrapCnt and then around again from 0. When a
              trace term written to the current  file  makes  it  longer  than
              WrapSize,  that  file  is closed, if the number of files in this
              wrap trace is as many as WrapCnt 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  WrapCnt  trace  files
              saved  with  a  size of at least WrapSize (but not much bigger),
              except for the last file that might even be empty.  The  default
              values are WrapSize = 128*1024 and WrapCnt = 8.

              The  SeqCnt  values  in  the  filenames  are  all in the range 0
              through WrapCnt with a gap in the circular sequence. The gap  is
              needed to find the end of the trace.

              If  the  WrapSize  is specified as {time, WrapTime}, the current
              file is closed when it has been open  more  than  WrapTime  mil-
              liseconds, regardless of it being empty or not.

              The  ip  trace driver has a queue of QueSize 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
              trace_client/3 as the tuple {drop, N} where N 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 read-
              ing the trace messages. The default value of QueSize is 200.

       flush_trace_port()

              Equivalent to flush_trace_port(node()).

       flush_trace_port(Nodename) -> ok | {error, Reason}

              Equivalent to trace_port_control(Nodename,flush).

       trace_port_control(Operation)

              Equivalent to trace_port_control(node(),Operation).

       trace_port_control(Nodename,Operation)  ->  ok | {ok, Result} | {error,
       Reason}

              Types:

                 Nodename = atom()

              This function is used to do a control operation  on  the  active
              trace port driver on the given node (Nodename). Which operations
              are allowed as well as their return values depend on which trace
              driver is used.

              Returns  either ok or {ok, Result} if the operation was success-
              ful, or {error, Reason} if the current tracer is a process or if
              it is a port not supporting the operation.

              The allowed values for Operation are:

                flush:
                  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 ok.

                get_listen_port:
                  Returns {ok, IpPort} where IpPort is the IP port number used
                  by the driver listen socket. Only the ip trace  driver  sup-
                  ports this operation.

       trace_client(Type, Parameters) -> pid()

              Types:

                 Type = ip | file | follow_file
                 Parameters = Filename | WrapFilesSpec | IPClientPortSpec
                 Filename = string() | [string()] | atom()
                 WrapFilesSpec = see trace_port/2
                 Suffix = string()
                 IpClientPortSpec = PortNumber | {Hostname, PortNumber}
                 PortNumber = integer()
                 Hostname = string()

              This  function  starts a trace client that reads the output cre-
              ated by a trace port driver and handles it in  mostly  the  same
              way as a tracer process created by the tracer/0 function.

              If  Type  is file, the client reads all trace messages stored in
              the file named Filename or specified by WrapFilesSpec  (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.

              If Type is follow_file, the client behaves as in the file  case,
              but  keeps  trying to read (and process) more data from the file
              until stopped by stop_trace_client/1. WrapFilesSpec is  not  al-
              lowed as second argument for this Type.

              If Type is ip, the client connects to the TCP/IP port PortNumber
              on the host Hostname, from where it reads trace  messages  until
              the  TCP/IP  connection  is closed. If no Hostname is specified,
              the local host is assumed.

              As an example, one can let trace messages be sent over the  net-
              work  to another Erlang node (preferably not distributed), where
              the formatting occurs:

              On the node stack there's  an  Erlang  node  ant@stack,  in  the
              shell, type the following:

              ant@stack> dbg:tracer(port, dbg:trace_port(ip,4711)).
              <0.17.0>
              ant@stack> dbg:p(self(), send).
              {ok,1}

              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:

              -> dbg:trace_client(ip, {"stack", 4711}).
              <0.42.0>

              If we now send a message from the shell on the  node  ant@stack,
              where all sends from the shell are traced:

              ant@stack> self() ! hello.
              hello

              The  following  will  appear  at  the  console  on the node that
              started the trace client:

              (<0.23.0>) <0.23.0> ! hello
              (<0.23.0>) <0.22.0> ! {shell_rep,<0.23.0>,{value,hello,[],[]}}

              The last line is generated due to internal  message  passing  in
              the Erlang shell. The process id's will vary.

       trace_client(Type, Parameters, HandlerSpec) -> pid()

              Types:

                 Type = ip | file | follow_file
                 Parameters = Filename | WrapFilesSpec | IPClientPortSpec
                 Filename = string() | [string()] | atom()
                 WrapFilesSpec = see trace_port/2
                 Suffix = string()
                 IpClientPortSpec = PortNumber | {Hostname, PortNumber}
                 PortNumber = integer()
                 Hostname = string()
                 HandlerSpec = {HandlerFun, InitialData}
                 HandlerFun = fun() (two arguments)
                 InitialData = term()

              This function works exactly as trace_client/2, but allows you to
              write your own handler  function.  The  handler  function  works
              mostly  as  the one described in tracer/2, but will also have to
              be prepared to handle trace messages  of  the  form  {drop,  N},
              where  N  is  the  number of dropped messages. This pseudo trace
              message will only occur if the ip trace driver is used.

              For trace type file, the pseudo trace message end_of_trace  will
              appear  at  the end of the trace. The return value from the han-
              dler function is in this case ignored.

       stop_trace_client(Pid) -> ok

              Types:

                 Pid = pid()

              This function shuts down a previously started trace client.  The
              Pid  argument is the process id returned from the trace_client/2
              or trace_client/3 call.

       get_tracer()

              Equivalent to get_tracer(node()).

       get_tracer(Nodename) -> {ok, Tracer}

              Types:

                 Nodename = atom()
                 Tracer = port() | pid() | {module(), term()}

              Returns the process, port or tracer module to  which  all  trace
              messages are sent.

       stop() -> ok

              Stops  the  dbg  server  and clears all trace flags for all pro-
              cesses and all local trace  patterns  for  all  functions.  Also
              shuts down all trace clients and closes all trace ports.

              Note  that  no  global trace patterns are affected by this func-
              tion.

       stop_clear() -> ok

              Same as stop/0, but also clears all  trace  patterns  on  global
              functions calls.

SIMPLE EXAMPLES - TRACING FROM THE SHELL
       The  simplest way of tracing from the Erlang shell is to use dbg:c/3 or
       dbg:c/4, e.g. tracing the function dbg:get_tracer/0:

       (tiger@durin)84> dbg:c(dbg,get_tracer,[]).
       (<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>

       Another way of tracing from the shell is to explicitly start  a  tracer
       and  then  set the trace flags of your choice on the processes you want
       to trace, e.g. trace messages and process events:

       (tiger@durin)66> Pid = spawn(fun() -> receive {From,Msg} -> From ! Msg end end).
       <0.126.0>
       (tiger@durin)67> dbg:tracer().
       {ok,<0.128.0>}
       (tiger@durin)68> dbg:p(Pid,[m,procs]).
       {ok,[{matched,tiger@durin,1}]}
       (tiger@durin)69> Pid ! {self(),hello}.
       (<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> flush().
       Shell got hello
       ok
       (tiger@durin)71>

       If you set the call trace flag, you also have to set  a  trace  pattern
       for the functions you want to trace:

       (tiger@durin)77> dbg:tracer().
       {ok,<0.142.0>}
       (tiger@durin)78> dbg:p(all,call).
       {ok,[{matched,tiger@durin,3}]}
       (tiger@durin)79> dbg:tp(dbg,get_tracer,0,[]).
       {ok,[{matched,tiger@durin,1}]}
       (tiger@durin)80> dbg:get_tracer().
       (<0.116.0>) call dbg:get_tracer()
       {ok,<0.143.0>}
       (tiger@durin)81> dbg:tp(dbg,get_tracer,0,[{'_',[],[{return_trace}]}]).
       {ok,[{matched,tiger@durin,1},{saved,1}]}
       (tiger@durin)82> dbg:get_tracer().
       (<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>

ADVANCED TOPICS - COMBINING WITH SEQ_TRACE
       The  dbg  module  is primarily targeted towards tracing through the er-
       lang:trace/3 function. It is sometimes desired to trace messages  in  a
       more  delicate  way,  which  can be done with the help of the seq_trace
       module.

       seq_trace implements sequential tracing (known in the AXE10 world,  and
       sometimes  called "forlopp tracing"). dbg can interpret messages gener-
       ated from seq_trace and the same tracer  function  for  both  types  of
       tracing can be used. The seq_trace messages can even be sent to a trace
       port for further analysis.

       As a match specification can turn on sequential tracing,  the  combina-
       tion  of  dbg  and  seq_trace can be quite powerful. This brief example
       shows a session where sequential tracing is used:

       1> dbg:tracer().
       {ok,<0.30.0>}
       2> {ok, Tracer} = dbg:get_tracer().
       {ok,<0.31.0>}
       3> seq_trace:set_system_tracer(Tracer).
       false
       4> dbg:tp(dbg, get_tracer, 0, [{[],[],[{set_seq_token, send, true}]}]).
       {ok,[{matched,nonode@nohost,1},{saved,1}]}
       5> dbg:p(all,call).
       {ok,[{matched,nonode@nohost,22}]}
       6> dbg:get_tracer(), seq_trace:set_token([]).
       (<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}

       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 dbg:get_tracer to one that has the action of setting a sequen-
       tial  token.  When the function is called by a traced process (all pro-
       cesses are traced in this case), the process gets "contaminated" by the
       token  and  seq_trace messages are sent both for the server request and
       the response. The seq_trace:set_token([]) after  the  call  clears  the
       seq_trace  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.

NOTE OF CAUTION
       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 io function such as format/2. Note that  when  dbg:p(all,call)
       is called, IO processes are also traced. Here's an example:

       %% Using a default line editing shell
       1> dbg:tracer(process, {fun(Msg,_) -> io:format("~p~n", [Msg]), 0 end, 0}).
       {ok,<0.37.0>}
       2> dbg:p(all, [call]).
       {ok,[{matched,nonode@nohost,25}]}
       3> dbg:tp(mymod,[{'_',[],[]}]).
       {ok,[{matched,nonode@nohost,0},{saved,1}]}
       4> mymod: % TAB pressed here
       %% -- Deadlock --

       Here's another example:

       %% Using a shell without line editing (oldshell)
       1> dbg:tracer(process).
       {ok,<0.31.0>}
       2> dbg:p(all, [call]).
       {ok,[{matched,nonode@nohost,25}]}
       3> dbg:tp(lists,[{'_',[],[]}]).
       {ok,[{matched,nonode@nohost,0},{saved,1}]}
       % -- Deadlock --

       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 mymod:module_info(). This generates a trace mes-
       sage which, in turn, causes the tracer process to send an IO request to
       the group leader (by calling io:format/2). We end up in a deadlock.

       In  the  second example we use the default trace handler function. This
       handler prints to tty by sending IO requests to the user process.  When
       Erlang is started in oldshell mode, the shell process will have user as
       its group leader and so will the tracer process in this example.  Since
       user  calls  functions  in lists we end up in a deadlock as soon as the
       first IO request is sent.

       Here are a few suggestions for how to avoid deadlock:

         * Don't trace the group leader of the tracer process. If tracing  has
           been  switched  on for all processes, call dbg:p(TracerGLPid,clear)
           to stop tracing the group leader (TracerGLPid).  process_info(Trac-
           erPid,group_leader)  tells  you which process this is (TracerPid is
           returned from dbg:get_tracer/0).

         * Don't trace the user process if using  the  default  trace  handler
           function.

         * In  your  own trace handler function, call erlang:display/1 instead
           of an io function or, if user is not used as group leader, print to
           user   instead  of  the  default  group  leader.  Example:  io:for-
           mat(user,Str,Args).

Ericsson AB                   runtime_tools 1.15                     dbg(3erl)

Man(1) output converted with man2html
list of all man pages