[erlang-questions] Erlang tracing

Lukas Larsson lukas@REDACTED
Fri Sep 25 11:38:01 CEST 2015


Hello,

On Thu, Sep 24, 2015 at 11:58 PM, Philip Clarke <send2philip@REDACTED>
wrote:

> One common use case for tracing I would like is the ability to trace a
> function call for just the next request in the system.
>
> Currently the PidSpec in erlang:trace/3 allows for pid, existing, new or
> all.
>
> We would use pid if we knew the pid of the next short lived process to
> call a function (but we don't).
> We cannot use new either as tracing a function call for all new processes
> might mean that this function is traced 1000s times per second.
>
> What I would like is some new PidSpec like 'next_pid' which would specify
> that I want to trace all new processes until the function call I am tracing
> has been triggered.  Once the trace is triggered then it should turn off
> tracing on all processes.
>
> e.g.
> dbg:p(next_pid, call).
> dbg:tp(M, F, x).
>
> This would be a great help in my work where quite often I want to see the
> typical format of a request from a client and just capturing 1 request is
> enough.  I believe that libraries such as redbug have this kind of ability,
> but perhaps the feature is fundamental enough to include as part of trace ?
>
>
Doing this kind of thing and guaranteeing that just one trace will be
printed cannot be done without suspending all schedulers running in the
system, which is something that I'm pretty sure you do not want :) You can
however come pretty close even today by doing something like this:

-module(single_trace).

-export([trace/2,trace/4]).

trace(M,F) ->
    trace(M,F,'_',[]).
trace(M,F,A,MS) ->
    DisableTrace = {'_',[],[{disable_trace,[call]}]},
    erlang:trace_pattern({M,F,A}, [ DisableTrace | MS], []),
    Tracer = spawn(fun trace_loop/0),
    erlang:trace(all, true, [{tracer, Tracer}, call]).

trace_loop() ->
    receive
        Msg ->
            io:format("~p~n",[Msg]),
            erlang:trace(all, false, [call]),
            trace_loop()
    end.

12> spawn(fun F() -> lists:map(fun(I) -> I + 1 end, lists:seq(1,100)), F()
end).
<0.53.0>
13> spawn(fun F() -> lists:map(fun(I) -> I + 1 end, lists:seq(1,100)), F()
end).
<0.55.0>
14> spawn(fun F() -> lists:map(fun(I) -> I + 1 end, lists:seq(1,100)), F()
end).
<0.57.0>
15> spawn(fun F() -> lists:map(fun(I) -> I + 1 end, lists:seq(1,100)), F()
end).
<0.59.0>
16> spawn(fun F() -> lists:map(fun(I) -> I + 1 end, lists:seq(1,100)), F()
end).
<0.61.0>
17> single_trace:trace(lists,map).
{trace,<0.61.0>,call,
       {lists,map,
              [#Fun<erl_eval.6.54118792>,
               [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,
                24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,
                44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,
                64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,
                84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100]]}}
18>

Writing your own little tracer process can sometimes do wonders :) This
will occasionally print a couple of more messages, but it is quite fast at
turning things off.

Lukas
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20150925/ef976b20/attachment.htm>


More information about the erlang-questions mailing list