Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
dbg(3)			   Erlang Module Definition			dbg(3)

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

	      h	stands for help. Gives a list of items for brief online	help.

       h(Item) -> ok

	      Types:

		 Item =	atom()

	      h	stands for help. 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()

	      p	stands for process. 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)

	      c	 stands	 for  call.  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

	      i	 stands	for information. 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}

	      tp stands	for trace pattern. 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 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()}

	      tpl stands for trace pattern local. This function	works as tp/2,
	      but  enables  tracing  for  local	calls (and local functions) as
	      well as for global calls (and functions).

       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}

	      tpe  stands  for trace pattern event. This function associates a
	      match specification with trace event send	or 'receive'.  By  de-
	      fault  all  executed send	and 'receive' events are traced	if en-
	      abled for	a process. A match specification can be	used to	filter
	      traced events based on sender, receiver 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}

	      ctp stands for clear trace pattern. This function	disables  call
	      tracing on the specified functions. The semantics	of the parame-
	      ter 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 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()}

	      ctpl  stands  for	clear trace pattern local. 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()}

	      ctpg  stands for clear trace pattern global. 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}

	      ctpe stands for clear trace pattern event. This function	clears
	      match specifications for the specified trace event (send or 're-
	      ceive'). It will revert back to the default behavior of  tracing
	      all triggered events.

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

       ltp() ->	ok

	      ltp  stands for list trace patterns. 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	speci-
	      fications. 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

	      dtp stands for delete trace patterns. Use	this function to "for-
	      get"  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()

	      dtp stands for delete trace pattern. Use this function to	 "for-
	      get" a specific match specification saved	during calls to	tp/2.

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

	      Types:

		 Name =	string()
		 IOError = term()

	      wtp stands for write trace patterns. 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 designated 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 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()

	      rtp  stands  for	read trace patterns. 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 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()

	      n	stands for node. 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 including the
	      local  node  (except  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()

	      cn  stands for clear node. 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

	      ln stands	for list nodes.	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.17			dbg(3)

NAME | DESCRIPTION | EXPORTS | SIMPLE EXAMPLES - TRACING FROM THE SHELL | ADVANCED TOPICS - COMBINING WITH SEQ_TRACE | NOTE OF CAUTION

Want to link to this manual page? Use this URL:
<https://www.freebsd.org/cgi/man.cgi?query=dbg&sektion=3&manpath=FreeBSD+13.0-RELEASE+and+Ports>

home | help