檢視原始碼 dyntrace (runtime_tools v2.1.1)
動態追蹤介面
此模組實作動態追蹤的介面,應將其編譯至虛擬機器中。對於標準和/或商業版本,沒有可用的動態追蹤功能,在這種情況下,此模組中的任何函數都不可用或不會產生任何效果。
如果目前的建置已啟用動態追蹤,無論是透過使用 ./configure --with-dynamic-trace=dtrace
或 ./configure --with-dynamic-trace=systemtap
進行設定,此模組可用於兩件事
- 透過呼叫
dyntrace:p/{1,2,3,4,5,6,7,8}
來觸發 NIF 函式庫dyntrace.so
中的使用者探針user_trace_i4s4
。 - 設定一個使用者指定的標籤,該標籤將會同時出現在
efile_drv
和上述使用者探針的追蹤訊息中。
使用動態追蹤探針進行建置和使用它們都是實驗性的,且不受 Erlang/OTP 支援。它作為開發人員在系統中追蹤和除錯效能問題的選項而包含在內。
原始實作主要由 Scott Lystiger Fritchie 作為開放原始碼貢獻完成,即使動態追蹤的原始碼以及此模組都包含在主要發行版本中,也應將其視為如此。但是,使用虛擬機器的動態追蹤能力是非常有價值的貢獻,OTP 有意將其維護為開發人員的工具。
如何編寫 d
程式或 systemtap
腳本可以從書籍和網路上大量的頁面中學習。本手冊頁面不包含有關使用各個平台的動態追蹤工具的任何文件。但是,runtime_tools
應用程式的 examples
目錄包含 d
和 systemtap
程式的全面範例,可協助您入門。另一個資訊來源是 Runtime Tools 使用者指南中的 dtrace 和 systemtap 章節。
摘要
函數
此函數使用 NIF 函式庫來判斷是否可以使用動態追蹤。
此函數會傳回目前程序中設定的使用者標籤。如果沒有設定標籤或無法使用動態追蹤,則會傳回 undefined
。
呼叫此函數會觸發 dyntrace NIF 模組中的「使用者」追蹤探針 user_trace_i4s4
,並傳送僅包含使用者標籤以及所有其他欄位中的零/空字串的追蹤訊息。
呼叫此函數會觸發 dyntrace
NIF 模組中的「使用者」追蹤探針 user_trace_i4s4
,並傳送包含使用者標籤以及第一個整數/字串欄位中的整數或字串參數的追蹤訊息。
此函數會設定目前程序的使用者標籤。
復原使用者標籤及其散佈的先前狀態,如同在呼叫 spread_tag/1
之前一樣。
此函數控制是否要將使用者標籤隨下一個訊息散佈至其他程序。
類型
函數
-spec available() -> true | false.
此函數使用 NIF 函式庫來判斷是否可以使用動態追蹤。
如果此模組中的 on_load
函數無法載入 dyntrace
NIF 函式庫,此函數會擲回例外狀況。
使用 erlang:system_info(dynamic_trace)
來判斷執行階段系統是否支援動態追蹤。
-spec get_tag() -> binary() | undefined.
此函數會傳回目前程序中設定的使用者標籤。如果沒有設定標籤或無法使用動態追蹤,則會傳回 undefined
。
此函數會傳回目前程序中設定的使用者標籤,或者,如果沒有使用者標籤,則會傳回與訊息一起傳送到程序的最後一個使用者標籤 (其方式與 循序追蹤符號 與訊息一起散佈到其他程序的方式相同)。有關使用者標籤如何與訊息一起散佈的說明,請參閱 spread_tag/1
。如果找不到標籤或無法使用動態追蹤,則會傳回 undefined
-spec p() -> true | false | error | badarg.
呼叫此函數會觸發 dyntrace NIF 模組中的「使用者」追蹤探針 user_trace_i4s4
,並傳送僅包含使用者標籤以及所有其他欄位中的零/空字串的追蹤訊息。
-spec p(probe_arg()) -> true | false | error | badarg.
呼叫此函數會觸發 dyntrace
NIF 模組中的「使用者」追蹤探針 user_trace_i4s4
,並傳送包含使用者標籤以及第一個整數/字串欄位中的整數或字串參數的追蹤訊息。
呼叫此函數會觸發 dyntrace NIF 模組中的「使用者」追蹤探針 user_trace_i4s4
,並傳送包含使用者標籤以及 integer()
或 string()
參數作為其各自類型之第一個欄位的追蹤訊息。
integer()
參數應置於任何 string()
參數之前。
也就是說,下列呼叫有效
下列呼叫無效,因為字串引數在整數引數之前
呼叫此函數會觸發 dyntrace NIF 模組中的「使用者」追蹤探針 user_trace_i4s4
,並傳送包含使用者標籤以及 integer()
或 string()
參數作為其各自類型之第一個欄位的追蹤訊息。
呼叫此函數會觸發 dyntrace NIF 模組中的「使用者」追蹤探針 user_trace_i4s4
,並傳送包含使用者標籤以及 integer()
或 string()
參數作為其各自類型之第一個欄位的追蹤訊息。
-spec p(probe_arg(), probe_arg(), probe_arg(), probe_arg(), probe_arg()) -> true | false | error | badarg.
呼叫此函數會觸發 dyntrace NIF 模組中的「使用者」追蹤探針 user_trace_i4s4
,並傳送包含使用者標籤以及 integer()
或 string()
參數作為其各自類型之第一個欄位的追蹤訊息。
integer()
參數應置於任何 string()
參數之前。
每種型別最多只能有四個參數,因此第一個參數的型別必須為 integer()
,而最後一個參數的型別必須為 string()
。
-spec p(probe_arg(), probe_arg(), probe_arg(), probe_arg(), probe_arg(), probe_arg()) -> true | false | error | badarg.
呼叫此函數會觸發 dyntrace NIF 模組中的「使用者」追蹤探針 user_trace_i4s4
,並傳送包含使用者標籤以及 integer()
或 string()
參數作為其各自類型之第一個欄位的追蹤訊息。
integer()
參數應置於任何 string()
參數之前。
每種型別最多只能有四個參數,因此前兩個參數的型別必須為 integer()
,而最後兩個參數的型別必須為 string()
。
-spec p(probe_arg(), probe_arg(), probe_arg(), probe_arg(), probe_arg(), probe_arg(), probe_arg()) -> true | false | error | badarg.
呼叫此函數會觸發 dyntrace NIF 模組中的「使用者」追蹤探針 user_trace_i4s4
,並傳送包含使用者標籤以及 integer()
或 string()
參數作為其各自類型之第一個欄位的追蹤訊息。
integer()
參數應置於任何 string()
參數之前。
每種型別最多只能有四個參數,因此前三個參數的型別必須為 integer()
,而最後三個參數的型別必須為 string()
。
-spec p(probe_arg(), probe_arg(), probe_arg(), probe_arg(), probe_arg(), probe_arg(), probe_arg(), probe_arg()) -> true | false | error | badarg.
呼叫此函數會觸發 dyntrace NIF 模組中的「使用者」追蹤 probe user_trace_i4s4
,並傳送包含所有提供的 integer()
和 string()
參數,以及目前程序中設定的任何使用者標籤的追蹤訊息。
此函數會設定目前程序的使用者標籤。
使用者標籤是 binary()
,但可以指定為任何 iodata()
,此函數會自動將其轉換為二進位。
使用者標籤會提供給由呼叫 dyntrace:p/{1,2,3,4,5,6,7,8}
觸發的使用者探針,以及 efile
驅動程式中的探針。在未來,使用者標籤可能會新增至更多探針。
舊的使用者標籤 (如果有的話) 會傳回,如果沒有使用者標籤,或未啟用動態追蹤,則會傳回 undefined
。
-spec restore_tag(true | {non_neg_integer(), binary() | []}) -> true.
復原使用者標籤及其散佈的先前狀態,如同在呼叫 spread_tag/1
之前一樣。
請注意,還原不限於同一個進程;可以利用此功能關閉一個進程中的擴散,並在一個新創建的、實際上要發送訊息的進程中還原它。
f() ->
TagData = dyntrace:spread_tag(false),
spawn(fun() ->
dyntrace:restore_tag(TagData),
do_something()
end),
do_something_else(),
dyntrace:restore_tag(TagData).
正確處理使用者標籤及其擴散可能需要一些努力,因為 Erlang 程式傾向於發送和接收訊息,因此有時使用者標籤會因為各種原因而遺失,例如雙重接收或與埠的通訊(埠不處理使用者標籤,就像它們不處理常規順序追蹤標記一樣)。
-spec spread_tag(boolean()) -> true | {non_neg_integer(), binary() | []}.
此函數控制是否要將使用者標籤隨下一個訊息散佈至其他程序。
使用者標籤的擴散與順序追蹤標記的擴散類似,因此接收到的使用者標籤將在進程中保持活動狀態,直到下一個訊息到達(如果該訊息也不包含使用者標籤)。
當客戶端進程與檔案 I/O 伺服器通訊時,會使用此功能將使用者標籤擴散到 I/O 伺服器,然後向下擴散到 efile
驅動程式。透過使用 spread_tag/1
和 restore_tag/1
,可以啟用或停用使用者標籤向其他進程的擴散,然後還原使用者標籤的先前狀態。從此呼叫返回的 TagData 包含所有先前資訊,因此稍後呼叫 restore_tag/1
將完全還原狀態(包括任何先前擴散的使用者標籤)。
file
模組已經擴散標籤,因此不需要手動呼叫此函數來將使用者標籤透過該模組擴散到 efile
驅動程式。
此函數最常見的用法是,例如,使用 io
模組與常規檔案的 I/O 伺服器通訊,如下例所示
f() ->
{ok, F} = file:open("test.tst", [write]),
Saved = dyntrace:spread_tag(true),
io:format(F, "Hello world!", []),
dyntrace:restore_tag(Saved),
file:close(F).
在此範例中,在呼叫進程中設定的任何使用者標籤,在完成 io:format/3
呼叫時,都會擴散到 I/O 伺服器。