在erlang doc中:
return_to 与呼叫追踪标志一起使用。跟踪 从跟踪函数实际返回其调用者。只有作品 对于使用erlang的本地选项跟踪的函数:trace_pattern / 3。
语义是跟踪调用时发送跟踪消息 函数实际上返回,也就是当一个尾链递归时 通话结束。每个链只会发送一条跟踪消息 tail递归调用,为什么尾递归的属性为 使用此标志进行跟踪时保留函数调用。使用呼叫和 return_to trace一起可以准确地知道哪个 函数一个进程随时执行。
要从函数中获取包含返回值的跟踪消息,请使用 改为{return_trace} match_spec action。
消息标签:return_to。
什么是"实际回报"?我测试了一个尾递归函数,但似乎没什么区别。
以下是我的test.erl:
-module(test).
-compile(export_all).
-record(state, {stacks=[]}).
test_tracer() ->
Tracer = spawn_tracer(),
erlang:trace_pattern({?MODULE, '_', '_'}, [], [local]),
erlang:trace(self(), true, [call,
arity,
return_to,
%% procs,
%% running,
timestamp,
{tracer, Tracer}]),
loop(100),
Tracer!dump.
spawn_tracer() ->
spawn(fun()-> trace_listener(#state{}) end).
trace_listener(State) ->
receive
dump ->
io:format("~p", [lists:reverse(State#state.stacks)]);
{trace_ts, Pid, call, MFA, Ts} ->
Stacks = State#state.stacks,
trace_listener(State#state{stacks=[MFA|Stacks]});
_Term ->
io:format("~p~n", [_Term]),
trace_listener(State)
end.
loop(0) -> ok;
loop(N) -> loop(N-1).
是否有return_to
,它会打印101 {test,loop,1}
。
我认为它应该只返回一个{test,loop,1}
return_to
。
答案 0 :(得分:0)
不,return_to标志不会禁用尾调用,它只会跟踪返回最终结果的位置。
更改代码以适应屏幕:
...
loop(10),
timer:sleep(100),
Tracer ! dump.
启用return_to后,您将收到消息:
{trace_ts,<0.348.0>,return_to,{test,test_tracer,0},{1405,153820,908198}}
这意味着loop / 1函数将其结果返回到test:test_tracer / 0。
没有return_to就没有这样的消息。
要获取返回值,您需要更改模式:
erlang:trace_pattern({?MODULE, '_', '_'}, [{'_', [], [{return_trace}]}], [local]),
现在您将收到以下消息:
{trace_ts,<0.657.0>,return_from,{test,loop,1},ok,{1405,155132,517284}}