View Source edbg_tracer (edbg v0.9.1)

The edbg tracer.

The function edbg:fstart/2 takes one argument containing the list of modules we want to trace, and a second argument containing various options. The trace output will be stored on file.

So in the example below we want to trace on three modules: yaws_server, yaws, yaws_config, from the Yaws webserver. With the max_msgs option we restrict the allowed number of trace messages to 10000.

    1> edbg:fstart([yaws_server,yaws,yaws_config],[{max_msgs,10000}]).
    ok

Now run some traffic toward yaws and when done, stop the tracing:

     2> edbg:fstop().
     ok

Here we rely on using the default filename for storing the trace output, hence we don't have to specify it here when loading the trace info to be displayed.

    3> edbg:file().
  
    (h)elp (a)t [<N>] (d)own (u)p (t)op (b)ottom
    (s)how <N> [<ArgN>] (r)etval <N> ra(w) <N>
    (pr)etty print record <N> <ArgN>
    (f)ind <RegExp> [<ArgN> <ArgRegExp>] | ~r<RegExp>
    (on)/(off) send_receive | memory
    (p)agesize <N> (q)uit
    (set) <Var> <N> [<ArgN>]  (let) <Var> <Expr>
    (eval) <Expr>  (xall/xnall) <Mod>

As can be seen, we first get a compact help text showing what commands we can use. Then follows the beginning of the trace output. Each line is prefixed with a number that we use for reference. The indentation shows the depth of the call chain.

     0: <0.255.0> yaws_server:gserv_loop/4
     1:  <0.258.0> yaws_server:gserv_loop/4
     2:   <0.233.0> yaws:month/1
     4:   <0.259.0> yaws_server:peername/2
     6:   <0.258.0> yaws_server:close_accepted_if_max/2
     8:   <0.258.0> yaws_server:acceptor/1
    10:   <0.258.0> yaws_server:gserv_loop/4
    11:    <0.281.0> yaws_server:acceptor0/2
    12:     <0.281.0> yaws_server:do_accept/1
      ...snip...

As you can see, we get a pretty output where we can follow the chain of execution without drowning in output which would be the case if we should have displayed the contents of all the arguments to the functions.

Instead, we can now inspect a particular call of interest, let's say line 4; we use the (s)how command to display the function clause heads in order to help us decide which argument to inspect.

     tlist> s 4
  
      Call: yaws_server:peername/2
      -----------------------------------
  
      peername(CliSock, ssl) ->
  
      peername(CliSock, nossl) ->
  
      -----------------------------------

To show what the second argument contained, we add 2 to the show command:

    tlist> s 4 2
  
    Call: yaws_server:peername/2 , argument 2:
    -----------------------------------
    nossl

We can also see what the function returned:

    tlist> r 4
  
    Call: yaws_server:peername/2 , return value:
    -----------------------------------
    {{127,0,0,1},35871}

To display (again) the function call chain, you use the a(t) command. With no arguments it will just re-display the trace output. If you want to go to a particular line you just give that as an argument. Example, go to line 10 in the example above:

     tlist> a 10
     10:   <0.258.0> yaws_server:gserv_loop/4
     11:    <0.281.0> yaws_server:acceptor0/2
     12:     <0.281.0> yaws_server:do_accept/1
     13:      <0.259.0> yaws_server:aloop/4
      ...snip...

To change the number of lines shown of the trace output. Set it with the p(age) command. Example, display (roughly) 50 lines:

    tlist> p 50

The amount of trace output can be huge so we can search for a particular function call that we are interested in. Note that you can specify a RegExp for searching among the Mod:Fun calls.

     tlist> f yaws:decode_b
     32:           <0.537.0> yaws:decode_base64/1
     33:            <0.537.0> yaws:decode_base64/2
     34:             <0.537.0> yaws:d/1
      ...snip...

We can also search in a particular argument of a particular function call. Here the second argument of yaws:setopts should contain the string: 'packet_size':

     tlist> f yaws:setopts 2 packet_size
     22:         <0.537.0> yaws:setopts/3
     24:         <0.537.0> yaws:do_recv/3
     26:         <0.537.0> yaws:http_collect_headers/5
      ...snip...

We can now verify that it found it:

     tlist> s 22 2
  
     Call: yaws:setopts/3 , argument 2:
     -----------------------------------
     [{packet,httph},{packet_size,16384}]

To search among the return values we prefix our search string with a ~r sigil:

     tlist> f ~rGET
     184:           <0.537.0> yaws:make_allow_header/1
     187:          <0.537.0> yaws_server:deliver_accumulated/1
     188:           <0.537.0> yaws:outh_get_content_encoding/0
     190:           <0.537.0> yaws:outh_set_content_encoding/1
      ...snip...

We can now verify that it found it:

     tlist> r 184
  
     Call: yaws:make_allow_header/1 , return value:
     -----------------------------------
     ["Allow: GET, POST, OPTIONS, HEAD\r\n"]
To see more examples visit the edbg wiki at: https://github.com/etnt/edbg/wiki/Tracing