diff --git a/erts/emulator/beam/erl_bif_trace.c b/erts/emulator/beam/erl_bif_trace.c index 632e21bee48c..0ab8b5940643 100644 --- a/erts/emulator/beam/erl_bif_trace.c +++ b/erts/emulator/beam/erl_bif_trace.c @@ -349,8 +349,15 @@ trace_pattern(Process* p, ErtsTraceSession *session, } flags.breakpoint = 1; flags.meta = 1; - if (ERTS_TRACER_IS_NIL(meta_tracer)) - meta_tracer = erts_term_to_tracer(THE_NON_VALUE, p->common.id); + if (ERTS_TRACER_IS_NIL(meta_tracer)) { + if (ERTS_TRACER_IS_NIL(session->tracer)) { + meta_tracer = erts_term_to_tracer(THE_NON_VALUE, + p->common.id); + } + else { + erts_tracer_update(&meta_tracer, session->tracer); + } + } break; case am_global: if (flags.breakpoint) { diff --git a/erts/emulator/test/trace_session_SUITE.erl b/erts/emulator/test/trace_session_SUITE.erl index 37afa99be9c6..dace045447f8 100644 --- a/erts/emulator/test/trace_session_SUITE.erl +++ b/erts/emulator/test/trace_session_SUITE.erl @@ -91,8 +91,15 @@ erlang_trace(Session, Pid, How, FlagList) when is_pid(Pid) -> erlang_trace_pattern(legacy, MFA, MS, FlagList) -> erlang:trace_pattern(MFA, MS, FlagList); -erlang_trace_pattern(Session, MFA, MS, FlagList) -> - trace:function(Session, MFA, MS, FlagList). +erlang_trace_pattern(Session, MFA, MS, FlagList0) -> + FlagList1 = lists:keydelete(tracer, 1, FlagList0), + FlagList3 = case lists:keytake(meta, 1, FlagList1) of + {value, {meta,_Tracer}, FlagList2} -> + [meta | FlagList2]; + false -> + FlagList1 + end, + trace:function(Session, MFA, MS, FlagList3). on_load(_Config) -> @@ -1152,27 +1159,44 @@ call_do2(S1, Tracer1, Opts1, S2, Tracer2, Opts2, {TPopt, Call}) -> meta(_Config) -> Tester = self(), Tracer0 = spawn_link(fun() -> tracer("Tracer0",Tester) end), + Tracer1 = spawn_link(fun() -> tracer("Tracer1",Tester) end), + S1 = trace:session_create(session1, Tracer1, []), + meta_do(legacy, Tracer0, S1, Tracer1), + meta_do(S1, Tracer1, legacy, Tracer0), + + unlink(Tracer0), + exit(Tracer0, die), + unlink(Tracer1), + exit(Tracer1, die), + ok. + +meta_do(S1, Tracer1, S2, Tracer2) -> + Tester = self(), MFArity = {?MODULE,foo,0}, MFArgs = {?MODULE,foo,[]}, - 1 = erlang:trace_pattern(MFArity,true,[{meta,Tracer0}]), + + 1 = erlang_trace_pattern(S1, MFArity, true, [{meta,Tracer1}]), + 1 = erlang_trace_pattern(S2, MFArity, true, [{meta,Tracer2}]), ?line, foo(), - {Tracer0, {trace_ts,P,call,MFArgs,{_,_,_}}} = receive_any(), + receive_parallel({[{Tracer1, {trace_ts,Tester,call,MFArgs,{'_','_','_'}}}], + [{Tracer2, {trace_ts,Tester,call,MFArgs,{'_','_','_'}}}]}), ?line, ?MODULE:foo(), - {Tracer0, {trace_ts,P,call,MFArgs,{_,_,_}}} = receive_any(), + receive_parallel({[{Tracer1, {trace_ts,Tester,call,MFArgs,{'_','_','_'}}}], + [{Tracer2, {trace_ts,Tester,call,MFArgs,{'_','_','_'}}}]}), - 1 = erlang:trace_pattern(MFArity,false,[meta]), + 1 = erlang_trace_pattern(S1, MFArity, false, [meta]), ?line, foo(), - timeout = receive_nothing(), + {Tracer2, {trace_ts,Tester,call,MFArgs,{_,_,_}}} = receive_any(), - unlink(Tracer0), - exit(Tracer0, die), + 1 = erlang_trace_pattern(S2, MFArity, false, [meta]), + timeout = receive_nothing(), ok.