查看源码 trace (kernel 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}
,并且默认跟踪器永远不是调用进程。
摘要
函数
等效于 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
向进程To
发送消息Msg
时。{trace, Port, send_to_non_existing_process, Msg, To}
- 当Port
向不存在的进程To
发送消息Msg
时。{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
- 跟踪进程的垃圾回收。消息标签:
gc_minor_start
,gc_max_heap_size
和gc_minor_end
。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
,而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
本身。也就是说,在第一个派生完成后,set_on_first_spawn
将在派生的进程和派生进程中都被清除。如果同时设置了两者,则
set_on_first_spawn
将取代set_on_spawn
。set_on_link
- 使由跟踪进程链接的任何进程继承其所有跟踪标志,包括标志set_on_link
本身。set_on_first_link
- 使由跟踪进程链接的第一个进程继承其所有跟踪标志,但不包括标志set_on_first_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
向进程To
发送消息Msg
时。{trace, Pid, send_to_non_existing_process, Msg, To}
- 当进程Pid
向不存在的进程To
发送消息Msg
时。{trace, Pid, 'receive', Msg}
- 当进程Pid
接收消息Msg
时。如果Msg
设置为超时,则接收语句可能已超时,或者进程接收到负载为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
应该是参数列表,但如果派生错误,则可以是任何项。{trace, Pid, spawned, Pid2, {M, F, Args}}
- 当Pid
由进程Pid2
派生,并将指定的函数调用作为入口点时。Args
应该是参数列表,但如果派生错误,则可以是任何项。{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
是一个由两元素元组组成的列表,其中第一个元素是键,第二个元素是值。不要依赖元组的任何顺序。定义了以下键heap_size
- 堆的已用部分的大小。heap_block_size
- 用于存储堆和堆栈的内存块的大小。old_heap_size
- 旧堆的已用部分的大小。old_heap_block_size
- 用于存储旧堆的内存块的大小。stack_size
- 堆栈的大小。recent_size
- 在上次垃圾回收中幸存下来的数据大小。mbuf_size
- 与进程关联的消息缓冲区的总大小。bin_vheap_size
- 从进程堆引用的唯一堆外二进制文件的总大小。bin_vheap_block_size
- 在进行垃圾回收之前,进程虚拟堆中允许的二进制文件的总大小。bin_old_vheap_size
- 从进程旧堆引用的唯一堆外二进制文件的总大小。bin_old_vheap_block_size
- 在进行垃圾回收之前,进程虚拟旧堆中允许的二进制文件的总大小。wordsize
- 对于gc_minor_start
事件,它是触发 GC 的需求大小。对于相应的gc_minor_end
事件,它是回收的内存大小 = 开始heap_size
- 结束heap_size
。
所有大小均以字为单位。
{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}
- 当全扫描垃圾回收即将开始时发送。Info
包含与消息gc_minor_start
中相同的列表。{trace, Pid, gc_major_end, Info}
- 当全扫描垃圾回收完成时发送。Info
包含与消息gc_minor_start
中相同的列表,但大小反映了全扫描垃圾回收后的新大小。
如果跟踪进程死亡或跟踪器模块返回 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
是消息项。可以使用守卫函数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'
跟踪的匹配规范可以使用所有守卫和主体函数,除了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
是消息项。可以使用守卫函数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
跟踪的匹配规范可以使用所有守卫和主体函数,除了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
也可以是一个元组 {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
。