檢視原始碼 trace (核心 v10.2)
Erlang 追蹤介面。
Erlang 執行時期系統公開了數個追蹤點,允許使用者在這些追蹤點被觸發時收到通知。追蹤點像是函數呼叫、訊息傳送與接收、垃圾回收以及行程排程。
這個模組中的函式可以直接使用,也可以作為建立更複雜的除錯或效能分析工具的基礎。對於除錯 Erlang 程式碼,建議使用 dbg
,而對於效能分析,則建議使用 tprof
。
追蹤工作階段
所有的追蹤都在追蹤工作階段中進行。追蹤工作階段可以動態地 建立 和 銷毀。每個工作階段都有自己的追蹤器,會接收所有的追蹤訊息。可以同時存在多個工作階段,彼此不會互相干擾。當追蹤工作階段被銷毀時,它所有的追蹤設定都會被自動清除。
範例:
%% Create a tracer process that will receive the trace events
1> Tracer = spawn(fun F() -> receive M -> io:format("~p~n",[M]), F() end end).
<0.91.0>
%% Create a session using the Tracer
2> Session = trace:session_create(my_session, Tracer, []).
{#Ref<0.1543805153.1548353537.92331>,{my_session, 0}}
%% Setup call tracing on self()
3> trace:process(Session, self(), true, [call]).
1
%% Setup call tracing on lists:seq/2
4> trace:function(Session, {lists,seq,2}, [], []).
1
%% Call the traced function
5> lists:seq(1, 10).
{trace,<0.89.0>,call,{lists,seq,[1,10]}} % The trace message
[1,2,3,4,5,6,7,8,9,10] % The return value
%% Cleanup the trace session
6> trace:session_destroy(Session).
ok
僅限節點本機追蹤
這個模組中的函式只在本地節點上運作。也就是說,被追蹤的行程/埠以及追蹤器行程/埠/模組都必須與進行呼叫的本地節點位於同一節點上。要追蹤遠端節點,請使用 dbg
或 ttb
。
變更
此
trace
模組是在 OTP 27.0 中引入的。介面和語意與較舊的函式erlang:trace/3
、erlang:trace_pattern/3
和erlang:trace_info/2
類似。主要的差異在於舊的函式在每個節點上對單一靜態追蹤工作階段進行操作。這可能會導致不同的使用者和工具互相干擾彼此的追蹤設定的問題。此模組中的新追蹤函式都在彼此隔離的動態建立的追蹤工作階段上操作。此外,這使得當完成時,更容易透過單次呼叫
session_destroy/1
安全地停用所有追蹤設定。若要變更現有工具以使用此介面,下表會很有幫助
引數
S
是必須先使用session_create/3
建立的追蹤工作階段。其他引數(由...
暗示)大致相同。唯一的另一個差異是追蹤器永遠是在建立工作階段時指定的追蹤器。因此不允許使用選項{tracer,T}
、{tracer,M,S}
、{meta,T}
和{meta,M,S}
,且預設追蹤器永遠不會是呼叫的行程。
摘要
類型
隔離的追蹤工作階段的控制代碼。
由 session_info/1
傳回的弱式工作階段控制代碼。弱式工作階段控制代碼可以像完整工作階段控制代碼一樣使用,但當最後一個強式控制代碼被垃圾回收時,它不會阻止工作階段被銷毀。
函式
等同於 erlang:trace_delivered(Tracee)
,但它是在給定的 session/0
中執行。
為一個或多個函式啟用或停用呼叫追蹤。
傳回關於埠、行程、函式或事件的追蹤資訊。
為一個或多個埠開啟或關閉追蹤旗標。
為一個或多個行程開啟或關閉追蹤旗標。
為訊息接收設定追蹤模式。
為訊息傳送設定追蹤模式。
建立新的追蹤工作階段。
銷毀追蹤工作階段並清除其在行程、埠和函式上的所有設定。
傳回影響埠、行程、函式或事件的追蹤工作階段。
類型
-type match_variable() :: atom().
-type session() :: {session_strong_ref(), session_weak_ref()} | session_weak_ref().
隔離的追蹤工作階段的控制代碼。
-opaque session_strong_ref()
-opaque session_weak_ref()
由 session_info/1
傳回的弱式工作階段控制代碼。弱式工作階段控制代碼可以像完整工作階段控制代碼一樣使用,但當最後一個強式控制代碼被垃圾回收時,它不會阻止工作階段被銷毀。
-type trace_flag() :: trace_info_flag() | all | cpu_timestamp.
-type trace_info_flag() ::
arity | call | exiting | garbage_collection | monotonic_timestamp | procs | ports |
'receive' | return_to | running | running_procs | running_ports | send | set_on_first_link |
set_on_first_spawn | set_on_link | set_on_spawn | silent | strict_monotonic_timestamp |
timestamp.
-type trace_info_item_result() :: {traced, global | local | false | undefined} | {match_spec, trace_match_spec() | false | undefined} | {meta, pid() | port() | false | undefined | []} | {meta, module(), term()} | {meta_match_spec, trace_match_spec() | false | undefined} | {call_count, non_neg_integer() | boolean() | undefined} | {call_time | call_memory, [{pid(), non_neg_integer(), non_neg_integer(), non_neg_integer()}] | boolean() | undefined}.
-type trace_info_return() :: undefined | {flags, [trace_info_flag()]} | {tracer, pid() | port() | []} | {tracer, module(), term()} | trace_info_item_result() | {all, [trace_info_item_result()] | false | undefined}.
-type trace_match_spec() :: [{[term()] | '_' | match_variable(), [term()], [term()]}].
函式
等同於 erlang:trace_delivered(Tracee)
,但它是在給定的 session/0
中執行。
-spec function(Session, MFA, MatchSpec, FlagList) -> non_neg_integer() when Session :: session(), MFA :: trace_pattern_mfa() | on_load, MatchSpec :: trace_match_spec() | boolean() | restart | pause, FlagList :: [trace_pattern_flag()].
為一個或多個函式啟用或停用呼叫追蹤。
必須與 process/4
結合,以設定一個或多個行程的 call
追蹤旗標。
從概念上講,呼叫追蹤的工作方式如下。在每個追蹤工作階段中,一組行程和一組函式已被標記為追蹤。如果被追蹤的行程呼叫被追蹤的函式,則會採取追蹤動作。否則,不會發生任何事情。
若要新增或移除被追蹤行程集合中的一個或多個行程,請使用 process/4
。
使用此函式可在追蹤工作階段中新增或移除被追蹤函式集合中的函式。
引數 Session
是要操作的追蹤工作階段,由 session_create/3
傳回。
參數 MFA
必須為一個元組,例如 {Module, Function, Arity}
,或是原子 on_load
(如下所述)。MFA
元組指定要追蹤的函數的模組、函數名稱和參數個數。原子 '_'
可在以下任何方式中用作萬用字元:
{Module,Function,'_'}
- 模組Module
中所有名稱為Function
的任何參數個數的函數。{Module,'_','_'}
- 模組Module
中的所有函數。{'_','_','_'}
- 所有已載入模組中的所有函數。
不允許其他組合,例如 {Module,'_',Arity}
。
如果參數 MFA
是原子 on_load
,則比對規格和旗標列表會用於所有新載入模組中的所有函數。
參數 MatchSpec
可以採用以下形式:
true
- 啟用比對函數的追蹤。任何比對規格都會被移除。false
- 停用比對函數的追蹤。任何比對規格都會被移除。MatchExpression
- 一個比對規格。空列表等同於true
。有關比對規格的描述,請參閱 ERTS 應用程式的使用者指南中「Erlang 中的比對規格」一節。restart
- 對於FlagList
選項call_count
、call_time
和call_memory
:重新啟動現有的計數器。對於其他FlagList
選項,行為未定義。pause
- 對於FlagList
選項call_count
、call_time
和call_memory
:暫停現有的計數器。對於其他FlagList
選項,行為未定義。
參數 FlagList
是一個選項列表。以下是有效的選項:
global
- 開啟或關閉全域函數呼叫的呼叫追蹤(也就是明確指定模組的呼叫)。只有匯出的函數會符合,而且只有全域呼叫會產生追蹤訊息。如果FlagList
為空,則這是預設值。local
- 開啟或關閉所有類型函數呼叫的呼叫追蹤。無論如何呼叫,只要呼叫任何指定的函數,就會傳送追蹤訊息。如果為程序設定了return_to
旗標,當此函數返回呼叫者時,也會傳送return_to
訊息。meta
- 開啟或關閉所有類型函數呼叫的中繼追蹤。無論何時呼叫任何指定的函數,都會向追蹤器傳送追蹤訊息。中繼追蹤會追蹤所有程序,並且不關心
process/4
設定的程序追蹤旗標,追蹤旗標會固定為[call, timestamp]
。比對規格函數
{return_trace}
可用於中繼追蹤。call_count
- 針對所有類型的函數呼叫,開始 (MatchSpec == true
) 或停止 (MatchSpec == false
) 呼叫次數追蹤。對於每個函數,在任何程序中呼叫該函數時,計數器都會遞增。不需要啟用任何程序追蹤旗標。如果在執行時開始呼叫次數追蹤,計數會從零重新開始。若要暫停正在執行的計數器,請使用
MatchSpec == pause
。可以使用MatchSpec == restart
從零重新開始暫停和正在執行的計數器。若要讀取函數的計數器值,請呼叫
trace:info(_, MFA, call_count)
。call_time
- 針對所有類型的函數呼叫,開始 (MatchSpec
為true
) 或停止 (MatchSpec
為false
) 呼叫時間追蹤。對於每個函數,在呼叫該函數時,計數器會遞增,並測量在函數中花費的時間,並累積在另一個計數器中。這些計數器會針對每個追蹤呼叫的程序儲存。如果在執行時開始呼叫時間追蹤,計數和時間會從零重新開始。若要暫停正在執行的計數器,請使用
MatchSpec == pause
。可以使用MatchSpec == restart
從零重新開始暫停和正在執行的計數器。若要讀取計數器值,請使用
info/3
。call_memory
- 針對所有類型的函數呼叫,開始 (MatchSpec == true
) 或停止 (MatchSpec == false
) 呼叫記憶體追蹤。如果在執行時開始呼叫記憶體追蹤,計數器和配置會從零重新開始。若要暫停正在執行的計數器,請使用
MatchSpec == pause
。可以使用MatchSpec == restart
從零重新開始暫停和正在執行的計數器。若要讀取計數器值,請使用
info/3
。
選項 global
不能與任何其他選項合併使用,這些選項都會執行某種本地追蹤。如果為一組函數指定了全域追蹤,則會停用該組函數的 local
、meta
、call_count
、call_time
和 call_memory
追蹤,反之亦然。
停用追蹤時,選項必須符合在函數上設定的追蹤類型。也就是說,必須使用選項 local
停用本地追蹤,而使用選項 global
(或無選項)停用全域追蹤,依此類推。
無法直接變更比對規格的一部分。如果函數具有比對規格,可以使用新的比對規格取代它。可以使用函數 info/3
來擷取現有的比對規格。
傳回符合參數 MFA
的函數數量。如果沒有符合的函數,或指定了 on_load
,則會傳回零。
如果發生下列情況,則會失敗並引發錯誤例外:
badarg
- 如果參數無效。system_limit
- 如果作為參數傳遞的比對規格具有過度的巢狀結構,導致呼叫程序在其上執行的排程器發生排程器堆疊耗盡。啟動執行階段系統時,可以設定排程器堆疊大小。
-spec info(Session, PidPortFuncEvent, Item) -> Res when Session :: session(), PidPortFuncEvent :: pid() | port() | new | new_processes | new_ports | MFA | on_load | send | 'receive', MFA :: {module(), atom(), arity()}, Item :: flags | tracer | traced | match_spec | meta | meta_match_spec | call_count | call_time | call_memory | all, Res :: trace_info_return().
傳回關於埠、行程、函式或事件的追蹤資訊。
參數 Session
是要檢視的追蹤工作階段,由 session_create/3
或 session_info/1
傳回。
若要取得埠或程序的相關資訊,PidPortFuncEvent
必須是一個程序識別碼 (pid)、埠識別碼,或其中一個原子 new
、new_processes
或 new_ports
。原子 new
或 new_processes
表示傳回將要建立的程序的預設追蹤狀態。原子 new_ports
表示傳回將要建立的埠的預設追蹤狀態。
適用於埠和程序的有效 Item
值:
flags
- 傳回一個原子列表,指示為該程序啟用了哪些類型的追蹤。如果未啟用任何追蹤,則列表為空,如果啟用追蹤,則列表包含一個或多個trace_info_flag()
。順序是任意的。tracer
- 傳回追蹤此程序的程序、埠的識別碼,或包含追蹤器模組和追蹤器狀態的元組。如果未追蹤此程序,則傳回值為[]
。
若要取得函數的相關資訊,PidPortFuncEvent
必須是三元素元組 {Module, Function, Arity}
或原子 on_load
。不允許使用萬用字元。如果函數不存在,則傳回 undefined
;如果未追蹤該函數,則傳回 false
。如果 PidPortFuncEvent
為 on_load
,則傳回的資訊是指將要載入的程式碼的預設值。
適用於函數的有效 Item
值:
traced
- 如果此函數在全域函數呼叫上追蹤,則傳回global
;如果此函數在本地函數呼叫上追蹤(也就是本地和全域函數呼叫),則傳回local
;如果未追蹤本地或全域函數呼叫,則傳回false
。match_spec
- 如果函數具有比對規格,則傳回該函數的比對規格。如果函數已在本機或全域追蹤,但未定義比對規格,則傳回值為[]
。meta
- 如果函數具有中繼追蹤器程序、埠或追蹤模組,則傳回該追蹤器。如果未對函數進行中繼追蹤,則傳回值為false
。如果已對函數進行中繼追蹤,但曾經偵測到追蹤器程序無效,則傳回值為[]
。meta_match_spec
- 如果函數具有中繼追蹤比對規格,則傳回該規格。如果已對函數進行中繼追蹤,但未定義比對規格,則傳回值為[]
。call_count
- 如果呼叫次數追蹤為啟用狀態,則傳回此函數的呼叫次數值,或者傳回虛擬函數on_load
的true
。否則會傳回false
。另請參閱
function/4
。call_time
- 如果呼叫時間追蹤為啟用狀態,則傳回此函數的呼叫時間值,或者傳回虛擬函數on_load
的true
。否則會傳回false
。傳回的呼叫時間值[{Pid, Count, S, Us}]
是執行該函數的每個程序及其特定計數器的列表。Count
是呼叫次數。S
和Us
是以秒和微秒表示的累積呼叫時間。另請參閱
function/4
。call_memory
- 傳回此函數配置的累計字組數量。累積會在下一個追蹤記憶體的函數停止:如果存在outer
、middle
和inner
函數,每個函數都配置 3 個字組,但只追蹤outer
,它會回報配置了 9 個字組。如果追蹤outer
和inner
,則outer
會回報 6 個字組,inner
會回報 3 個字組。如果未追蹤函數,則會傳回false
。傳回的元組是[{Pid, Count, Words}]
,適用於執行該函數的每個程序。另請參閱
function/4
。all
- 傳回包含所有其他項目的{Item, Value}
元組列表,如果未針對此函數啟用任何追蹤,則傳回false
。
若要取得事件的相關資訊,PidPortFuncEvent
必須是其中一個原子 send
或 'receive'
。
事件存在一個有效的 Item
:
match_spec
- 傳回此事件的匹配規範(如果有的話),如果沒有設定匹配規範,則傳回true
。
傳回值為 {Item, Value}
,其中 Value
是先前描述的要求資訊。如果指定了已停止進程的 pid,或是不存在的函數名稱,則 Value
為 undefined
。
-spec port(Session, Ports, How, FlagList) -> integer() when Session :: session(), Ports :: port() | all | existing | new, How :: boolean(), FlagList :: [trace_flag()].
為一個或多個埠開啟或關閉追蹤旗標。
引數 Session
是要操作的追蹤工作階段,由 session_create/3
傳回。
Ports
可以是本機埠的埠識別符,或是下列原子之一
all
- 所有目前存在的埠,以及未來將建立的所有埠。existing
- 所有目前存在的埠。new
- 所有未來將建立的埠。
FlagList
可以包含任意數量的以下旗標(「訊息標籤」指的是 追蹤訊息
的列表)
all
- 設定除了cpu_timestamp
以外的所有追蹤旗標,因為其本質與其他旗標不同。send
- 追蹤訊息的傳送。訊息標籤:
send
和send_to_non_existing_process
。'receive'
- 追蹤訊息的接收。訊息標籤:
'receive'
。ports
- 追蹤與埠相關的事件。訊息標籤:
open
、closed
、register
、unregister
、getting_linked
和getting_unlinked
。running_ports
- 追蹤埠的排程。timestamp
、cpu_timestamp
、monotonic_timestamp
、strict_monotonic_timestamp
- 與process/4
中的時間戳記相同。
追蹤進程會收到以下列表描述的 *追蹤訊息*。Port
是已追蹤事件發生的追蹤埠的埠識別符。第三個元組元素是訊息標籤。
如果指定了旗標 timestamp
、strict_monotonic_timestamp
或 monotonic_timestamp
,則第一個元組元素將會是 trace_ts
,並且時間戳記會作為額外的元素加入訊息元組的最後。如果傳遞了多個時間戳記旗標,則 timestamp
的優先順序高於 strict_monotonic_timestamp
,而 strict_monotonic_timestamp
的優先順序又高於 monotonic_timestamp
。所有時間戳記旗標都會被記住,因此如果傳遞了兩個旗標,並且稍後停用了優先順序較高的旗標,則另一個旗標將會啟動。
如果匹配規範(僅適用於 send
和 'receive'
追蹤)包含一個具有非布林值的 {message}
動作函數,則該值會作為額外元素加入訊息元組,位於最後一個位置或時間戳記之前(如果有的話)。
追蹤訊息
{trace, Port, send, Msg, To}
- 當Port
將訊息Msg
傳送至進程To
時。{trace, Port, send_to_non_existing_process, Msg, To}
- 當Port
將訊息Msg
傳送至不存在的進程To
時。{trace, Port, 'receive', Msg}
- 當Port
接收到訊息Msg
時。如果Msg
設定為逾時,則接收語句可能已逾時,或者進程接收到包含timeout
酬載的訊息。{trace, Port, register, RegName}
- 當Port
獲得已註冊的名稱RegName
時。{trace, Port, unregister, RegName}
- 當Port
取消註冊名稱RegName
時。當註冊的進程或埠退出時,會自動執行此操作。{trace, Port, getting_linked, Pid2}
- 當Port
與進程Pid2
連結時。{trace, Port, getting_unlinked, Pid2}
- 當Port
從進程Pid2
取消連結時。{trace, Port, open, Pid, Driver}
- 當Pid
使用正在執行的Driver
開啟一個新的埠Port
時。Driver
是以原子表示的驅動程式名稱。{trace, Port, closed, Reason}
- 當Port
因Reason
而關閉時。{trace, Port, in, Command | 0}
- 當Port
排程執行時。Command
是埠將執行的第一個操作,但是它可以在排程出去之前執行多個命令。在極少數情況下,無法確定當前函數,則最後一個元素為0
。可能的命令包括
call
、close
、command
、connect
、control
、flush
、info
、link
、open
和unlink
。{trace, Port, out, Command | 0}
- 當Port
排程結束時。最後執行的命令是Command
。在極少數情況下,無法確定當前函數,則最後一個元素為0
。Command
可以包含與in
相同的命令
如果追蹤的進程/埠停止運作,或者追蹤器模組傳回 remove
,則會靜默移除旗標。
傳回一個數字,表示符合 Ports
的埠的數量。如果 Ports
是埠識別符,則傳回值為 1
。如果 Ports
是 all
或 existing
,則傳回值為現有埠的數量。如果 Ports
是 new
,則傳回值為 0
。
失敗:如果指定的不支援引數,則為 badarg
。例如,並非所有平台都支援 cpu_timestamp
。
-spec process(Session, Procs, How, FlagList) -> integer() when Session :: session(), Procs :: pid() | all | existing | new, How :: boolean(), FlagList :: [trace_flag()].
為一個或多個行程開啟或關閉追蹤旗標。
引數 Session
是要操作的追蹤工作階段,由 session_create/3
傳回。
引數 Procs
可以是本機進程的進程識別符 (pid),或是下列原子之一
all
- 所有目前存在的進程,以及未來將建立的所有進程。existing
- 所有目前存在的進程。new
- 所有未來將建立的進程。
引數 How
可以是 true
以開啟追蹤旗標,或 false
以關閉追蹤旗標。
引數 FlagList
可以包含任意數量的以下旗標(「訊息標籤」指的是 追蹤訊息
的列表)
all
- 設定除了cpu_timestamp
以外的所有追蹤旗標,因為其本質與其他旗標不同。send
- 追蹤訊息的傳送。透過呼叫send/3
來限制要追蹤哪些傳送的訊息。訊息標籤:
send
和send_to_non_existing_process
。'receive'
- 追蹤訊息的接收。透過呼叫recv/3
來限制要追蹤哪些接收的訊息。訊息標籤:
'receive'
。call
- 追蹤特定的函數呼叫。透過呼叫function/4
來指定要追蹤哪些函數呼叫。訊息標籤:
call
和return_from
。silent
- 與call
追蹤旗標一起使用。如果設定此旗標,則會禁止call
、return_from
和return_to
追蹤訊息,但是如果存在匹配規範,則它們會像正常情況一樣執行。執行
trace:process(_, _, false, [silent|_])
,或是由執行函數{silent, false}
的匹配規範,會禁止靜默模式。silent
追蹤旗標有助於在系統中許多甚至所有進程上設定追蹤。然後可以使用匹配規範函數{silent,Bool}
來啟動和停用追蹤,從而高度控制哪些函數及其哪些引數會觸發追蹤。訊息標籤:
call
、return_from
和return_to
。或者更確切地說,沒有。return_to
- 與call
追蹤旗標一起使用。追蹤從呼叫追蹤函數返回到執行恢復位置的退出。僅適用於使用選項local
追蹤的函數,請參閱function/4
。語意是,當呼叫追蹤函數返回或拋出被捕獲的例外狀況時,會傳送
return_to
追蹤訊息。對於尾呼叫,每個尾呼叫鏈僅傳送一條追蹤訊息,因此在使用此旗標進行追蹤時,會保留函數呼叫的尾遞迴屬性。對於例外狀況也是如此,即使例外狀況在捕獲之前經過了多個呼叫追蹤函數,也只會傳送一個return_to
追蹤訊息。同時使用
call
和return_to
追蹤,可以確切知道程序在任何時間點正在執行哪個函式。若要取得包含函式傳回值的追蹤訊息,請改用
{return_trace}
比對規格動作。訊息標籤:
return_to
。procs
- 追蹤程序相關事件。訊息標籤:
spawn
、spawned
、exit
、register
、unregister
、link
、unlink
、getting_linked
和getting_unlinked
。running
- 追蹤程序的排程。exiting
- 追蹤正在結束的程序的排程。訊息標籤:
in_exiting
、out_exiting
和out_exited
。running_procs
- 追蹤程序的排程,如同running
。然而,此選項也包含當程序在埠的上下文中執行,而本身沒有被排程出去時的排程事件。garbage_collection
- 追蹤程序的垃圾回收。timestamp
- 在所有追蹤訊息中包含時間戳記。時間戳記 (Ts) 的格式與erlang:now/0
傳回的格式相同。cpu_timestamp
- Erlang 節點的全域追蹤旗標,讓使用timestamp
旗標的所有追蹤時間戳記都使用 CPU 時間,而不是實際時間。也就是說,如果啟用monotonic_timestamp
或strict_monotonic_timestamp
,則不得使用cpu_timestamp
。僅允許搭配Procs==all
。如果主機的作業系統不支援高解析度的 CPU 時間測量,process/4
會以badarg
結束。請注意,大多數作業系統不會在核心之間同步此值,因此使用此選項時,時間可能會看起來倒退。monotonic_timestamp
- 在所有追蹤訊息中包含 Erlang 單調時間 時間戳記。時間戳記 (Ts) 的格式和值與erlang:monotonic_time(nanosecond)
產生的相同。此旗標會覆蓋cpu_timestamp
旗標。strict_monotonic_timestamp
- 在所有追蹤訊息中包含由 Erlang 單調時間 和單調遞增整數組成時間戳記。時間戳記 (Ts) 的格式和值與{
erlang:monotonic_time(nanosecond)
,
erlang:unique_integer([monotonic])
}
產生的相同。此旗標會覆蓋cpu_timestamp
旗標。如果傳遞多個時間戳記旗標,
timestamp
的優先順序高於strict_monotonic_timestamp
,而後者又高於monotonic_timestamp
。所有時間戳記旗標都會被記住,因此如果傳遞兩個旗標,且優先順序較高的那個稍後被停用,則另一個旗標會變成啟用狀態。arity
- 與call
追蹤旗標一起使用。在呼叫追蹤訊息中,會指定{M, F, Arity}
,而不是{M, F, Args}
。set_on_spawn
- 使由追蹤程序建立的任何程序繼承其所有追蹤旗標,包括set_on_spawn
旗標本身。set_on_first_spawn
- 使由追蹤程序建立的第一個程序繼承其所有追蹤旗標,但不包括set_on_first_spawn
旗標本身。也就是說,在完成第一個 spawn 後,set_on_first_spawn
將會在 spawn 的程序和產生 spawn 的程序中清除。如果同時設定這兩個旗標,
set_on_first_spawn
會取代set_on_spawn
。set_on_link
- 使由追蹤程序連結的任何程序繼承其所有追蹤旗標,包括set_on_link
旗標本身。set_on_first_link
- 使由追蹤程序連結的第一個程序繼承其所有追蹤旗標,但不包括set_on_first_link
旗標本身。也就是說,在完成第一個 link 後,set_on_first_link
將會在連結的程序和產生連結的程序中清除。如果同時設定這兩個旗標,
set_on_first_link
會取代set_on_link
。
追蹤程序會收到下列清單中所述的追蹤訊息。Pid
是發生追蹤事件的被追蹤程序的程序識別碼。第三個元組元素是訊息標籤。
如果指定了 timestamp
、strict_monotonic_timestamp
或 monotonic_timestamp
旗標,則第一個元組元素會改為 trace_ts
,且時間戳記會做為額外元素加入訊息元組的最後一個位置。
如果比對規格(僅適用於 call
、send
和 'receive'
追蹤)包含具有非布林值的 {message}
動作函式,則該值會做為額外元素加入訊息元組中,放在最後一個位置或時間戳記之前(如果有的話)。
追蹤訊息
{trace, Pid, send, Msg, To}
- 當程序Pid
將訊息Msg
傳送給程序To
時。{trace, Pid, send_to_non_existing_process, Msg, To}
- 當程序Pid
將訊息Msg
傳送給不存在的程序To
時。{trace, Pid, 'receive', Msg}
- 當程序Pid
收到訊息Msg
時。如果Msg
設定為逾時,則 receive 陳述式可能會逾時,或者程序收到 payload 為timeout
的訊息。{trace, Pid, call, {M, F, Args}}
- 當程序Pid
呼叫已追蹤的函式時。永遠不會提供呼叫的傳回值,只會提供呼叫及其引數。可以使用追蹤旗標
arity
來變更此訊息的內容,以便指定Arity
,而不是Args
。{trace, Pid, return_to, {M, F, Arity}}
- 當程序Pid
傳回至指定的函式時。如果同時設定call
和return_to
旗標,並且將函式設定為追蹤本機函式呼叫,則會傳送此追蹤訊息。只有在從尾遞迴函式呼叫鏈返回時,才會傳送此訊息,其中至少有一個呼叫產生call
追蹤訊息(也就是說,函式比對規格符合,且{message, false}
不是動作)。{trace, Pid, return_from, {M, F, Arity}, ReturnValue}
- 當Pid
從指定的函式傳回時。如果設定了call
旗標,且函式具有return_trace
或exception_trace
動作的比對規格,則會傳送此追蹤訊息。{trace, Pid, exception_from, {M, F, Arity}, {Class, Value}}
- 當Pid
因為例外狀況而從指定的函式結束時。如果設定了call
旗標,且函式具有exception_trace
動作的比對規格,則會傳送此追蹤訊息。{trace, Pid, spawn, Pid2, {M, F, Args}}
- 當Pid
以指定的函式呼叫做為進入點,產生新的程序Pid2
時。Args
應該是引數清單,但如果產生 spawn 時發生錯誤,則可以是任何 term。{trace, Pid, spawned, Pid2, {M, F, Args}}
- 當Pid
由程序Pid2
產生,並以指定的函式呼叫做為進入點時。Args
應該是引數清單,但如果產生 spawn 時發生錯誤,則可以是任何 term。{trace, Pid, exit, Reason}
- 當Pid
以原因Reason
結束時。{trace, Pid, register, RegName}
- 當程序Pid
取得已註冊的名稱RegName
時。{trace, Pid, unregister, RegName}
- 當程序Pid
取消註冊名稱RegName
時。當已註冊的程序或埠結束時,會自動執行此操作。{trace, Pid, link, Pid2}
- 當Pid
連結到程序Pid2
時。{trace, Pid, unlink, Pid2}
- 當Pid
從程序Pid2
移除連結時。{trace, Pid, getting_linked, Pid2}
- 當Pid
連結到程序Pid2
時。{trace, Pid, getting_unlinked, Pid2}
- 當Pid
從程序Pid2
取消連結時。{trace, Port, open, Pid, Driver}
- 當Pid
使用執行的Driver
開啟新的埠Port
時。Driver
是以原子表示的驅動程式名稱。{trace, Pid, in | in_exiting, {M, F, Arity} | 0}
當Pid
被排程執行時。程序在函式{M, F, Arity}
中執行。在某些罕見情況下,無法判斷目前的函式,則最後一個元素為0
。{trace, Pid, out | out_exiting | out_exited, {M, F, Arity} | 0}
當Pid
被排程出去時。程序在函式{M, F, Arity}
中執行。在某些罕見情況下,無法判斷目前的函式,則最後一個元素為0
。{trace, Pid, gc_minor_start, Info}
- 當年輕代的垃圾回收即將開始時發送。Info
是一個包含雙元素 tuple 的列表,其中第一個元素是鍵,第二個是值。不要依賴 tuple 的任何順序。定義了以下鍵:heap_size
- Heap 已使用部分的大小。heap_block_size
- 用於儲存 heap 和 stack 的記憶體區塊大小。old_heap_size
- Old heap 已使用部分的大小。old_heap_block_size
- 用於儲存 old heap 的記憶體區塊大小。stack_size
- Stack 的大小。recent_size
- 在前一次垃圾回收中存活的資料大小。mbuf_size
- 與進程關聯的訊息緩衝區的總大小。bin_vheap_size
- 從進程 heap 參考的唯一 off-heap 二進制檔案的總大小。bin_vheap_block_size
- 在執行垃圾回收之前,允許在進程虛擬 heap 中使用的二進制檔案總大小。bin_old_vheap_size
- 從進程 old heap 參考的唯一 off-heap 二進制檔案的總大小。bin_old_vheap_block_size
- 在執行垃圾回收之前,允許在進程虛擬 old heap 中使用的二進制檔案總大小。wordsize
- 對於gc_minor_start
事件,它是觸發 GC 的需求大小。對於相應的gc_minor_end
事件,它是回收的記憶體大小 = 開始heap_size
- 結束heap_size
。
所有大小都以 word 為單位。
{trace, Pid, gc_max_heap_size, Info}
- 當垃圾回收期間達到max_heap_size
時發送。Info
包含與gc_start
訊息中相同的列表,但大小反映了觸發max_heap_size
達到的大小。{trace, Pid, gc_minor_end, Info}
- 當年輕代垃圾回收完成時發送。Info
包含與gc_minor_start
訊息中相同的列表,但大小反映了垃圾回收後的新大小。{trace, Pid, gc_major_start, Info}
- 當 fullsweep 垃圾回收即將開始時發送。Info
包含與gc_minor_start
訊息中相同的列表。{trace, Pid, gc_major_end, Info}
- 當 fullsweep 垃圾回收完成時發送。Info
包含與gc_minor_start
訊息中相同的列表,但大小反映了 fullsweep 垃圾回收後的新大小。
如果追蹤進程終止或追蹤模組返回 remove
,則會靜默地移除標誌。
返回一個數字,指示符合 Procs
的進程數量。如果 Procs
是進程識別碼,則返回值為 1
。如果 Procs
是 all
或 existing
,則返回值是正在運行的進程數量。如果 Procs
是 new
,則返回值為 0
。
失敗:如果指定的不支援引數,則為 badarg
。例如,並非所有平台都支援 cpu_timestamp
。
-spec recv(Session, MatchSpec, FlagList) -> non_neg_integer() when Session :: session(), MatchSpec :: trace_match_spec() | boolean(), FlagList :: [].
為訊息接收設定追蹤模式。
必須與 process/4
或 port/4
結合使用,才能為一個或多個進程或端口設定 'receive'
追蹤標誌。
引數 Session
是要操作的追蹤工作階段,由 session_create/3
傳回。
每個會話中 receive
追蹤模式的預設值為 true
。也就是說,所有具有啟用 'receive'
追蹤的進程所接收的訊息都將被追蹤。使用此函數可根據訊息內容、發送者和/或接收者來限制追蹤的 'receive'
事件。
參數 MatchSpec
可以採用以下形式:
MatchExpression
- 匹配規範。匹配是在列表[Node, Sender, Msg]
上完成的。Node
是發送者的節點名稱。Sender
是發送者的進程或端口身份,如果發送者未知(遠端發送者可能如此),則為原子undefined
。Msg
是訊息 term。可以使用 guard 函數self/0
來存取接收進程的 pid。空列表與true
相同。如需更多資訊,請參閱 ERTS 應用程式使用者指南中的 Erlang 中的匹配規範 章節。true
- 為所有接收到的訊息(到'receive'
追蹤的進程)啟用追蹤。任何匹配規範都會被移除。這是預設值。false
- 停用所有接收到的訊息的追蹤。任何匹配規範都會被移除。
參數 FlagList
對於接收追蹤必須為 []
。
返回值始終為 1
。
範例
僅追蹤來自特定進程 Pid
的訊息
> trace:recv(Session, [{['_',Pid, '_'],[],[]}], []).
1
僅追蹤符合 {reply, _}
的訊息
> trace:recv(Session, [{['_','_', {reply,'_'}],[],[]}], []).
1
僅追蹤來自其他節點的訊息
> trace:recv(Session, [{['$1', '_', '_'],[{'=/=','$1',{node}}],[]}], []).
1
注意
用於
'receive'
追蹤的匹配規範可以使用所有 guard 和 body 函數,但caller
、is_seq_trace
、get_seq_token
、set_seq_token
、enable_trace
、disable_trace
、trace
、silent
和process_dump
除外。
如果發生下列情況,則會失敗並引發錯誤例外:
badarg
- 如果參數無效。system_limit
- 如果作為參數傳遞的比對規格具有過度的巢狀結構,導致呼叫程序在其上執行的排程器發生排程器堆疊耗盡。啟動執行階段系統時,可以設定排程器堆疊大小。
-spec send(Session, MatchSpec, FlagList) -> non_neg_integer() when Session :: session(), MatchSpec :: trace_match_spec() | boolean(), FlagList :: [].
為訊息傳送設定追蹤模式。
必須與 process/4
或 port/4
結合使用,才能為一個或多個進程或端口設定 send
追蹤標誌。
引數 Session
是要操作的追蹤工作階段,由 session_create/3
傳回。
每個會話中 send
追蹤模式的預設值為 true
。也就是說,所有具有啟用 send
追蹤的進程所發送的訊息都將被追蹤。使用此函數可根據訊息內容、發送者和/或接收者來限制追蹤的 send
事件。
參數 MatchSpec
可以採用以下形式:
MatchExpression
- 匹配規範。匹配是在列表[Receiver, Msg]
上完成的。Receiver
是接收者的進程或端口身份,而Msg
是訊息 term。可以使用 guard 函數self/0
來存取發送進程的 pid。空列表與true
相同。如需更多資訊,請參閱 ERTS 應用程式使用者指南中的 Erlang 中的匹配規範 章節。true
- 為所有發送的訊息(從send
追蹤的進程)啟用追蹤。任何匹配規範都會被移除。false
- 停用所有發送的訊息的追蹤。任何匹配規範都會被移除。
參數 FlagList
必須為 []
。
返回值始終為 1
。
範例
僅追蹤到特定進程 Pid
的訊息
> trace:send(Session, [{[Pid, '_'],[],[]}], []).
1
僅追蹤符合 {reply, _}
的訊息
> trace:send(Session, [{['_', {reply,'_'}],[],[]}], []).
1
僅追蹤發送到發送者本身的訊息
> trace:send(Session, [{['$1', '_'],[{'=:=','$1',{self}}],[]}], []).
1
僅追蹤發送到其他節點的訊息
> trace:send(Session, [{['$1', '_'],[{'=/=',{node,'$1'},{node}}],[]}], []).
1
注意
用於
send
追蹤的匹配規範可以使用所有 guard 和 body 函數,但caller
除外。
如果發生下列情況,則會失敗並引發錯誤例外:
badarg
- 如果參數無效。system_limit
- 如果作為參數傳遞的比對規格具有過度的巢狀結構,導致呼叫程序在其上執行的排程器發生排程器堆疊耗盡。啟動執行階段系統時,可以設定排程器堆疊大小。
-spec session_create(Name, Tracer, Opts) -> session() when Name :: atom(), Tracer :: pid() | port() | {module(), term()}, Opts :: [].
建立新的追蹤工作階段。
參數 Name
是會話的原子名稱。使用 session_info/1
檢查時將返回此名稱。
參數 Tracer
指定會話中所有追蹤事件的消費者。它可以是接收所有追蹤訊息的本地進程或端口的識別碼。
Tracer
也可以是 tuple {TracerModule, TracerState}
,用於呼叫追蹤模組而不是發送追蹤訊息。然後,追蹤模組可以忽略或變更追蹤訊息。如需更多有關如何編寫追蹤模組的詳細資訊,請參閱模組 erl_tracer
。
參數 Opts
必須為 []
。
返回追蹤會話的不透明句柄。句柄將保持會話處於活動狀態。如果句柄被捨棄並進行垃圾回收,則會話將被銷毀和清除,如同呼叫了 session_destroy/1
一樣。
-spec session_destroy(Session) -> true | false when Session :: session().
銷毀追蹤工作階段並清除其在行程、埠和函式上的所有設定。
唯一沒有被清除的是已經發送的追蹤訊息。
如果會話處於活動狀態,則返回 true
。如果會話已由先前對此函數的呼叫或垃圾回收器銷毀,則返回 false
。
-spec session_info(PidPortFuncEvent) -> Res when PidPortFuncEvent :: all | pid() | port() | new | new_processes | new_ports | MFA | on_load | send | 'receive', MFA :: {module(), atom(), arity()}, Res :: undefined | [session_weak_ref()].
傳回影響埠、行程、函式或事件的追蹤工作階段。
參數 all
會回傳節點上所有存在的啟用追蹤會期。
回傳 弱會期句柄 的列表,如果程序/埠/函數不存在則回傳 undefined
。