查看源代码 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
来处理请求。关闭消息。如果进程捕获退出,它必须能够处理来自其父进程(即 supervisor)的关闭请求。来自父进程的消息
{'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
传递给此函数。
打印调试结构中记录的系统事件,使用 FormFunc
作为通过调用 handle_debug/4
生成事件时定义的函数。
函数
获取进程的状态。
获取进程的状态。
启用安装替代的调试函数。此类函数的一个示例是触发器,即等待某些特殊事件并在生成事件时执行某些操作的函数。例如,打开低级别跟踪。
打开或关闭系统事件的日志记录。如果打开,则在调试结构中最多保留 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}
- 当回调模块返回{reply,To,Msg}
操作时,由gen_statem
产生,将回复Msg
发送回To
。To
的类型与gen_statem:reply/2
的第一个参数相同。{out,Msg,To,State}
- 当回调模块返回{reply,...}
元组时,由gen_server
产生,将回复Msg
发送回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}
- 当它在状态State
中以原因Reason
终止时,由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()].
打印调试结构中记录的系统事件,使用 FormFunc
作为通过调用 handle_debug/4
生成事件时定义的函数。
函数
-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
)。