查看源码 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
程序的全面示例,这些示例将帮助您入门。另一个信息来源是运行时工具用户指南中的 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 服务器。