Reputation: 3617
I suspect the answer is probably "no", but just in case, is there a way to add data to the traced event when using return_trace()?
E.g.
1> erlang:trace(all, true, [call]).
...
2> MatchSpec = dbg:fun2ms(fun([Num1, Num2]) when Num1 < Num2 ->
return_trace(), message({event_name, neg_sub_event});
(_) ->
return_trace(), message({event_name, sub_event}) end).
...
3> erlang:trace_pattern({mod, sub, 2}, MatchSpec, [local]).
...
4> flush().
ok
5> spawn(mod, sub, [4, 5]).
...
6> flush().
Shell got {trace,<0.64.0>,call,
{mod,sub,[4,5]},
{event_name,neg_sub_event}}
Shell got {trace,<0.64.0>,return_from,{mod,sub,2},-1}
ok
7> spawn(mod, sub, [6, 5]).
...
8> flush().
Shell got {trace,<0.67.0>,call,{mod,sub,[6,5]},{event_name,sub_event}}
Shell got {trace,<0.67.0>,return_from,{mod,sub,2},1}
ok
I just came up with the example without really thinking about it... in this case I could figure out whether it's a neg_sub_event or a sub_event from the return value included in a return_from trace... but the point is that I would like to include {event_name, Name} not only when a call event fires, but also when a return_from event is generated.
Is this even possible?
Thanks.
Edit
This is why I can't simply receive a 'return_from' trace and say "ok, so this 'return_from' trace must correspond to the last 'call' trace I received. Therefore, this 'return_from' trace must have the event_name of the last 'call' trace I received":
Consider 2 processes A and B. Both call function F1 which is being traced with a specification which states that in one case (e.g. F1 is called with an argument of 10), the 'call' trace generated should have an event_name of "is_ten" and a return_trace() should be generated after the call trace is. Therefore, the process receiving the trace messages would receive:
{trace, Pid, call, {Mod, Fun, Args}, {event_name, is_ten}}
when F1 is called with an argument of 10, and
{trace, Pid, return_from, {Mod, Fun, Arity}, ReturnVal}
when F1, called with an argument of 10, is evaluated and returns.
Another specification placed on F1 (via the match spec used in erlang:trace_pattern/3) is that, for e.g., when F1 is called with an argument of 20, the 'call' trace generated should have an event_name of "is_twenty" and a return_trace() should be generated after the call trace is. Therefore, the process receiving the trace messages would receive:
{trace, Pid, call, {Mod, Fun, Args}, {event_name, is_twenty}}
when F1 is called with an argument of 20, and
{trace, Pid, return_from, {Mod, Fun, Arity}, ReturnVal}
when F1, called with an argument of 20, is evaluated and returns.
Now if A starts evaluating F1 (with arg 10), generates a 'call' trace, is preempted, B starts evaluating F1 (with arg 20), generates a 'call' trace, is preempted, A finishes evaluating F1, and generates a 'return_from' trace, the process receiving the trace messages would receive:
{trace, Pid, call, {Mod, Fun, Args}, {event_name, is_ten}}
{trace, Pid, call, {Mod, Fun, Args}, {event_name, is_twenty}}
{trace, Pid, return_from, {Mod, Fun, Arity}, ReturnVal}
At this stage, if the process receiving the trace messages assumes that every 'return_from' trace message corresponds to the latest 'call' message receive, it will assign the event_name of 'is_twenty' to the return_from message when in fact it should be 'is_ten'.
Upvotes: 0
Views: 288
Reputation: 3617
No. You can only add extra information in a trace 'call' using message(Data) in MatchSpec. Furthermore, when writing the body of a specification, you can add a return_trace(). This will generate a 'return_from' trace message when the function being traced returns, BUT, unlike the trace message which is sent when the function in question is being called, you cannot add extra information to the trace message which is sent when the function in question returns.
E.g.
dbg:fun2ms(fun([Num1, Num2]) when Num1 < Num2 ->
return_trace(), message({event_name, neg_sub_event});
(_) ->
message({event_name, sub_event}) end).
The match specification generated above, when applied to the function mod:sub/2 using erlang:trace_pattern({mod, sub, 2}, MatchSpec, [local]), will generate the following trace events (when the traced processes have the flag 'call' turned on using erlang:trace/3):
{trace, Pid, call, {Mod, Fun, Args}, {event_name, neg_sub_event}}
and
{trace, Pid, return_from, {Mod, Fun, Arity}, ReturnVal}
when mod:sub/2 is called with Num1 and Num2 such that Num1 < Num2. In all other cases, the generated trace would be:
{trace, Pid, call, {Mod, Fun, Args}, {event_name, sub_event}}
Therefore, you cannot add extra info like "{event_name, Name}" to a 'return_from' trace because there is no way of specifying this in a match specification.
Upvotes: 1
Reputation: 552
According to the doc for erlang:trace/3,
{trace, Pid, return_from, {M, F, Arity}, ReturnValue}
is sent to the tracer process, so I'd think you can't attach any more data. (Well, an obvious hack is if the return value contains the call argument... but this would be ugly.)
However, if you do stateful tracing, (i.e. keep track of the trace message sequence) then you might correlate the
{trace, Pid, call, {M, F, Args}}
message with the subsequent return_from above. You might use e.g. pan for that with a callback module, see my other post.
Upvotes: 2