diff --git a/src/eTpf.erl b/src/eTpf.erl index a050629..feb72ee 100644 --- a/src/eTpf.erl +++ b/src/eTpf.erl @@ -43,13 +43,13 @@ -compile([export_all, nowarn_export_all]). sts() -> - trace([{app, eSync}, {scope, [whereis(esSyncSrv)]}]). + trace([self(), whereis(esSyncSrv)], [call, return_to], [{test, '_', '_'}, {app, eSync}], tpTracerShell, #{}, #{}). sts1() -> trace([test, {scope, [self()]}]). stl() -> - trace([test, {scope, [self()]}], tpTracerLog). + trace(self(), [all], [{test, '_', '_'}], tpTracerLog, #{}, #{}). stf() -> trace([{app, eSync}, {scope, [whereis(esSyncSrv)]}], tpTracerFile). @@ -116,7 +116,7 @@ trace(PidPortSpec, TracerMod) -> -spec trace(pidPortSpec(), module(), tracerOpts()) -> ok. trace(PidPortSpec, TracerMod, TracerOpts) -> - trace(PidPortSpec, [all], [{'_', '_', '_'}], TracerMod, TracerOpts, #{}). + trace(PidPortSpec, [all], [], TracerMod, TracerOpts, #{}). -spec trace(pidPortSpec(), flagList(), pattern(), module(), tracerOpts(), traceOpts()) -> ok. trace(PidPortSpec, FlagList, TraceMods, TracerMod, TracerOpts, TraceOpts) -> @@ -137,16 +137,31 @@ doTrace(PidPortSpec, FlagList, TraceMods, TracerMod, TracerOpts, TraceOpts) -> case supervisor:start_child(eTpf_sup, TracerSpec) of {ok, TracerPid} -> - LastTraceMods = flattenMods(TraceMods, []), - traceInput(PidPortSpec, FlagList, LastTraceMods, TracerPid, TraceOpts), + TraceMFAs = flattenMods(TraceMods, []), + + % 每个进程只能由一个tracer进行跟踪。因此,跟踪已跟踪进程会失败。 + [ + begin + erlang:trace(OnePidPortSpec, true, [{tracer, tpTracerNif, TracerPid} | FlagList]) + end || OnePidPortSpec <- PidPortSpec + ], + + PtFlags = maps:get(FlagList, TraceOpts, [local]), + MatchSpec = ?IIF(maps:get(stackTc, TraceOpts, false), [{'_', [], [{message, {process_dump}}]}], true), + [ + begin + %% The module must be loaded before we attempt to trace it. + _ = code:ensure_loaded(M), + _ = erlang:trace_pattern(OneTraceMFA, MatchSpec, PtFlags) + end || {M, _F, _A} = OneTraceMFA <- TraceMFAs + ], ok; _Err -> io:format("trace start error ~p~n", [_Err]) end. flattenMods([], Acc) -> - AllMFA = lists:flatten(Acc), - ?IIF(AllMFA == [], [{'_', '_', '_'}], AllMFA); + lists:flatten(Acc); flattenMods([{callback, Mod, Fun} | Tail], Acc) when is_atom(Mod), is_atom(Fun) -> Input = flattenMods(Mod:Fun(), []), flattenMods(Tail, [Input | Acc]); @@ -158,25 +173,4 @@ flattenMods([{app, App} | Tail], Acc) when is_atom(App) -> flattenMods([{_, _, _} = MFA | Tail], Acc) -> flattenMods(Tail, [MFA | Acc]); flattenMods([OneMod | Tail], Acc) -> - flattenMods(Tail, [{OneMod, '_', '_'} | Acc]). - -traceInput(PidPortSpec, FlagList, TraceMFAs, TracerState, TraceOpts) -> - % 每个进程只能由一个tracer进行跟踪。因此,跟踪已跟踪进程会失败。 - [ - begin - erlang:trace(OnePidPortSpec, true, [{tracer, tpTracerNif, TracerState} | FlagList]) - end || OnePidPortSpec <- PidPortSpec - ], - - PtFlags = maps:get(FlagList, TraceOpts, [local]), - MatchSpec = ?IIF(maps:get(stackTc, TraceOpts, false), [{'_', [], [{message, {process_dump}}]}], true), - - [ - begin - %% The module must be loaded before we attempt to trace it. - _ = code:ensure_loaded(M), - io:format("IMY****************** ~p~n ", [OneTraceMFA]), - _ = erlang:trace_pattern(OneTraceMFA, MatchSpec, PtFlags) - end || {M, _F, _A} = OneTraceMFA <- TraceMFAs - ], - ok. + flattenMods(Tail, [{OneMod, '_', '_'} | Acc]). \ No newline at end of file diff --git a/src/tracer/tpTracerShell.erl b/src/tracer/tpTracerShell.erl index 698ed30..675d4f1 100644 --- a/src/tracer/tpTracerShell.erl +++ b/src/tracer/tpTracerShell.erl @@ -25,6 +25,8 @@ loop(Parent) -> receive {system, From, Request} -> sys:handle_system_msg(Request, From, Parent, ?MODULE, [], Parent); + {'EXIT', Parent, Reason} -> + terminate(Reason); RMsg -> io:format("~10000p\n", [RMsg]), %erlang:display(RMsg), @@ -40,3 +42,7 @@ system_terminate(Reason, _, _, _) -> system_code_change(Misc, _, _, _) -> {ok, Misc}. + +-spec terminate(any()) -> no_return(). +terminate(Reason) -> + exit(Reason). diff --git a/src/trace说明.md b/src/trace说明.md index 3af0499..767811d 100644 --- a/src/trace说明.md +++ b/src/trace说明.md @@ -109,3 +109,5 @@ {gc_minor_end, Pid, Ts, Info} Sent when young garbage collection is finished. Info contains the same kind of list as in message gc_minor_start, but the sizes reflect the new sizes after garbage collection. {gc_major_start, Pid, Ts, Info} Sent when fullsweep garbage collection is about to be started. Info contains the same kind of list as in message gc_minor_start. {gc_major_end, Pid, Ts, Info} Sent when fullsweep garbage collection is finished. Info contains the same kind of list as in message gc_minor_start, but the sizes reflect the new sizes after a fullsweep garbage collection. + +