perldtrace - Perl 的 DTrace 支持
# dtrace -Zn 'perl::sub-entry, perl::sub-return { trace(copyinstr(arg0)) }'
dtrace: description 'perl::sub-entry, perl::sub-return ' matched 10 probes
# perl -E 'sub outer { inner(@_) } sub inner { say shift } outer("hello")'
hello
(dtrace output)
CPU ID FUNCTION:NAME
0 75915 Perl_pp_entersub:sub-entry BEGIN
0 75915 Perl_pp_entersub:sub-entry import
0 75922 Perl_pp_leavesub:sub-return import
0 75922 Perl_pp_leavesub:sub-return BEGIN
0 75915 Perl_pp_entersub:sub-entry outer
0 75915 Perl_pp_entersub:sub-entry inner
0 75922 Perl_pp_leavesub:sub-return inner
0 75922 Perl_pp_leavesub:sub-return outer
DTrace 是一个用于全面系统和应用程序级跟踪的框架。Perl 是一个 DTrace 提供者,这意味着它为检测暴露了几个探针。您可以将这些探针与内核级探针以及来自其他提供者(如 MySQL)的探针结合使用,以诊断软件缺陷,甚至只是应用程序的瓶颈。
Perl 必须使用 -Dusedtrace
选项编译才能使用提供的探针。虽然 DTrace 旨在在其检测不活动时没有开销,但 Perl 的支持本身无法保证这一点,因此它在大多数系统下没有 DTrace 探针的情况下构建。一个值得注意的例外是 Mac OS X 附带一个启用了 DTrace 支持的/usr/bin/perl。
Perl 的初始 DTrace 支持已添加,提供了 sub-entry
和 sub-return
探针。
sub-entry
和 sub-return
探针获得第四个参数:函数的包名。
添加了 phase-change
探针。
添加了 op-entry
、loading-file
和 loaded-file
探针。
跟踪任何子例程的进入。请注意,所有变量都引用正在调用的子例程;目前无法从 DTrace 操作中获取有关子例程调用者的任何信息。
:*perl*::sub-entry {
printf("%s::%s entered at %s line %d\n",
copyinstr(arg3), copyinstr(arg0), copyinstr(arg1), arg2);
}
跟踪任何子程序的退出。请注意,所有变量都引用正在返回的子程序;目前无法从 DTrace 操作中获取有关子程序的调用者的任何信息。
:*perl*::sub-return {
printf("%s::%s returned at %s line %d\n",
copyinstr(arg3), copyinstr(arg0), copyinstr(arg1), arg2);
}
跟踪 Perl 解释器状态的变化。您可以将其内化为跟踪 Perl 的 ${^GLOBAL_PHASE}
变量的变化,尤其是因为 NEWPHASE
和 OLDPHASE
的值是 ${^GLOBAL_PHASE}
报告的字符串。
:*perl*::phase-change {
printf("Phase changed from %s to %s\n",
copyinstr(arg1), copyinstr(arg0));
}
跟踪 Perl 运行循环中每个操作码的执行。此探针在执行操作码之前触发。当启用 Perl 调试器时,DTrace 探针会在调试器钩子之后触发(但在操作码本身执行之前)。
:*perl*::op-entry {
printf("About to execute opcode %s\n", copyinstr(arg0));
}
当 Perl 即将加载单个文件时触发,无论是来自 use
、require
还是 do
。此探针在从磁盘读取文件之前触发。文件名参数被转换为本地文件系统路径,而不是提供 Module::Name
样式的名称。
:*perl*:loading-file {
printf("About to load %s\n", copyinstr(arg0));
}
当 Perl 成功加载单个文件时触发,无论是来自 use
、require
还是 do
。此探针在从磁盘读取文件并评估其内容后触发。文件名参数被转换为本地文件系统路径,而不是提供 Module::Name
样式的名称。
:*perl*:loaded-file {
printf("Successfully loaded %s\n", copyinstr(arg0));
}
# dtrace -qZn 'sub-entry { @[strjoin(strjoin(copyinstr(arg3),"::"),copyinstr(arg0))] = count() } END {trunc(@, 10)}'
Class::MOP::Attribute::slots 400
Try::Tiny::catch 411
Try::Tiny::try 411
Class::MOP::Instance::inline_slot_access 451
Class::MOP::Class::Immutable::Trait:::around 472
Class::MOP::Mixin::AttributeCore::has_initializer 496
Class::MOP::Method::Wrapped::__ANON__ 544
Class::MOP::Package::_package_stash 737
Class::MOP::Class::initialize 1128
Class::MOP::get_metaclass_by_name 1204
# dtrace -qFZn 'sub-entry, sub-return { trace(copyinstr(arg0)) }'
0 -> Perl_pp_entersub BEGIN
0 <- Perl_pp_leavesub BEGIN
0 -> Perl_pp_entersub BEGIN
0 -> Perl_pp_entersub import
0 <- Perl_pp_leavesub import
0 <- Perl_pp_leavesub BEGIN
0 -> Perl_pp_entersub BEGIN
0 -> Perl_pp_entersub dress
0 <- Perl_pp_leavesub dress
0 -> Perl_pp_entersub dirty
0 <- Perl_pp_leavesub dirty
0 -> Perl_pp_entersub whiten
0 <- Perl_pp_leavesub whiten
0 <- Perl_dounwind BEGIN
# dtrace -Zn 'phase-change /copyinstr(arg0) == "END"/ { self->ending = 1 } sub-entry /self->ending/ { trace(copyinstr(arg0)) }'
CPU ID FUNCTION:NAME
1 77214 Perl_pp_entersub:sub-entry END
1 77214 Perl_pp_entersub:sub-entry END
1 77214 Perl_pp_entersub:sub-entry cleanup
1 77214 Perl_pp_entersub:sub-entry _force_writable
1 77214 Perl_pp_entersub:sub-entry _force_writable
# dtrace -qZn 'phase-change /copyinstr(arg0) == "START"/ { self->interesting = 1 } phase-change /copyinstr(arg0) == "RUN"/ { self->interesting = 0 } syscall::: /self->interesting/ { @[probefunc] = count() } END { trunc(@, 3) }'
lseek 310
read 374
stat64 1056
# dtrace -qZn 'sub-entry { self->fqn = strjoin(copyinstr(arg3), strjoin("::", copyinstr(arg0))) } op-entry /self->fqn != ""/ { @[self->fqn] = count() } END { trunc(@, 3) }'
warnings::unimport 4589
Exporter::Heavy::_rebuild_cache 5039
Exporter::import 14578
https://www.amazon.com/DTrace-Dynamic-Tracing-Solaris-FreeBSD/dp/0132091518/
此 CPAN 模块允许您使用 Perl 创建应用程序级 DTrace 探针。
Shawn M Moore [email protected]