Skip to content

dbg module

Serge edited this page Oct 11, 2021 · 10 revisions

using dbg module

basic principles

The same information needs to be provided:

  • prepare the tracer/receiver
  • where to trace? ** all processes ** a particular process
  • what action to trace
    • all actions
    • call a function
    • send a message
    • ... etc
  • what Module, function, arity to trace?
  • what function arguments to trace?

prepare the receiver.

The dbg module has its own receiver, so there is no need to provide one or refer to it later:

    dbg:tracer().

specify the processes and actions:

    dbg:p(
       all,   %% all processes
         c    %% c for function calls
       ).

specify module and function:

   dbg:tpl(math,   %% module math
            sin,   %% function sim
              1,   %% taking a single argument
              x)   %% x will trace the return value

which arguments we are interested in tracing - match spec

The helper function dbg:fun2ms gives us the match spec. What if we want to trace only Pi = 3.14 as sin argument?

   Ms = dbg:fun2ms(fun([X]) when X == 3.14 -> return_trace() end).
   dbg:tpl(math,   %% module math
            sin,   %% function sim
              1,   %% taking a single argument
              Ms)   %% x will trace the return value

how to stop tracing and clear tracing setup:

   dbg:stop_clear().

Example 1. Trace all actions in a process Pid

   > dbg:tracer().
   ...
   > Pid = spawn(fun() -> receive X ->io:format("received: ~p~n",[X]) end).
<0.159.0>
   > dbg:p(Pid, all).
   ...
   > Pid ! msg.
received: msg
(<0.159.0>) in {prim_eval,'receive',2} (Timestamp: {1633,153915,892027})
(<0.159.0>) << msg (Timestamp: {1633,153915,892028})
msg
... skipped a whole bunch of tracing 
(<0.159.0>) out_exited 0 (Timestamp: {1633,153915,892034})

   >dbg:stop_clear().

Example 2. Trace function call math:sin for all processes

only the input is shown

   dbg:tracer().
   dbg:p(all,c).
   dbg:tpl(math, sin, 1, x).
   math:sin(1).
   ...

   dbg:stop_clear().

Example 3. Trace function call math:sin for all processes with the argument 3.14

the whole shell session is shown

   > dbg:tracer().
{ok,<0.150.0>}

   > dbg:p(all,c).
{ok,[{matched,nonode@nohost,44}]}

   > Ms = dbg:fun2ms(fun([X]) when X == 3.14 -> return_trace() end).
[{['$1'],[{'==','$1',3.14}],[{return_trace}]}]

   > dbg:tpl(math, sin, 1, Ms).
{ok,[{matched,nonode@nohost,1},{saved,1}]}

   > math:sin(1).   %% no trace
0.8414709848078965

   > math:sin(3.14). %% there will be trace
(<0.104.0>) call math:sin(3.14)
(<0.104.0>) returned from math:sin/1 -> 0.0015926529164868282
0.0015926529164868282

   dbg:stop_clear().

Example 4. Trace all calls in a module.

assuming a module an_app.erl:

-module(an_app).
-vsn(66).
-export([start/0,f1/1,sin/1,loop/0]).

start() ->
    spawn(?MODULE,loop,[]).
    
loop() ->
    receive
        {From,X} -> 
            From ! ?MODULE:f1(X);
        _ ->
            ok
    end,
    ?MODULE:loop().

f1(X) ->
    f2(X).    %% a local call to f2
    
f2(X) ->
    sin(X).   %% a local call to sin
    
sin(X) ->
    math:sin(X).    

The shell commands...

c(an_app).
S = an_app:start().
dbg:tracer().
dbg:tpl(an_app,'_',x). % trace all functions of an_app, with return_value 
dbg:p(all, c). % trace all processes, calls only
dbg:p(S).      % trace all messages sent and received by S
S ! {self(),1.57}.
flush().
an_app:f1(1.57).

... And their action

Erlang/OTP 24 [erts-12.0] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit]

Eshell V12.0  (abort with ^G)
1> c(an_app).
Recompiling d:/src/erlang/ja/stickynotes_big/src/an_app.erl
{ok,an_app}
2> 
2> S = an_app:start().
<0.86.0>
3> 
3> dbg:tracer().
{ok,<0.88.0>}
4> 
4> dbg:tpl(an_app,'_',x). % trace all functions of an_app, with return_value 
{ok,[{matched,nonode@nohost,7},{saved,x}]}
5> % trace all functions of an_app, with return_value 
5> 
5> dbg:p(all, c). % trace all processes, calls only
{ok,[{matched,nonode@nohost,43}]}
6> % trace all processes, calls only
6> 
6> dbg:p(S).      % trace all messages sent and received by S
{ok,[{matched,nonode@nohost,1}]}
7>      % trace all messages sent and received by S
7> 
7> S ! {self(),1.57}.
(<0.86.0>) << {<0.79.0>,1.57}
{<0.79.0>,1.57}
(<0.86.0>) call an_app:f1(1.57)
8> 
8> (<0.86.0>) call an_app:f2(1.57)
(<0.86.0>) call an_app:sin(1.57)
(<0.86.0>) returned from an_app:sin/1 -> 0.9999996829318346
(<0.86.0>) returned from an_app:f2/1 -> 0.9999996829318346
(<0.86.0>) returned from an_app:f1/1 -> 0.9999996829318346
(<0.86.0>) <0.79.0> ! 0.9999996829318346
(<0.86.0>) call an_app:loop()
flush().
Shell got 0.9999996829318346
ok
9> 
9> an_app:f1(1.57).
(<0.79.0>) call an_app:f1(1.57)
(<0.79.0>) call an_app:f2(1.57)
(<0.79.0>) call an_app:sin(1.57)
(<0.79.0>) returned from an_app:sin/1 -> 0.9999996829318346
(<0.79.0>) returned from an_app:f2/1 -> 0.9999996829318346
(<0.79.0>) returned from an_app:f1/1 -> 0.9999996829318346
0.9999996829318346
10> 

Clone this wiki locally