查看源码 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

仅限节点本地跟踪

此模块中的函数仅在本地节点上运行。也就是说,被跟踪的进程/端口以及跟踪器进程/端口/模块都必须与进行调用的本地节点位于同一节点上。要跟踪远程节点,请使用 dbgttb

更改

trace 模块是在 OTP 27.0 中引入的。接口和语义与旧函数 erlang:trace/3erlang:trace_pattern/3erlang:trace_info/2 类似。

主要区别在于,旧函数在每个节点上操作一个静态的跟踪会话。这可能会导致不同用户和工具相互干扰跟踪设置的问题。此模块中的新跟踪函数都在动态创建的、彼此隔离的跟踪会话上操作。此外,这使得通过一次调用 session_destroy/1 来安全禁用所有跟踪设置变得更容易。

要更改现有工具以使用该接口,下表可能很有用

旧的函数调用对应于
erlang:trace(Pid, ...)process(S, Pid, ...)
erlang:trace(processes, ...)process(S, all, ...)
erlang:trace(existing_processes, ...)process(S, existing, ...)
erlang:trace(new_processes, ...)process(S, new, ...)
erlang:trace(Port, ...)port(S, Port, ...)
erlang:trace(ports, ...)port(S, all, ...)
erlang:trace(existing_ports, ...)port(S, existing, ...)
erlang:trace(new_ports, ...)port(S, new, ...)
erlang:trace(all, ...)process(S, all, ...)port(S, all, ...)
erlang:trace(existing, ...)process(S, existing, ...)port(S, existing, ...)
erlang:trace(new, ...)process(S, new, ...)port(S, new, ...)
erlang:trace_pattern(MFA, ...)function(S, MFA, ...)
erlang:trace_pattern(send, ...)send(S, ...)
erlang:trace_pattern('receive', ...)recv(S, ...)
erlang:trace_info(...)info(S, ...)

参数 S 是必须首先使用 session_create/3 创建的跟踪会话。其他参数(由 ... 暗示)基本相同。唯一的其他区别是,跟踪器始终是创建会话时指定的跟踪器。因此不允许使用选项 {tracer,T}{tracer,M,S}{meta,T}{meta,M,S},并且默认跟踪器永远不是调用进程。

摘要

类型

隔离跟踪会话的句柄。

session_info/1 返回的弱会话句柄。弱会话句柄可以像完全会话句柄一样使用,但当最后一个强句柄被垃圾回收时,它不会阻止会话被销毁。

函数

等效于 erlang:trace_delivered(Tracee),只是它在给定的 session/0 中运行。

启用或禁用一个或多个函数的调用跟踪

返回有关端口、进程、函数或事件的跟踪信息。

为一个或多个端口打开或关闭跟踪标志。

为一个或多个进程打开或关闭跟踪标志。

设置消息接收的跟踪模式。

设置消息发送的跟踪模式。

创建一个新的跟踪会话。

销毁跟踪会话并清除其在进程、端口和函数上的所有设置。

返回影响端口、进程、函数或事件的跟踪会话。

类型

链接到此类型

match_variable()

查看源码 (未导出) (自 OTP 27.0 起)
-type match_variable() :: atom().
链接到此类型

session()

查看源码 (自 OTP 27.0 起)
-type session() :: {session_strong_ref(), session_weak_ref()} | session_weak_ref().

隔离跟踪会话的句柄。

链接到此不透明类型

session_strong_ref()

查看源码 (自 OTP 27.0 起)
-opaque session_strong_ref()
链接到此不透明类型

session_weak_ref()

查看源码 (自 OTP 27.0 起)
-opaque session_weak_ref()

session_info/1 返回的弱会话句柄。弱会话句柄可以像完全会话句柄一样使用,但当最后一个强句柄被垃圾回收时,它不会阻止会话被销毁。

链接到此类型

trace_flag()

查看源码 (未导出) (自 OTP 27.0 起)
-type trace_flag() :: trace_info_flag() | all | cpu_timestamp.
链接到此类型

trace_info_flag()

查看源码 (未导出) (自 OTP 27.0 起)
-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.
链接到此类型

trace_info_item_result()

查看源码 (未导出) (自 OTP 27.0 起)
-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}.
链接到此类型

trace_info_return()

查看源码 (未导出) (自 OTP 27.0 起)
-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}.
链接到此类型

trace_match_spec()

查看源码 (未导出) (自 OTP 27.0 起)
-type trace_match_spec() :: [{[term()] | '_' | match_variable(), [term()], [term()]}].
链接到此类型

trace_pattern_flag()

查看源码 (未导出) (自 OTP 27.0 起)
-type trace_pattern_flag() ::
          global | local | meta |
          {meta, Pid :: pid()} |
          {meta, TracerModule :: module(), TracerState :: term()} |
          call_count | call_time | call_memory.
链接到此类型

trace_pattern_mfa()

查看源码 (未导出) (自 OTP 27.0 起)
-type trace_pattern_mfa() :: {atom(), atom(), arity() | '_'}.

函数

链接到此函数

delivered(Session, Tracee)

查看源码 (自 OTP 27.0 起)
-spec delivered(Session :: session(), Tracee :: pid() | all) -> reference().

等效于 erlang:trace_delivered(Tracee),只是它在给定的 session/0 中运行。

链接到此函数

function(Session, MFA, MatchSpec, FlagList)

查看源码 (自 OTP 27.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_countcall_timecall_memory:重新启动现有的计数器。对于其他 FlagList 选项,行为未定义。

  • pause - 对于 FlagList 选项 call_countcall_timecall_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 - 为所有类型的函数调用启动 (MatchSpectrue) 或停止 (MatchSpecfalse) 调用时间跟踪。对于每个函数,当该函数被调用时,计数器会递增,并且在函数中花费的时间会被测量并累积到另一个计数器中。计数器存储在每个跟踪调用的进程中。

    如果在已经运行时启动调用时间跟踪,则计数和时间将从零重新开始。要暂停正在运行的计数器,请使用 MatchSpec == pause。可以使用 MatchSpec == restart 从零重新启动已暂停和正在运行的计数器。

    要读取计数器值,请使用 info/3

  • call_memory - 为所有类型的函数调用启动 (MatchSpec == true) 或停止 (MatchSpec == false) 调用内存跟踪。

    如果在已经运行时启动调用内存跟踪,则计数器和分配将从零重新开始。要暂停正在运行的计数器,请使用 MatchSpec == pause。可以使用 MatchSpec == restart 从零重新启动已暂停和正在运行的计数器。

    要读取计数器值,请使用 info/3

选项 global 不能与任何其他选项组合,所有其他选项都执行某种局部跟踪。如果为一组函数指定了全局跟踪,则将禁用该匹配函数集的 localmetacall_countcall_timecall_memory 跟踪,反之亦然。

禁用跟踪时,该选项必须与在函数上设置的跟踪类型匹配。也就是说,必须使用选项 local 禁用局部跟踪,使用选项 global (或没有选项)禁用全局跟踪,依此类推。

匹配规范的一部分不能直接更改。如果函数具有匹配规范,则可以用新的匹配规范替换它。函数 info/3 可用于检索现有的匹配规范。

返回与参数 MFA 匹配的函数数量。如果没有任何匹配或指定了 on_load,则返回零。

如果发生以下情况,则会引发错误异常并失败:

  • badarg - 如果参数无效。

  • system_limit - 如果作为参数传递的匹配规范具有过多的嵌套,导致调用进程在其上执行的调度程序耗尽调度程序堆栈。调度程序堆栈大小可以在启动运行时系统时进行配置。

链接到此函数

info(Session, PidPortFuncEvent, Item)

查看源代码 (自 OTP 27.0 起)
-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/3session_info/1 返回。

要获取有关端口或进程的信息PidPortFuncEvent 必须是进程标识符(pid)、端口标识符,或者原子 newnew_processesnew_ports 之一。原子 newnew_processes 表示返回要创建的进程的默认跟踪状态。原子 new_ports 表示返回要创建的端口的默认跟踪状态。

端口和进程的有效 Item 值:

  • flags - 返回一个原子列表,指示为进程启用了哪种类型的跟踪。如果未启用跟踪,则列表为空;如果启用了跟踪,则列表包含一个或多个 trace_info_flag()。顺序是任意的。

  • tracer - 返回跟踪此进程的进程、端口的标识符,或者包含跟踪器模块和跟踪器状态的元组。如果未跟踪此进程,则返回值为 []

要获取有关函数的信息PidPortFuncEvent 必须是三元素元组 {Module, Function, Arity} 或原子 on_load。不允许使用通配符。如果函数不存在,则返回 undefined;如果未跟踪该函数,则返回 false。如果 PidPortFuncEventon_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 是调用计数。SUs 是以秒和微秒表示的累积调用时间。

    另请参阅 function/4

  • call_memory - 返回此函数累计分配的字数。累积在下一个内存跟踪函数处停止:如果有 outermiddleinner 函数,每个函数都分配 3 个字,但只跟踪 outer,它将报告 9 个已分配的字。如果跟踪 outerinner,则为 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,或者不存在的函数的名称,则 Valueundefined

链接到此函数

port(Session, Ports, How, FlagList)

查看源代码 (自 OTP 27.0 起)
-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 - 跟踪消息的发送。

    消息标签:sendsend_to_non_existing_process

  • 'receive' - 跟踪消息的接收。

    消息标签:'receive'

  • ports - 跟踪与端口相关的事件。

    消息标签:openclosedregisterunregistergetting_linkedgetting_unlinked

  • running_ports - 跟踪端口的调度。

    消息标签:inout

  • timestampcpu_timestampmonotonic_timestampstrict_monotonic_timestamp - 与 process/4 中的时间戳相同。

跟踪进程接收以下列表中描述的跟踪消息Port 是发生跟踪事件的被跟踪端口的端口标识符。第三个元组元素是消息标签。

如果指定了标志 timestampstrict_monotonic_timestampmonotonic_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} - 当 PortReason 而关闭时。

  • {trace, Port, in, Command | 0} - 当 Port 被调度运行时。Command 是端口将要执行的第一件事,但它可以在被调度出去之前运行多个命令。在某些极少数情况下,无法确定当前函数,则最后一个元素为 0

    可能的命令为 callclosecommandconnectcontrolflushinfolinkopenunlink

  • {trace, Port, out, Command | 0} - 当 Port 被调度出时。上次运行的命令是 Command。在某些极少数情况下,无法确定当前函数,则最后一个元素为 0Command 可以包含与 in 相同的命令

如果跟踪进程/端口死亡或跟踪器模块返回 remove,则这些标志会被静默删除。

返回一个数字,指示与 Ports 匹配的端口数。如果 Ports 是一个端口标识符,则返回值为 1。如果 Portsallexisting,则返回值是现有端口的数量。如果 Portsnew,则返回值为 0

失败:如果指定的参数不受支持,则 badarg。例如,并非所有平台都支持 cpu_timestamp

链接到此函数

process(Session, Procs, How, FlagList)

查看源代码 (自 OTP 27.0 起)
-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 - 将来创建的所有进程。

参数 Howtrue(打开跟踪标志)或 false(关闭跟踪标志)。

参数 FlagList 可以包含以下任意数量的标志(“消息标签”指的是 跟踪消息 列表)

  • all - 设置除 cpu_timestamp 之外的所有跟踪标志,这些标志本质上与其他标志不同。

  • send - 跟踪消息的发送。通过调用 send/3 限制要跟踪的已发送消息。

    消息标签:sendsend_to_non_existing_process

  • 'receive' - 跟踪消息的接收。通过调用 recv/3 限制要跟踪的已接收消息。

    消息标签:'receive'

  • call - 跟踪某些函数调用。通过调用 function/4 指定要跟踪的函数调用。

    消息标签:callreturn_from

  • silent - 与 call 跟踪标志一起使用。如果设置此标志,则会禁止 callreturn_fromreturn_to 跟踪消息,但如果存在匹配规范,则它们会像正常情况下一样执行。

    执行 trace:process(_, _, false, [silent|_]) 或通过执行函数 {silent, false} 的匹配规范来抑制静默模式。

    silent 跟踪标志有助于在系统中的许多甚至所有进程上设置跟踪。然后可以使用匹配规范函数 {silent,Bool} 激活和停用该跟踪,从而高度控制哪些函数以及哪些参数触发该跟踪。

    消息标签:callreturn_fromreturn_to。或者,更确切地说,是没有。

  • return_to - 与 call 跟踪标志一起使用。跟踪从调用跟踪的函数返回到执行恢复的位置。仅适用于使用选项 local 跟踪的函数,请参阅 function/4

    其语义是,当调用跟踪的函数返回或抛出并捕获异常时,会发送 return_to 跟踪消息。对于尾调用,每个尾调用链仅发送一条跟踪消息,因此在以此标志跟踪时,会保留函数调用的尾递归属性。对于异常也是如此,即使异常在被捕获之前传递了多个调用跟踪的函数,也仅发送一条 return_to 跟踪消息。

    一起使用 callreturn_to 跟踪可以准确知道进程在任何时间执行哪个函数。

    要获取包含函数返回值的跟踪消息,请使用 {return_trace} 匹配规范操作。

    消息标签:return_to

  • procs - 跟踪与进程相关的事件。

    消息标签:spawn, spawned, exit, register, unregister, link, unlink, getting_linkedgetting_unlinked

  • running - 跟踪进程的调度。

    消息标签:inout

  • exiting - 跟踪正在退出的进程的调度。

    消息标签:in_exiting, out_exitingout_exited

  • running_procs - 跟踪进程的调度,与 running 类似。但是,此选项还包括进程在端口的上下文中执行时(而不是被调度出去时)的调度事件。

    消息标签:inout

  • garbage_collection - 跟踪进程的垃圾回收。

    消息标签:gc_minor_start, gc_max_heap_sizegc_minor_end

  • timestamp - 在所有跟踪消息中包含时间戳。时间戳 (Ts) 的格式与 erlang:now/0 返回的格式相同。

  • cpu_timestamp - Erlang 节点的全局跟踪标志,使所有使用 timestamp 标志的跟踪时间戳都使用 CPU 时间,而不是挂钟时间。也就是说,如果启用了 monotonic_timestampstrict_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 是发生跟踪事件的被跟踪进程的进程标识符。第三个元组元素是消息标签。

如果指定了标志 timestampstrict_monotonic_timestampmonotonic_timestamp,则第一个元组元素为 trace_ts,并且时间戳将作为消息元组中的最后一个额外元素添加。

如果匹配规范(仅适用于 callsend'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 返回指定的函数时。如果同时设置了 callreturn_to 标志,并且该函数设置为跟踪本地函数调用,则会发送此跟踪消息。仅当从尾递归函数调用链返回时才会发送该消息,其中至少一个调用生成了 call 跟踪消息(即,函数匹配规范匹配,并且 {message, false} 不是一个操作)。

  • {trace, Pid, return_from, {M, F, Arity}, ReturnValue} - 当 Pid 从指定的函数返回。如果设置了标志 call,并且该函数具有带有 return_traceexception_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。如果 Procsallexisting,则返回值为正在运行的进程数。如果 Procsnew,则返回值为 0

失败:如果指定的参数不受支持,则 badarg。例如,并非所有平台都支持 cpu_timestamp

链接到此函数

recv(Session, MatchSpec, FlagList)

查看源代码 (自 OTP 27.0 起)
-spec recv(Session, MatchSpec, FlagList) -> non_neg_integer()
              when Session :: session(), MatchSpec :: trace_match_spec() | boolean(), FlagList :: [].

设置消息接收的跟踪模式。

必须与 process/4port/4 结合使用,才能为一个或多个进程或端口设置 'receive' 跟踪标志。

参数 Session 是要操作的跟踪会话,由 session_create/3 返回。

每个会话中 receive 跟踪模式的默认值为 true。也就是说,所有具有 'receive' 跟踪功能的进程收到的所有消息都将被跟踪。使用此函数可以根据消息内容、发送者和/或接收者来限制跟踪的 'receive' 事件。

参数 MatchSpec 可以采用以下形式

  • MatchExpression - 一个匹配规范。匹配是在列表 [Node, Sender, Msg] 上完成的。 Node 是发送者的节点名称。 Sender 是发送者的进程或端口标识,如果发送者未知(对于远程发送者来说可能是这种情况),则为原子 undefinedMsg 是消息项。可以使用守卫函数 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, silentprocess_dump

如果发生以下情况,则会引发错误异常并失败:

  • badarg - 如果参数无效。

  • system_limit - 如果作为参数传递的匹配规范具有过多的嵌套,导致调用进程在其上执行的调度程序耗尽调度程序堆栈。调度程序堆栈大小可以在启动运行时系统时进行配置。

链接到此函数

send(Session, MatchSpec, FlagList)

查看源代码 (自 OTP 27.0 起)
-spec send(Session, MatchSpec, FlagList) -> non_neg_integer()
              when Session :: session(), MatchSpec :: trace_match_spec() | boolean(), FlagList :: [].

设置消息发送的跟踪模式。

必须与 process/4port/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 - 如果作为参数传递的匹配规范具有过多的嵌套,导致调用进程在其上执行的调度程序耗尽调度程序堆栈。调度程序堆栈大小可以在启动运行时系统时进行配置。

链接到此函数

session_create(Name, Tracer, Opts)

查看源代码 (自 OTP 27.0 起)
-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 一样。

链接到此函数

session_destroy(Session)

查看源代码 (自 OTP 27.0 起)
-spec session_destroy(Session) -> true | false when Session :: session().

销毁跟踪会话并清除其在进程、端口和函数上的所有设置。

唯一未清理的是已发送的跟踪消息。

如果会话处于活动状态,则返回 true。如果会话已被更早对此函数的调用或垃圾回收器销毁,则返回 false

链接到此函数

session_info(PidPortFuncEvent)

查看源代码 (自 OTP 27.0 起)
-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