inviso_rt_meta.erl

来自「OTP是开放电信平台的简称」· ERL 代码 · 共 1,195 行 · 第 1/4 页

ERL
1,195
字号
%%   Res1,Res2=ok|{error,Reason}remove_global_register(Pid) ->    Res1=ctpm(Pid,global,handle_call,3),    Res2=ctpm(Pid,global,delete_global_name,2),    {Res1,Res2}.%% -----------------------------------------------------------------------------%% Exported help functions which may be used in programming CallFunc and/or%% ReturnFunc. Useful if the call is done on one node but must trigger the%% start of something at other nodes.metacast_call(Nodes,OrigPid,M,F,Args) ->    multicast(Nodes,{trace_ts,OrigPid,call,{M,F,Args},void}),    ok.metacast_return_from(Nodes,OrigPid,M,F,Arity,Value) ->    multicast(Nodes,{trace_ts,OrigPid,return_from,{M,F,Arity},Value,void}),    ok.multicast([Node|Rest],Msg) ->    {?MODULE,Node} ! Msg,    multicast(Rest,Msg);multicast([],_) ->    true.%% -----------------------------------------------------------------------------%% get_states(Pid)={ok,LD,PubLD}.get_state(Pid) ->    send_wait(Pid,get_state).%% -----------------------------------------------------------------------------send_wait(To,Msg) ->    Ref=make_ref(),    To ! {Msg,Ref,self()},    receive	{inviso_rt_meta_reply,Ref,Reply} ->	    Reply    end.reply(To,Ref,Reply) ->    To ! {inviso_rt_meta_reply,Ref,Reply}.%% -----------------------------------------------------------------------------%% =============================================================================%% Special API.%% =============================================================================%% write_ti(OutPut)=%%   OutPut=binary()%% Makes an extra entry into the trace information file (ti-file). This is useful%% if a pid-alias association is learned in another way than through a meta traced%% function call. Note that this API can only be used locally at the node in%% question.write_ti(OutPut) ->    catch ?MODULE ! {write_ti,OutPut}.%% -----------------------------------------------------------------------------%% =============================================================================%% API intended to be used on CallFuncs and RemoveFuncs.%% =============================================================================%% The reason there must be a special API for CallFuncs and RemoveFuncs are is%% that those functions are executed inside *this* process context. Hence they%% can not make function calls requiering this process to receive messages.%% Returns the tracer used for regular tracing. The reason this is implemented%% in this way is that this function is intended to be used in meta trace call-%% back functions. And there we can not have message passing API:s to the meta%% trace(!).get_tracer() ->    get(tracer).%% -----------------------------------------------------------------------------%% Function equivalent to inviso_rt:tpm_ms/6. This function can *only* be used%% inside a CallFunc or a RemoveFunc.tpm_ms(Mod,Func,Arity,MSname,MS) ->    case check_mfarity_exists(Mod,Func,Arity) of	yes ->                               % Ok, and args must be ok then also.	    {ok,h_tpm_ms(Mod,Func,Arity,MSname,MS)};	no ->	    {error,not_initiated}    end.%% -----------------------------------------------------------------------------tpm_ms_tracer(Mod,Func,Arity,MSname,MS) ->    case check_mfarity_exists(Mod,Func,Arity) of	yes ->                               % Ok, and args must be ok then also.	    NewMS=add_tracer(MS,get_tracer()),	    {ok,h_tpm_ms(Mod,Func,Arity,MSname,NewMS)};	no ->	    {error,not_initiated}    end.%% -----------------------------------------------------------------------------%% Function that returns all MSname in use for Mod:Func/Aritylist_tpm_ms(Mod,Func,Arity) ->    {ok,h_list_tpm_ms(Mod,Func,Arity)}.%% -----------------------------------------------------------------------------%% Function equivalent to inviso_rt:ctpm_ms/5. This function can *only* be used%% inside a CallFunc or a RemoveFunc.ctpm_ms(Mod,Func,Arity,MSname) ->    h_ctpm_ms(Mod,Func,Arity,MSname),    ok.%% -----------------------------------------------------------------------------%% =============================================================================%% The server implemenation.%% =============================================================================init(Parent,TiData,Tracer,InitPublLDmfa,RemovePublLDmf,CleanPublLDmf) ->    process_flag(priority,high),            % Since we may receive from many procs.    register(?MODULE,self()),               % So we can act as relay receiver.    case open_traceinfo_file(TiData) of	{ok,TI} ->                          % The ti.-file.	    TId=ets:new(?NAMED_MS_TAB,[named_table,set,protected]),	    PublLD=do_init_publ_ld(InitPublLDmfa),	    Parent ! {self(),ok},	    put(tracer,Tracer),             % Uggly quick fix!	    loop(Parent,		 Tracer,		 TI,		 mk_new_ld(InitPublLDmfa,RemovePublLDmf,CleanPublLDmf,TId),		 PublLD,		 now());	{error,Reason} ->	    Parent ! {self(),{error,Reason}}    end.%% -----------------------------------------------------------------------------loop(Parent,Tracer,TI,LD,PrevPublLD,PrevCleanTime) ->    {PublLD,CleanTime}=throw_old_failed(get_cleanpublldmf_ld(LD),PrevPublLD,PrevCleanTime),    receive	{{init_tpm,{Mod,Func,Arity},InitFunc,CallFunc,ReturnFunc,RemoveFunc},Ref,Parent} ->	    case check_mfarity_exists(Mod,Func,Arity) of		no ->                       % Good then we can add it!		    case check_tpm_args(Mod,Func,Arity) of			true ->             % Args are ok.			    {NewLD,NewPublLD}=				h_init_tpm(Mod,Func,Arity,					   InitFunc,CallFunc,ReturnFunc,RemoveFunc,					   TI,LD,PublLD),			    reply(Parent,Ref,ok),			    loop(Parent,Tracer,TI,NewLD,NewPublLD,CleanTime);			false ->            % Faulty arguments,			    reply(Parent,Ref,{error,bad_mfa}),			    loop(Parent,Tracer,TI,LD,PublLD,CleanTime)		    end;		yes ->                      % If it already exists, cant init again.		    reply(Parent,Ref,{error,already_initiated}),		    loop(Parent,Tracer,TI,LD,PublLD,CleanTime)	    end;	{{tpm,{Mod,Func,Arity,MS},InitFunc,CallFunc,ReturnFunc,RemoveFunc},Ref,Parent} ->	    case check_mfarity_exists(Mod,Func,Arity) of		no ->                       % Good then we can add it!		    case check_tpm_args(Mod,Func,Arity) of			true ->             % Args are ok.			    {NewLD,NewPublLD,N}=				h_tpm(Mod,Func,Arity,MS,				      InitFunc,CallFunc,ReturnFunc,RemoveFunc,				      TI,LD,PublLD),			    reply(Parent,Ref,{ok,N}),			    loop(Parent,Tracer,TI,NewLD,NewPublLD,CleanTime);			false ->			    reply(Parent,Ref,{error,bad_mfa}),			    loop(Parent,Tracer,TI,LD,PublLD,CleanTime)		    end;		yes ->		    reply(Parent,Ref,{error,already_initiated}),		    loop(Parent,Tracer,TI,LD,PublLD,CleanTime)	    end;	{{tpm,{Mod,Func,Arity,MS}},Ref,Parent} ->	    case check_mfarity_exists(Mod,Func,Arity) of		yes ->                      % Ok, and args must be ok then also.		    {NewLD,N}=h_tpm(Mod,Func,Arity,MS,LD),		    reply(Parent,Ref,{ok,N}),		    loop(Parent,Tracer,TI,NewLD,PublLD,CleanTime);		no ->                       % Must be initiated before.		    reply(Parent,Ref,{error,not_initiated}),		    loop(Parent,Tracer,TI,LD,PublLD,CleanTime)	    end;	{{tpm_tracer,{Mod,Func,Arity,MS},InitFunc,CallFunc,ReturnFunc,RemoveFunc},Ref,Parent} ->	    case check_mfarity_exists(Mod,Func,Arity) of		no ->                       % Good then we can add it!		    case check_tpm_args(Mod,Func,Arity) of			true ->             % Args are ok.			    NewMS=add_tracer(MS,Tracer),			    {NewLD,NewPublLD,N}=				h_tpm(Mod,Func,Arity,NewMS,				      InitFunc,CallFunc,ReturnFunc,RemoveFunc,				      TI,LD,PublLD),			    reply(Parent,Ref,{ok,N}),			    loop(Parent,Tracer,TI,NewLD,NewPublLD,CleanTime);			false ->			    reply(Parent,Ref,{error,bad_mfa}),			    loop(Parent,Tracer,TI,LD,PublLD,CleanTime)		    end;		yes ->		    reply(Parent,Ref,{error,already_initiated}),		    loop(Parent,Tracer,TI,LD,PublLD,CleanTime)	    end;	{{tpm_tracer,{Mod,Func,Arity,MS}},Ref,Parent} ->	    case check_mfarity_exists(Mod,Func,Arity) of		yes ->                      % Ok, and args must be ok then also.		    NewMS=add_tracer(MS,Tracer),		    {NewLD,N}=h_tpm(Mod,Func,Arity,NewMS,LD),		    reply(Parent,Ref,{ok,N}),		    loop(Parent,Tracer,TI,NewLD,PublLD,CleanTime);		no ->                       % Must be initiated before.		    reply(Parent,Ref,{error,not_initiated}),		    loop(Parent,Tracer,TI,LD,PublLD,CleanTime)	    end;	{{tpm_ms,{Mod,Func,Arity},MSname,MS},Ref,Parent} ->	    case check_mfarity_exists(Mod,Func,Arity) of		yes ->                      % Ok, and args must be ok then also.		    reply(Parent,Ref,{ok,h_tpm_ms(Mod,Func,Arity,MSname,MS)}),		    loop(Parent,Tracer,TI,LD,PublLD,CleanTime);		no ->		    reply(Parent,Ref,{error,not_initiated}),		    loop(Parent,Tracer,TI,LD,PublLD,CleanTime)	    end;	{{tpm_ms_tracer,{Mod,Func,Arity},MSname,MS},Ref,Parent} ->	    case check_mfarity_exists(Mod,Func,Arity) of		yes ->                      % Ok, and args must be ok then also.		    NewMS=add_tracer(MS,Tracer),		    reply(Parent,Ref,{ok,h_tpm_ms(Mod,Func,Arity,MSname,NewMS)}),		    loop(Parent,Tracer,TI,LD,PublLD,CleanTime);		no ->		    reply(Parent,Ref,{error,not_initiated}),		    loop(Parent,Tracer,TI,LD,PublLD,CleanTime)	    end;	{{ctpm_ms,{Mod,Func,Arity},MSname},Ref,Parent} ->	    reply(Parent,Ref,ok),	    h_ctpm_ms(Mod,Func,Arity,MSname),	    loop(Parent,Tracer,TI,LD,PublLD,CleanTime);	{{ctpm,{Mod,Func,Arity}},Ref,Parent} ->	    case get_remove_func_ld(Mod,Func,Arity,LD) of		false ->                    % Incorrect Mod:Func/Arity!		    reply(Parent,Ref,{error,bad_mfa}),		    loop(Parent,Tracer,TI,LD,PublLD,CleanTime); % Do nothing!		MF ->                       % {M,F}, Func or 'void'.		    catch erlang:trace_pattern({Mod,Func,Arity},false,[meta]),		    NewPublLD=do_removefunc(MF,Mod,Func,Arity,PublLD),		    NewLD=ctpm_ld(Mod,Func,Arity,LD),		    reply(Parent,Ref,ok),		    loop(Parent,Tracer,TI,NewLD,NewPublLD,CleanTime)	    end;	{suspend,Parent} ->                 % Removes all meta trace patterns.	    stop_all_meta_tracing(get_all_meta_funcs_ld(LD),PublLD,LD),	    do_remove_publ_ld(get_removepublldmf_ld(LD),PublLD),	    NewPublLD=do_init_publ_ld(get_initpublldmfa_ld(LD)),	    loop(Parent,Tracer,TI,reset_ld(LD),NewPublLD,CleanTime);	{stop,Parent} ->                    % Make a controlled shutdown.	    stop_all_meta_tracing(get_all_meta_funcs_ld(LD),PublLD,LD),	    do_remove_publ_ld(get_removepublldmf_ld(LD),PublLD),	    close_traceinfo_file(TI);       % And then simply terminate.	{trace_ts,Pid,call,{M,F,Args},_TS} ->	    case handle_meta(get_call_func_ld(M,F,length(Args),LD),Pid,Args,PublLD) of		{ok,NewPublLD,Output} when is_binary(Output) ->		    write_output(TI,Output),		    loop(Parent,Tracer,TI,LD,NewPublLD,CleanTime);		{ok,NewPublLD,_} ->         % No output to the ti-file this time.		    loop(Parent,Tracer,TI,LD,NewPublLD,CleanTime);		_ ->                        % Not handled correct, not much to do.		    loop(Parent,Tracer,TI,LD,PublLD,CleanTime)	    end;	{trace_ts,Pid,return_from,{M,F,Arity},Value,_TS} ->	    case handle_meta(get_return_func_ld(M,F,Arity,LD),Pid,Value,PublLD) of		{ok,NewPublLD,Output} when is_binary(Output) ->		    write_output(TI,Output),		    loop(Parent,Tracer,TI,LD,NewPublLD,CleanTime);		{ok,NewPublLD,_} ->         % No output to the ti-file this time.		    loop(Parent,Tracer,TI,LD,NewPublLD,CleanTime);		_ ->                        % Not handled correct, not much to do.		    loop(Parent,Tracer,TI,LD,PublLD,CleanTime)	    end;	{relayed_meta,Bin} ->	    write_output(TI,Bin),	    loop(Parent,Tracer,TI,LD,PublLD,CleanTime);	{write_ti,OutPut} ->	    write_output(TI,OutPut),	    loop(Parent,Tracer,TI,LD,PublLD,CleanTime);	{get_state,Ref,From} ->             % Debug function.	    reply(From,Ref,{ok,LD,PublLD}),	    loop(Parent,Tracer,TI,LD,PublLD,CleanTime);	_Other ->	    loop(Parent,Tracer,TI,LD,PublLD,CleanTime)    end.%% =============================================================================%% First level help functions.%% =============================================================================%% Function which opens the trace-information file(s). It must understand%% the tidata specification which is part of the tracerdata given to the%% runtime component during init_tracing.

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?