inviso_rt_meta.erl

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

ERL
1,195
字号
%% ``The contents of this file are subject to the Erlang Public License,%% Version 1.1, (the "License"); you may not use this file except in%% compliance with the License. You should have received a copy of the%% Erlang Public License along with this software. If not, it can be%% retrieved via the world wide web at http://www.erlang.org/.%% %% Software distributed under the License is distributed on an "AS IS"%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See%% the License for the specific language governing rights and limitations%% under the License.%% %% The Initial Developer of the Original Code is Ericsson Utvecklings AB.%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings%% AB. All Rights Reserved.''%% %%     $Id$%%%% Author: Lennart 謍man, lennart.ohman@st.se%%%% This module implements the meta tracer process belonging to the%% runtime component. Its main purpose is to write the ti-file (traceinformation).%% The ti-file contains translations between process id:s and what ever "you"%% want to read in the merged and formatted logfile.%% This process interacts with the runtime component process.%%%% Currently it handles the following types of ti-files:%%   Plain raw, binary log.%%   Relay to other inviso_rt_meta process on another node.%%%% The TI file will be on binary format and each entry is:%%   <<LengthIndicator:32, {Pid,Alias,Op,NowStamp} >>%%       Pid=pid(), or if OP==unalias pid()|any_other_than_pid()%%       Op=alias|unalias%% ------------------------------------------------------------------------------module(inviso_rt_meta).%% -----------------------------------------------------------------------------%% API exports.%% ------------------------------------------------------------------------------export([start/2,start/5]).-export([stop/1,suspend/1]).-export([init_tpm/5,init_tpm/8]).-export([tpm/5,tpm/6,tpm/9,tpm_tracer/5,tpm_tracer/6,tpm_tracer/9]).-export([tpm_ms/6,tpm_ms_tracer/6,ctpm_ms/5,ctpm/4]).-export([local_register/1,global_register/1]).-export([remove_local_register/1,remove_global_register/1]).-export([write_ti/1]).-export([get_tracer/0,tpm_ms/5,tpm_ms_tracer/5,list_tpm_ms/3,ctpm_ms/4]).-export([metacast_call/5,metacast_return_from/6]).-export([get_state/1]).%% -----------------------------------------------------------------------------%% -----------------------------------------------------------------------------%% Internal exports.%% ------------------------------------------------------------------------------export([init/6]).-export([init_std_publld/2,clean_std_publld/1]).%% -----------------------------------------------------------------------------%% -----------------------------------------------------------------------------%% Constants.%% ------------------------------------------------------------------------------define(NAMED_MS_TAB,inviso_rt_meta_named_ms).%% -----------------------------------------------------------------------------%% =============================================================================%% Exported API (Meant to be used by a runtime component).%% =============================================================================%% start(TiData,Tracer)={ok,Pid} | {error,Reason}%% start(TiData,Tracer,InitPublLDmfa,RemovePublLDmfa,CleanPublLDmf)=%%     {ok,Pid} | {error,Reason}%%   TiData={file,FileName}|{relay,Node}%%   Tracer=pid()|port()%%   FileName=string()%%   InitPublLDmfa={Mod,Func,ArgList}%%   RemovePublLDmf={Mod,Func} | void%%     RemovePublLDmf(PublLD)->nothing significant.%%     These functions are called to create and destroy the public loopdata%%     structure available to the meta-trace CallFunc and ReturnFunc.%%   CleanPublLDmf={Mod,Func}%%     This function will periodically be called to clean the public LD from%%     pending meta-trace messages waiting for a corresponding return_from%%     message.%%%% Starts a meta-tracer process, opening the ti-file specified in TiData. PublLD%% is used to communicate data, typically between a call and return_from.%% If no special initialization function is specified a standard one is used.%% Note that the meta tracer function must know "who" is the regular tracer%% (process or port). This because it must be possible to append {tracer,Tracer}%% in meta match specs.start(TiData,Tracer) ->    Pid=spawn_link(?MODULE,		   init,		   [self(),		    TiData,		    Tracer,		    {?MODULE,init_std_publld,[2,[]]},		    void,		    {?MODULE,clean_std_publld}]),    wait_for_reply(Pid).start(TiData,Tracer,InitPublLDmfa,RemovePublLDmf,CleanPublLDmf) ->    Pid=spawn_link(?MODULE,		   init,		   [self(),TiData,Tracer,InitPublLDmfa,RemovePublLDmf,CleanPublLDmf]),    wait_for_reply(Pid).wait_for_reply(Pid) ->    receive	{Pid,ok} ->	    {ok,Pid};	{Pid,{error,Reason}} ->	    {error,Reason}    after	10000 ->                             % After very long time.	    exit(Pid,kill),                  % It must be hanging.	    {error,time_out}    end.%% -----------------------------------------------------------------------------%% stop(Pid)=ok%%   Pid=Adders to the meta tracer, pid().%% Shutsdown the metatracer.stop(Pid) ->    Pid ! {stop,self()},    ok.%% -----------------------------------------------------------------------------%% suspend(Pid)=ok%%   Pid=Adders to the meta tracer, pid().%% Suspends the meta tracer by removing all meta trace patterns.suspend(Pid) ->    Pid ! {suspend,self()},    ok.%% -----------------------------------------------------------------------------%% init_tpm(Pid,Mod,Func,Arity,CallFunc)=%% init_tpm(Pid,Mod,Func,Arity,InitFunc,CallFunc,ReturnFunc,RemoveFunc)=ok|{error,Reason}.%%   Pid=Address to meta tracer process, pid().%%   Mod,Func=Pointing out the function which shall be meta traced, atom().%%   Arity=As above, integer().%%   InitFunc,RemoveFunc={Module,Function}|fun(), functions being called when%%     to initialize the public loopdata structure, and to reset it.%%       InitFunc(Mod,Func,Arity,PublLD)->{ok,NewPublLD,Output}%%         Supposed to initialize whatever needs to be done before%%         handling any incoming meta-trace message for the Mod:Func/Arity.%%       RemoveFunc(Mod,Func,Arity,PublLD)->{ok,NewPublLD}%%         Called when meta tracing of Mod:Func/Arity is stopped. It is supposed%%         to clear datastructures away from the PublLD.%% Initializes the public loopdata for this function. Note that we can not use wildcards%% here (even if it is perfectly legal in Erlang). It also sets the CallFunc and%% ReturnFunc for the meta traced function. The function is hence ready to be%% meta traced with either tpm/5 or tpm_ms/5.%% This function is synchronous, waiting for a reply from the meta server.init_tpm(Pid,Mod,Func,Arity,CallFunc) ->    init_tpm(Pid,Mod,Func,Arity,void,CallFunc,void,void).init_tpm(Pid,Mod,Func,Arity,InitFunc,CallFunc,ReturnFunc,RemoveFunc) ->    send_wait(Pid,	      {init_tpm,{Mod,Func,Arity},InitFunc,CallFunc,ReturnFunc,RemoveFunc}).%% -----------------------------------------------------------------------------%% tpm(Pid,Mod,Func,Arity,MatchSpec)={ok,N}|{error,Reason}%% tpm(Pid,Mod,Func,Arity,MatchSpec,CallFunc)={ok,N}|{error,Reason}%% tpm(Pid,Mod,Func,Arity,MatchSpec,InitFunc,CallFunc,ReturnFunc,RemoveFunc)=%%   Pid=Address to meta tracer process, pid().%%   Mod,Func=Pointing out the function which shall be meta traced, atom().%%   Arity=As above, integer().%%   MatchSpec=List of match specification, possibly empty. Remember {return_trace}%%     if expecting return_from messages.%%   InitFunc,CallFunc,ReturnFunc,RemoveFunc={Module,Function}|fun(),%%     functions being called when these functions are called by the meta trace%%     server at certain events.%%       CallFunc(CallingPid,ActualArgList,PublLD)->{ok,NewPrivLD,Output}%%       ReturnFunc(CallingPid,ReturnValue,PublLD)->{ok,NewPrivLD,Output}%%         When a call respectively return_from trace message arrives for the meta%%         traced function, the corresponding function is called.%%         The ReturnFunc must handle the fact that a return_from message arrives%%         for a call which was never noticed. This because the message queue of the%%         meta tracer may have been emptied.%%   Reason=badarg | %%   Output=Characters to be written to the ti-file, bin() | 'void'%% The tpm/5 function simply starts meta tracing for the function. It must%% previously have been initialized.%% tpm/6 & /9 initializes the function and starts meta tracing.tpm(Pid,Mod,Func,Arity,MatchSpec)  when is_atom(Mod),is_atom(Func),is_integer(Arity),is_list(MatchSpec),Mod/='_',Func/='_'->    send_wait(Pid,{tpm,{Mod,Func,Arity,MatchSpec}});tpm(_,_,_,_,_) ->    {error,badarg}.tpm(Pid,Mod,Func,Arity,MatchSpec,CallFunc) ->    tpm(Pid,Mod,Func,Arity,MatchSpec,void,CallFunc,void,void).tpm(Pid,Mod,Func,Arity,MatchSpec,InitFunc,CallFunc,ReturnFunc,RemoveFunc)  when is_atom(Mod),is_atom(Func),is_integer(Arity),is_list(MatchSpec),Mod/='_',Func/='_' ->    send_wait(Pid,{tpm,{Mod,Func,Arity,MatchSpec},InitFunc,CallFunc,ReturnFunc,RemoveFunc});tpm(_,_,_,_,_,_,_,_,_) ->    {error,badarg}.%% -----------------------------------------------------------------------------%% Same as tpm/X but the meta tracer will automatically append {tracer,Tracer}%% to the enable list in a {trace,Disable,Enable} match spec action term.tpm_tracer(Pid,Mod,Func,Arity,MatchSpec)  when is_atom(Mod),is_atom(Func),is_integer(Arity),is_list(MatchSpec),Mod/='_',Func/='_'->    send_wait(Pid,{tpm_tracer,{Mod,Func,Arity,MatchSpec}});tpm_tracer(_,_,_,_,_) ->    {error,badarg}.tpm_tracer(Pid,Mod,Func,Arity,MatchSpec,CallFunc) ->    tpm_tracer(Pid,Mod,Func,Arity,MatchSpec,void,CallFunc,void,void).tpm_tracer(Pid,Mod,Func,Arity,MatchSpec,InitFunc,CallFunc,ReturnFunc,RemoveFunc)  when is_atom(Mod),is_atom(Func),is_integer(Arity),is_list(MatchSpec),Mod/='_',Func/='_' ->    send_wait(Pid,{tpm_tracer,		   {Mod,Func,Arity,MatchSpec},		   InitFunc,CallFunc,ReturnFunc,RemoveFunc});tpm_tracer(_,_,_,_,_,_,_,_,_) ->    {error,badarg}.%% -----------------------------------------------------------------------------%% tpm_ms(Pid,Mod,Func,Arity,MSname,MS)={ok,N}|{error,Reason}%%   Pid=Address to meta tracer process, pid().%%   Mod,Func=Pointing out the function to which we shall add a match-spec., atom().%%   Arity=As above, integer().%%   MSname=A name to be used if this MS shall be removed later. term().%%   MatchSpec=List of match specification, Remember {return_trace}%%     if expecting return_from messages.%% This function adds a list of match-specs to the already existing ones. It%% uses an internal database to keep track of existing match-specs. If the%% match-spec does not result in any meta traced functions (for whatever reason),%% the MS is not saved in the database. The previously known match-specs are%% not removed.tpm_ms(Pid,Mod,Func,Arity,MSname,MS) ->    send_wait(Pid,{tpm_ms,{Mod,Func,Arity},MSname,MS}).%% -----------------------------------------------------------------------------%% Same as tpm_ms/6 but the meta tracer will automatically append {tracer,Tracer}%% to the enable list in a {trace,Disable,Enable} match spec action term.tpm_ms_tracer(Pid,Mod,Func,Arity,MSname,MS) ->    send_wait(Pid,{tpm_ms_tracer,{Mod,Func,Arity},MSname,MS}).%% -----------------------------------------------------------------------------%% ctpm_ms(Pid,Mod,Func,Arity)=ok%%%% Removes a names match-spec from the meta traced function. Note that is never%% a fault to remove an MS. Not even from a function which is non existant.ctpm_ms(Pid,Mod,Func,Arity,MSname) ->    send_wait(Pid,{ctpm_ms,{Mod,Func,Arity},MSname}).%% -----------------------------------------------------------------------------%% Quick versions for erlang:register/2 which also uses a default CallFunc%% and a default ReturnFunc.local_register(Pid) ->    Res1=tpm(Pid,	     erlang,register,2,[{'_',[],[{return_trace}]}],	     fun metafunc_init/4,fun local_register_call/3,	     fun local_register_return/3,void),    Res2=tpm(Pid,	     erlang,unregister,1,[],	     void,fun local_unregister_call/3,void,void),    {Res1,Res2}.%% -----------------------------------------------------------------------------%% Quick version for global:register_name/2, /3.global_register(Pid) ->    Res1=tpm(Pid,global,handle_call,3,[{[{register,'_','_','_'},'_','_'],[],[]}],	void,fun global_register_call/3,void,void),    Res2=tpm(Pid,global,delete_global_name,2,[],	     void,fun global_unregister_call/3,void,void),    {Res1,Res2}.%% -----------------------------------------------------------------------------%% ctpm(Pid,Mod,Func,Arity)=ok|{error,bad_mfa}%%%% Removes the meta trace pattern for the function, means stops generating output%% for this function. The public LD may be cleared by the previously entered%% RemoveFunc.ctpm(Pid,Mod,Func,Arity) ->    send_wait(Pid,{ctpm,{Mod,Func,Arity}}).%% -----------------------------------------------------------------------------%% remove_local_register(Pid)={Res1,Res2}%%   Res1,Res2=ok|{error,Reason}remove_local_register(Pid) ->    Res1=ctpm(Pid,erlang,register,2),    Res2=ctpm(Pid,erlang,unregister,1),    {Res1,Res2}.%% -----------------------------------------------------------------------------%% remove_global_register(Pid)={Res1,Res2}

⌨️ 快捷键说明

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