檢視原始碼 sys 行為 (stdlib v6.2)
系統訊息的功能介面。
此模組包含用於傳送程式所使用的系統訊息,以及用於除錯目的之訊息的函式。
用於實作程序的函式也應理解系統訊息,例如除錯訊息和程式碼變更。這些函式必須用於實作程序系統訊息的使用;無論是直接使用,或透過標準行為,例如 gen_server
。
除非另有指定,否則預設逾時時間為 5000 毫秒。timeout
定義等待程序回應請求的時間。如果程序沒有回應,則函式會評估 exit({timeout, {M, F, A}})
。
這些函式會參考除錯結構。除錯結構是 dbg_opt/0
的列表,這是函式 handle_system_msg/6
所使用的內部資料類型。如果它是空列表,則不會執行任何除錯。
系統訊息
未實作為標準行為之一的程序仍必須理解系統訊息。必須理解以下三個訊息
純系統訊息。這些訊息會以
{system, From, Msg}
的形式接收。接收程序模組不會解譯此訊息的內容和含義。當收到系統訊息時,會呼叫函式handle_system_msg/6
來處理請求。關機訊息。如果程序攔截退出,則必須能夠處理來自其父系、監視器的關機請求。來自父系的訊息
{'EXIT', Parent, Reason}
是終止的指令。當收到此訊息時,程序必須終止,通常與Parent
的Reason
相同。如果在執行期間動態變更用於實作程序的模組,則程序必須理解另一個訊息。一個例子是
gen_event
程序。訊息為{_Label, {From, Ref}, get_modules}
。對此訊息的回覆為From ! {Ref, Modules}
,其中Modules
是程序中目前活動模組的清單。釋放處理器使用此訊息來尋找執行特定模組的程序。稍後可以暫停程序,並命令其對其其中一個模組執行程式碼變更。
系統事件
當使用此模組的函式除錯程序時,程序會產生 system_events,然後在除錯函式中處理這些事件。例如,trace
會將系統事件格式化到終端機。
當程序接收或傳送訊息時,會使用四個預先定義的系統事件。程序也可以定義自己的系統事件。格式化這些事件始終取決於程序本身。
摘要
回呼:程序實作函式
當程序要執行程式碼變更時,從 handle_system_msg/6
呼叫。當內部資料結構已變更時,會使用程式碼變更。此函式會將引數 Misc
轉換為新的資料結構。OldVsn
是舊版本 Module
的屬性 vsn。如果沒有定義此屬性,則會傳送原子 undefined
。
當程序要繼續執行時(例如,在暫停之後),從 handle_system_msg/6
呼叫。此函式永遠不會傳回。
當程序要傳回反映其目前狀態的詞彙時,從 handle_system_msg/6
呼叫。State
是 get_state/2
傳回的值。
當程序要取代其目前狀態時,從 handle_system_msg/6
呼叫。NState
是 replace_state/3
傳回的值。
當程序要終止時,從 handle_system_msg/6
呼叫。例如,當程序暫停且其父系命令關機時,會呼叫此函式。它讓程序有機會執行清除作業。此函式永遠不會傳回。
程序實作函式
可由從選項清單啟動除錯結構的程序使用。引數 Opt
的值與對應函式的值相同。
取得與除錯選項相關聯的資料。如果找不到 Item
,則會傳回 Default
。程序可以使用此函式來擷取除錯資料,以便在終止之前列印。
傳回除錯結構中記錄的系統事件,即 handle_debug/4
的最後一個引數。
當程序產生系統事件時,會呼叫此函式。FormFunc
是格式化函式,會呼叫為 FormFunc(Device, Event, Extra)
來列印事件,如果已啟用追蹤,這是必要的。Extra
是程序在格式化函式中需要的任何額外資訊,例如程序名稱。
程序模組使用此函式來處理系統訊息。程序會收到 {system, From, Msg}
訊息,並將 Msg
和 From
傳遞給此函式。
列印除錯結構中記錄的系統事件,使用 handle_debug/4
呼叫產生事件時定義的 FormFunc
。
函式
取得程序的狀態。
取得程序的狀態。
允許安裝替代的除錯函式。此類函式的一個範例是觸發器,這是一個等待某些特殊事件並在產生事件時執行某些動作的函式。例如,開啟低階追蹤。
開啟或關閉系統事件的記錄。如果開啟,則除錯結構中會保留最多 N
個事件(預設值為 10)。
啟用或停用以文字格式記錄所有系統事件到檔案。事件會使用產生事件的程序定義的函式(透過呼叫 handle_debug/4
)格式化。該檔案會以 UTF-8 編碼開啟。
關閉程序的所有除錯。這包括使用函式 install/2,3
明確安裝的函式,例如觸發器。
從程序中移除已安裝的除錯函式。Func
或 FuncId
必須與先前安裝的相同。
取代程序的狀態,並傳回新的狀態。
繼續已暫停的程序。
啟用或停用統計資料的收集。如果 Flag
是 get
,則會傳回統計資料集合。
暫停程序。當程序被暫停時,它只會回應其他系統訊息,而不會回應其他訊息。
命令程序以指定的 Reason
終止。終止操作是非同步進行的,因此無法保證函數返回時程序已終止。
在 standard_io
上印出所有系統事件。事件會使用產生事件的程序所定義的函數來格式化(透過呼叫 handle_debug/4
)。
類型
-type dbg_fun() :: fun((FuncState :: _, Event :: system_event(), ProcState :: _) -> done | (NewFuncState :: _)).
-opaque dbg_opt()
請參閱本手冊頁面的簡介。
-type format_fun() :: fun((Device :: io:device() | file:io_device(), Event :: system_event(), Extra :: term()) -> any()).
-type system_event() :: {in, Msg :: _} | {in, Msg :: _, State :: _} | {out, Msg :: _, To :: _} | {out, Msg :: _, To :: _, State :: _} | {noreply, State :: _} | {continue, Continuation :: _} | {postpone, Event :: _, State :: _, NextState :: _} | {consume, Event :: _, State :: _, NextState :: _} | {start_timer, Action :: _, State :: _} | {insert_timeout, Event :: _, State :: _} | {enter, Module :: module(), State :: _} | {module, Module :: module(), State :: _} | {terminate, Reason :: _, State :: _} | term().
由 gen_server
、gen_statem
和 gen_event
產生的除錯事件
{in,Msg}
- 當訊息Msg
到達時,由gen_server
和gen_event
產生。{in,Msg,State}
- 當訊息Msg
在狀態State
中到達時,由gen_statem
產生。對於
gen_statem
,Msg
項是一個{EventType,EventContent}
元組。{out,Msg,To}
- 當回覆Msg
從回呼模組返回{reply,To,Msg}
動作時,由gen_statem
產生,並將回覆發送回To
。To
的類型與gen_statem:reply/2
的第一個參數相同。{out,Msg,To,State}
- 當回覆Msg
從回呼模組返回{reply,...}
元組時,由gen_server
產生,並將回覆發送回To
。To
的類型與gen_server:reply/2
的第一個參數相同。State
是新的伺服器狀態。{noreply,State}
- 當從回呼模組返回{noreply,...}
元組時,由gen_server
產生。State
是新的伺服器狀態。{continue,Continuation}
- 當從回呼模組返回{continue,Continuation}
元組時,由gen_server
產生。{postpone,Event,State,NextState}
- 當訊息Event
在狀態State
中被延遲時,由gen_statem
產生。NextState
是新的狀態。Event
是一個{EventType,EventContent}
元組。{consume,Event,State,NextState}
- 當訊息Event
在狀態State
中被消耗時,由gen_statem
產生。NextState
是新的狀態。Event
是一個{EventType,EventContent}
元組。{start_timer,Action,State}
- 當動作Action
在狀態State
中啟動計時器時,由gen_statem
產生。{insert_timeout,Event,State}
- 當逾時為零的動作在狀態State
中插入事件Event
時,由gen_statem
產生。Event
是一個{EventType,EventContent}
元組。{enter,Module,State}
- 當模組Module
進入第一個狀態State
時,由gen_statem
產生。{module,Module,State}
- 當在狀態State
中設定模組Module
時,由gen_statem
產生。{terminate,Reason,State}
- 當它以原因Reason
在狀態State
中終止時,由gen_statem
產生。
回呼:程序實作函式
-callback system_code_change(Misc, Module, OldVsn, Extra) -> {ok, NMisc} when Misc :: term(), OldVsn :: undefined | term(), Module :: atom(), Extra :: term(), NMisc :: term().
當程序要執行程式碼變更時,從 handle_system_msg/6
呼叫。當內部資料結構已變更時,會使用程式碼變更。此函式會將引數 Misc
轉換為新的資料結構。OldVsn
是舊版本 Module
的屬性 vsn。如果沒有定義此屬性,則會傳送原子 undefined
。
-callback system_continue(Parent, Debug, Misc) -> no_return() when Parent :: pid(), Debug :: [dbg_opt()], Misc :: term().
當程序要繼續執行時(例如,在暫停之後),從 handle_system_msg/6
呼叫。此函式永遠不會傳回。
當程序要傳回反映其目前狀態的詞彙時,從 handle_system_msg/6
呼叫。State
是 get_state/2
傳回的值。
-callback system_replace_state(StateFun, Misc) -> {ok, NState, NMisc} when Misc :: term(), NState :: term(), NMisc :: term(), StateFun :: fun((State :: term()) -> NState).
當程序要取代其目前狀態時,從 handle_system_msg/6
呼叫。NState
是 replace_state/3
傳回的值。
-callback system_terminate(Reason, Parent, Debug, Misc) -> no_return() when Reason :: term(), Parent :: pid(), Debug :: [dbg_opt()], Misc :: term().
當程序要終止時,從 handle_system_msg/6
呼叫。例如,當程序暫停且其父系命令關機時,會呼叫此函式。它讓程序有機會執行清除作業。此函式永遠不會傳回。
程序實作函式
-spec debug_options([Opt :: debug_option()]) -> [dbg_opt()].
可由從選項清單啟動除錯結構的程序使用。引數 Opt
的值與對應函式的值相同。
-spec get_debug(Item, Debug, Default) -> term() when Item :: log | statistics, Debug :: [dbg_opt()], Default :: term().
取得與除錯選項相關聯的資料。如果找不到 Item
,則會傳回 Default
。程序可以使用此函式來擷取除錯資料,以便在終止之前列印。
-spec get_log(Debug) -> [system_event()] when Debug :: [dbg_opt()].
傳回除錯結構中記錄的系統事件,即 handle_debug/4
的最後一個引數。
-spec handle_debug(Debug, FormFunc, Extra, Event) -> [dbg_opt()] when Debug :: [dbg_opt()], FormFunc :: format_fun(), Extra :: term(), Event :: system_event().
當程序產生系統事件時,會呼叫此函式。FormFunc
是格式化函式,會呼叫為 FormFunc(Device, Event, Extra)
來列印事件,如果已啟用追蹤,這是必要的。Extra
是程序在格式化函式中需要的任何額外資訊,例如程序名稱。
-spec handle_system_msg(Msg, From, Parent, Module, Debug, Misc) -> no_return() when Msg :: term(), From :: {pid(), Tag :: _}, Parent :: pid(), Module :: module(), Debug :: [dbg_opt()], Misc :: term().
程序模組使用此函式來處理系統訊息。程序會收到 {system, From, Msg}
訊息,並將 Msg
和 From
傳遞給此函式。
此函式永不返回。它會呼叫下列其中一個函式
Module:system_continue(Parent, NDebug, Misc)
,其中程序繼續執行。Module:system_terminate(Reason, Parent, Debug, Misc)
,如果程序要終止。
Module
必須匯出下列函式
參數 Misc
可用於在程序中儲存內部資料,例如其狀態。它會發送到 Module:system_continue/3
或 Module:system_terminate/4
。
-spec print_log(Debug) -> ok when Debug :: [dbg_opt()].
列印除錯結構中記錄的系統事件,使用 handle_debug/4
呼叫產生事件時定義的 FormFunc
。
函式
-spec change_code(Name, Module, OldVsn, Extra, Timeout) -> ok | {error, Reason} when Name :: name(), Module :: module(), OldVsn :: undefined | term(), Extra :: term(), Timeout :: timeout(), Reason :: term().
告知程序變更程式碼。
必須暫停程序才能處理此訊息。參數 Extra
保留給每個程序自行使用。呼叫函式 Module:system_code_change/4
。OldVsn
是 Module
的舊版本。
取得程序的狀態。
注意
這些函式僅旨在協助除錯。它們是為了方便起見而提供,讓開發人員可以避免建立自己的狀態提取函式,也可以避免在除錯時必須從
get_status/1
或get_status/2
的傳回值中互動式地提取狀態。
State
的值會因不同類型的程序而異,如下所示
- 對於
gen_server
程序,傳回的State
是回呼模組的狀態。 - 對於
gen_statem
程序,State
是元組{CurrentState,CurrentData}
。 - 對於
gen_event
程序,State
是一個元組清單,其中每個元組對應於程序中註冊的事件處理常式,並包含{Module, Id, HandlerState}
,如下所示Module
- 事件處理常式的模組名稱。Id
- 處理常式的 ID(如果註冊時沒有 ID,則為false
)。HandlerState
- 處理常式的狀態。
如果回呼模組匯出函式 system_get_state/1
,則會在目標程序中呼叫它以取得其狀態。其參數與 get_status/1,2
傳回的 Misc
值相同,並且預期函式 Module:system_get_state/1
從中提取回呼模組的狀態。函式 system_get_state/1
必須傳回 {ok, State}
,其中 State
是回呼模組的狀態。
如果回呼模組未匯出 system_get_state/1
函式,get_state/1,2
會假設 Misc
值是回呼模組的狀態,並直接傳回它。
如果回呼模組的 system_get_state/1
函式崩潰或拋出例外,呼叫者會以錯誤 {callback_failed, {Module, system_get_state}, {Class, Reason}}
結束,其中 Module
是回呼模組的名稱,而 Class
和 Reason
表示例外的詳細資訊。
函式 system_get_state/1
主要用於使用者定義的行為和實作 OTP 特殊程序的模組。gen_server
、gen_statem
和 gen_event
OTP 行為模組會匯出此函式,因此這些行為的回呼模組不需要提供自己的函式。
如需關於程序的更多資訊,包含其狀態,請參閱 get_status/1
和 get_status/2
。
-spec get_status(Name, Timeout) -> Status when Name :: name(), Timeout :: timeout(), Status :: {status, Pid :: pid(), {module, Module :: module()}, [SItem]}, SItem :: (PDict :: [{Key :: term(), Value :: term()}]) | (SysState :: running | suspended) | (Parent :: pid()) | (Dbg :: [dbg_opt()]) | (Misc :: term()).
取得程序的狀態。
Misc
的值因不同類型的程序而異,例如
gen_server
程序會回傳回呼模組的狀態。gen_statem
程序會回傳資訊,例如其目前的狀態名稱和狀態資料。gen_event
程序會回傳關於其每個已註冊處理常式的資訊。- 一個裸
sys
程序會回傳傳遞給handle_system_message/6
的Misc
值。
針對 gen_server
、gen_statem
和 gen_event
的回呼模組也可以透過匯出函式 format_status/1
來變更 Misc
的值,這會貢獻模組特定的資訊。詳細資訊,請參閱 gen_server:format_status/1
、gen_statem:format_status/1
和 gen_event:format_status/1
。
-spec install(Name, FuncSpec, Timeout) -> ok when Name :: name(), FuncSpec :: {Func, FuncState} | {FuncId, Func, FuncState}, FuncId :: term(), Func :: dbg_fun(), FuncState :: term(), Timeout :: timeout().
允許安裝替代的除錯函式。此類函式的一個範例是觸發器,這是一個等待某些特殊事件並在產生事件時執行某些動作的函式。例如,開啟低階追蹤。
每當產生系統事件時,就會呼叫 Func
。此函式應回傳 done
,或新的 Func
狀態。在第一種情況下,函式會被移除。如果函式失敗,也會被移除。如果一個偵錯函式應被安裝多次,則每次安裝必須指定唯一的 FuncId
。
-spec log(Name, Flag) -> ok | {ok, [system_event()]} when Name :: name(), Flag :: true | {true, N :: pos_integer()} | false | get | print.
-spec log(Name, Flag, Timeout) -> ok | {ok, [system_event()]} when Name :: name(), Flag :: true | {true, N :: pos_integer()} | false | get | print, Timeout :: timeout().
開啟或關閉系統事件的記錄。如果開啟,則除錯結構中會保留最多 N
個事件(預設值為 10)。
如果 Flag
是 get
,則會回傳所有已記錄事件的列表。
如果 Flag
是 print
,則已記錄的事件會列印到 standard_io
。
這些事件會使用產生事件的程序所定義的函式來格式化(透過呼叫 handle_debug/4
))。
-spec log_to_file(Name, Flag, Timeout) -> ok | {error, open_file} when Name :: name(), Flag :: (FileName :: string()) | false, Timeout :: timeout().
啟用或停用以文字格式記錄所有系統事件到檔案。事件會使用產生事件的程序定義的函式(透過呼叫 handle_debug/4
)格式化。該檔案會以 UTF-8 編碼開啟。
-spec no_debug(Name) -> ok when Name :: name().
相當於 no_debug(Name, 5000)
。
關閉程序的所有除錯。這包括使用函式 install/2,3
明確安裝的函式,例如觸發器。
-spec remove(Name, Func | FuncId, Timeout) -> ok when Name :: name(), Func :: dbg_fun(), FuncId :: term(), Timeout :: timeout().
從程序中移除已安裝的除錯函式。Func
或 FuncId
必須與先前安裝的相同。
-spec replace_state(Name, StateFun, Timeout) -> NewState when Name :: name(), StateFun :: fun((State :: term()) -> NewState :: term()), Timeout :: timeout(), NewState :: term().
取代程序的狀態,並傳回新的狀態。
注意
這些函式僅用於協助偵錯,不應從正常程式碼呼叫。它們為了方便起見而提供,讓開發人員避免必須建立自己的自訂狀態替換函式。
函式 StateFun
為程序提供新的狀態。State
引數和 StateFun
的 NewState
回傳值因不同類型的程序而異,如下所示
對於
gen_server
程序,State
是回呼模組的狀態,而NewState
是該狀態的新實例。對於
gen_statem
程序,State
是元組{CurrentState,CurrentData}
,而NewState
是一個類似的元組,其中可以包含新的目前狀態、新的狀態資料或兩者。對於
gen_event
程序,State
是元組{Module, Id, HandlerState}
,如下所示Module
- 事件處理常式的模組名稱。Id
- 處理常式的 ID(如果註冊時沒有 ID,則為false
)。HandlerState
- 處理常式的狀態。
NewState
是一個類似的元組,其中Module
和Id
的值應與State
中的值相同,但HandlerState
的值可以不同。回傳一個NewState
,其Module
或Id
值與State
的值不同,會讓事件處理常式的狀態保持不變。對於gen_event
程序,會為在gen_event
程序中註冊的每個事件處理常式呼叫一次StateFun
。
如果 StateFun
函式決定不對程序狀態進行任何變更,那麼無論程序類型為何,它都可以回傳其 State
引數。
如果 StateFun
函式崩潰或拋出例外,則對於 gen_server
和 gen_statem
程序,程序的原始狀態不會變更。對於 gen_event
程序,崩潰或失敗的 StateFun
函式表示只有它在失敗或崩潰時正在處理的特定事件處理常式的狀態不會變更;它仍然可以成功變更在同一個 gen_event
程序中註冊的其他事件處理常式的狀態。
如果回呼模組匯出 system_replace_state/2
函式,則會在目標程序中呼叫它,使用 StateFun
來取代其狀態。它的兩個引數是 StateFun
和 Misc
,其中 Misc
與 get_status/1,2
回傳的 Misc
值相同。預期 system_replace_state/2
函式會回傳 {ok, NewState, NewMisc}
,其中 NewState
是透過呼叫 StateFun
取得的回呼模組的新狀態,而 NewMisc
是一個可能的新值,用於取代原始的 Misc
(因為 Misc
通常包含其中的回呼模組的狀態,所以是必要的)。
如果回呼模組沒有匯出 system_replace_state/2
函式,replace_state/2,3
會假設 Misc
是回呼模組的狀態,將其傳遞給 StateFun
,並使用回傳值作為新狀態和 Misc
的新值。
如果回呼模組的函式 system_replace_state/2
崩潰或拋出例外,呼叫者會以錯誤 {callback_failed, {Module, system_replace_state}, {Class, Reason}}
結束,其中 Module
是回呼模組的名稱,而 Class
和 Reason
表示例外的詳細資訊。如果回呼模組沒有提供 system_replace_state/2
函式,且 StateFun
崩潰或拋出例外,呼叫者會以錯誤 {callback_failed, StateFun, {Class, Reason}}
結束。
函式 system_replace_state/2
主要用於使用者定義的行為和實作 OTP 特殊程序的模組。OTP 行為模組 gen_server
、gen_statem
和 gen_event
會匯出此函式,因此這些行為的回呼模組不需要提供自己的函式。
-spec resume(Name) -> ok when Name :: name().
相當於 resume(Name, 5000)
。
繼續已暫停的程序。
-spec statistics(Name, Flag) -> ok | {ok, Statistics} when Name :: name(), Flag :: true | false | get, Statistics :: [StatisticsTuple] | no_statistics, StatisticsTuple :: {start_time, DateTime1} | {current_time, DateTime2} | {reductions, non_neg_integer()} | {messages_in, non_neg_integer()} | {messages_out, non_neg_integer()}, DateTime1 :: file:date_time(), DateTime2 :: file:date_time().
-spec statistics(Name, Flag, Timeout) -> ok | {ok, Statistics} when Name :: name(), Flag :: true | false | get, Statistics :: [StatisticsTuple] | no_statistics, StatisticsTuple :: {start_time, DateTime1} | {current_time, DateTime2} | {reductions, non_neg_integer()} | {messages_in, non_neg_integer()} | {messages_out, non_neg_integer()}, DateTime1 :: file:date_time(), DateTime2 :: file:date_time(), Timeout :: timeout().
啟用或停用統計資料的收集。如果 Flag
是 get
,則會傳回統計資料集合。
-spec suspend(Name) -> ok when Name :: name().
等同於 suspend(Name, 5000)
。
暫停程序。當程序被暫停時,它只會回應其他系統訊息,而不會回應其他訊息。
-spec terminate(Name, Reason, Timeout) -> ok when Name :: name(), Reason :: term(), Timeout :: timeout().
命令程序以指定的 Reason
終止。終止操作是非同步進行的,因此無法保證函數返回時程序已終止。
-spec trace(Name, Flag, Timeout) -> ok when Name :: name(), Flag :: boolean(), Timeout :: timeout().
在 standard_io
上印出所有系統事件。事件會使用產生事件的程序所定義的函數來格式化(透過呼叫 handle_debug/4
)。