Home Man
Today's Posts

Linux & Unix Commands - Search Man Pages
Man Page or Keyword Search:
Select Section of Man Page:
Select Man Page Repository:

Linux 2.6 - man page for dbg (linux section 3erl)

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

       dbg - The Text Based Trace Facility

       This module implements a text based interface to the trace/3 and the trace_pattern/2 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 pman module.

       For some examples of how to use dbg from the Erlang shell, see the simple example section.

       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  sequen-
       tial tracing is also included, see the advanced topics section.

       fun2ms(LiteralFun) -> MatchSpec

	      Types  LiteralFun = fun() literal
		     MatchSpec = term()

	      Pseudo  function	that  by  means of a parse_transform translates the literal fun()
	      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. Fail-
	      ing  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 parameter (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.


	      1> dbg:fun2ms(fun([M,N]) when N > 3 -> return_trace() end).

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

	      2> X=3.
	      3> dbg:fun2ms(fun([M,N]) when N > X -> return_trace() end).

	      The  imported  variables will be replaced by match_spec const expressions, which is
	      consistent with the static scoping for Erlang fun() 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:

	      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
	      5> dbg:fun2ms(fun([M,N]) when N > X, is_atom(M) -> return_trace() end).

	      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_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).

       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 replaced
       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:

		* If  the  Item is a pid() , 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 ( see n/1 and tracer/0/2/3 ).

		* If  the  Item is the atom all , all processes in the system as well as all pro-
		  cesses created hereafter are to be traced. This also affects	all  nodes  added
		  with the n/1 or tracer/0/2/3 function.

		* If the Item is the atom new , no currently existing processes are affected, but
		  every process created after the call is.This also affects all nodes added  with
		  the n/1 or tracer/0/2/3 function.

		* If  the  Item is the atom existing , all existing processes are traced, but new
		  processes will not be affected.This also affects all nodes added with  the  n/1
		  or tracer/0/2/3 function.

		* If  the Item is an atom other than all , new or existing , 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 n/1 or tracer/0/2/3 func-

		* If the Item is an integer, the process <0.Item.0> is traced.

		* If the Item is a tuple {X, Y, Z} , the process <X.Y.Z> is traced.

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

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

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

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

		m (messages) :
		  Traces the messages the process 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.

		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 when-
		  ever 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

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

		all :
		  Sets all flags.

		clear :
		  Clears all flags.

	      The list can also include any of the flags allowed in erlang:trace/3

	      The function returns either an error tuple or a tuple {ok, List} .  The  List  con-
	      sists  of  specifications of how many processes 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.


	      Same as tp({Module, '_', '_'}, 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() | atom() | [] | match_spec()
		     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}  argument  will  be  concerned,  but  the
	      match_spec()  may  further  narrow  down the set of function calls generating trace

	      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
	      Specification in Erlang explains the general match specification "language".

	      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/0/2/3 will be affected by this call, and if Mod-
	      ule is not '_' the module will be loaded on all nodes.

	      The function returns either an error tuple or a tuple {ok, List} .  The  List  con-
	      sists  of specifications of how many functions that matched, in the same way as the
	      processes 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 built-in aliases named
	      with atoms (see also ltp/0 below).

	      If an error is returned, it can be due to errors in compilation of the match speci-
	      fication. Such errors are presented as a list of tuples {error, string()} where the
	      string is a textual explanation of the compilation error. An example:

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


	      Same as tpl({Module, '_', '_'}, 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 func-
	      tions) as well as for global calls (and functions).


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


	      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 corresponding 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 however ever returned (for obvious rea-


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


	      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 ).


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


	      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 ).

       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 sessions, see wtp/1 and rtp/1

       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 specifications in a text file with the name des-
	      ignated  by  Name . The format of the file is textual, why it can be edited with an
	      ordinary text editor, and then restored with rtp/1 .

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

	      The function returns ok or an error tuple where the second element 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 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.

	      The match specifications in the file are merged with the current	match  specifica-
	      tions,  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 executed for all nodes in this list  includ-
	      ing  the	local  node  (except  for p/2 with a specific pid() as first argument, in
	      which case the command is executed only on the node where  the  designated  process

	      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

	      If Nodename is the local node, the error reason cant_add_local_node is returned.

	      If a trace port ( see trace_port/2 ) is running on the local node, remote nodes can
	      not     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 for-
	      matted way in the Erlang shell (i. e. use io:format). See tracer/2 for  a  descrip-
	      tion of how the trace message 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
		     Data = PortGenerator | HandlerSpec
		     HandlerSpec = {HandlerFun, InitialData}
		     HandlerFun = fun() (two arguments)
		     InitialData = term()
		     PortGenerator = fun() (no arguments)
		     Error = 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 ) or by a tracer port ( port ). For a description about
	      tracer ports see trace_port/2 .

	      If Type is a process, a message handler function can be specified ( HandlerSpec  ).
	      The  handler  function,  which should be a fun 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 InitialData part
	      of  the  HandlerSpec . The HandlerFun may chose any appropriate action to take when
	      invoked, and can save a state for the next invocation by returning it.

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

	      If an error is returned, it can either be due to a tracer server already running	(
	      {error,already_started} ) or due to the HandlerFun 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.

       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  con-
       trol 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, Wrap-
		     Size} | {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 (prefer-
	      ably  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 specification  as  parame-
	      ter.  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 consumed by the trace.
	      The trace is written to a limited number of files each with  a  limited  size.  The
	      actual  filenames are Filename ++ SeqCnt ++ Suffix , where SeqCnt counts as a deci-
	      mal string from 0 to WrapCnt and then around again from 0 . When a trace term writ-
	      ten 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  Wrap-
	      Size  (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 milliseconds, regardless of it being	empty  or

	      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
	      reading the trace messages.


	      Equivalent to flush_trace_port(node()) .

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

	      Equivalent to trace_port_control(Nodename,flush) .


	      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 that are allowed  as  well	as  their
	      return values are depending on which trace driver that is used.

	      Returns  either ok or {ok, Result} if the operation was successful, or {error, Rea-
	      son} if the current tracer is a process or if it is a port not supporting the oper-

	      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 lis-
		  ten socket. Only the ip trace driver supports 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 created 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 allowed as second argument for this Type .

	      If Type is ip , the client connects to the TCP/IP port PortNumber on the host Host-
	      name , 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  network  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 follow-

	      ant@stack> dbg:tracer(port, dbg:trace_port(ip,4711)).
	      ant@stack> dbg:p(self(), send).

	      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}).

	      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.

	      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 handler 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.


	      Equivalent to get_tracer(node()) .

       get_tracer(Nodename) -> {ok, Tracer}

	      Types  Nodename = atom()
		     Tracer = port() | pid()

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

       stop() -> stopped

	      Stops the dbg 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

	      Note that no trace patterns are affected by this function.

       stop_clear() -> stopped

	      Same as stop/0, but also clears all trace patterns on local  and	global	functions

       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

       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).
       (tiger@durin)67> dbg:tracer().
       (tiger@durin)68> dbg:p(Pid,[m,procs]).
       (tiger@durin)69> Pid ! {self(),hello}.
       (<0.126.0>) << {<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

       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().
       (tiger@durin)78> dbg:p(all,call).
       (tiger@durin)79> dbg:tp(dbg,get_tracer,0,[]).
       (tiger@durin)80> dbg:get_tracer().
       (<0.116.0>) call dbg:get_tracer()
       (tiger@durin)81> dbg:tp(dbg,get_tracer,0,[{'_',[],[{return_trace}]}]).
       (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>}

       The  dbg module is primarily targeted towards tracing through the erlang: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  generated  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	combination  of  dbg  and
       seq_trace can be quite powerful. This brief example shows a session where sequential trac-
       ing is used:

       1> dbg:tracer().
       2> {ok, Tracer} = dbg:get_tracer().
       3> seq_trace:set_system_tracer(Tracer).
       4> dbg:tp(dbg, get_tracer, 0, [{[],[],[{set_seq_token, send, true}]}]).
       5> dbg:p(all,call).
       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}]

       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 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
       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 other-
       wise have been more noisy.

       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}).
       2> dbg:p(all, [call]).
       3> dbg:tp(mymod,[{'_',[],[]}]).
       4> mymod:  % TAB pressed here
       %% -- Deadlock --

       Here's another example:

       %% Using a shell without line editing (oldshell)
       1> dbg:tracer(process).
       2> dbg:p(all, [call]).
       3> dbg:tp(lists,[{'_',[],[]}]).
       % -- 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:mod-
       ule_info() . This generates a trace message 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(TracerPid,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:format(user,Str,Args) .

Ericsson AB			       runtime_tools 1.8.5				dbg(3erl)

All times are GMT -4. The time now is 01:54 AM.

Unix & Linux Forums Content Copyrightę1993-2018. All Rights Reserved.
Show Password