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 は、システムレベルおよびアプリケーションレベルの包括的な トレースフレームワークです。 カーネルレベルのプローブと、MySQL のようなその他のプロバイダの プローブを組み合わせて使うことができ、 ソフトウェアの欠陥や、単にアプリケーションのボトルネックを 診断できます。
提供されているプローブを使うには、Perl は -Dusedtrace
オプション付きで コンパイルされていなければなりません。 DTrace は、機能が有効でないときにはオーバーヘッドがないことを 目指していますが、Perl 対応自体はそれを守ることはできないので、 ほとんどのシステムでは DTrace プローブなしでビルドされています。 注目すべき一つの例外として、Mac OS X は /usr/bin/perl を DTrace 対応を 有効にして出荷されています。
- 5.10.1
-
Perl の最初の DTrace 対応が追加されました;
sub-entry
sub-return
プローブが提供されました。 - 5.14.0
-
sub-entry
とsub-return
プローブが第 4 引数を取るようになりました: 関数のパッケージ名です。 - 5.16.0
-
phase-change
プローブが追加されました。 - 5.18.0
-
op-entry
,loading-file
,loaded-file
プローブが追加されました。
(プローブ)
- sub-entry(SUBNAME, FILE, LINE, PACKAGE)
-
任意のサブルーチンの入り口をトレースします。 全ての変数は起動されようとしているサブルーチンを参照していることに 注意してください; 現在の所、DTrace のアクションからサブルーチンの 呼び出し元 に関する情報を得る方法はありません。
:*perl*::sub-entry { printf("%s::%s entered at %s line %d\n", copyinstr(arg3), copyinstr(arg0), copyinstr(arg1), arg2); }
- sub-return(SUBNAME, FILE, LINE, PACKAGE)
-
任意のサブルーチンの出口をトレースします。 全ての変数は返ろうとしているサブルーチンを参照していることに 注意してください; 現在の所、DTrace のアクションからサブルーチンの 呼び出し元 に関する情報を得る方法はありません。
:*perl*::sub-return { printf("%s::%s returned at %s line %d\n", copyinstr(arg3), copyinstr(arg0), copyinstr(arg1), arg2); }
- phase-change(NEWPHASE, OLDPHASE)
-
Perl のインタプリタ状態の変更をトレースします。 Perl の
${^GLOBAL_PHASE}
変数の変更をトレースすることで これを内部化できます; 特にNEWPHASE
とOLDPHASE
の値は、${^GLOBAL_PHASE}
が報告する 文字列だからです。:*perl*::phase-change { printf("Phase changed from %s to %s\n", copyinstr(arg1), copyinstr(arg0)); }
- op-entry(OPNAME)
-
Perl の runloop の中での個々のオペコードの実行をトレースします。 このプローブは、オペコードが実行される前に起動されます。 Perl デバッガが有効の場合、 DTrace プローブは、デバッガフックの 後に 起動されます (しかしやはりオペコード自体が実行される前です)。
:*perl*::op-entry { printf("About to execute opcode %s\n", copyinstr(arg0)); }
- loading-file(FILENAME)
-
Perl が、
use
,require
,do
のどれかに関わらず、 個々のファイルを読み込もうとするときに発動します。 このプローブはファイルがディスクから読み込まれる前に発動します。 ファイル名引数は、指定されたModule::Name
型の名前ではなく、 ローカルファイルシステムパスに変換されます。:*perl*:loading-file { printf("About to load %s\n", copyinstr(arg0)); }
- loaded-file(FILENAME)
-
Perl が、
use
,require
,do
のどれかに関わらず、 個々のファイルの読み込みに成功したときに発動します。 このプローブはファイルがディスクから読み込まれ、その内容が評価された後に 発動します。 ファイル名引数は、指定されたModule::Name
型の名前ではなく、 ローカルファイルシステムパスに変換されます。:*perl*:loaded-file { printf("Successfully loaded %s\n", copyinstr(arg0)); }
- Most frequently called functions
-
(もっともよく呼び出される関数)
# 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
- Trace function calls
-
(関数呼び出しのトレース)
# 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
- Function calls during interpreter cleanup
-
(インタプリタのクリーンアップ中の関数呼び出し)
# 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
- System calls at compile time
-
(コンパイル時のシステムコール)
# 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
- Perl functions that execute the most opcodes
-
(もっとも多いオペコードを実行する Perl の関数)
# 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
- DTrace Dynamic Tracing Guide
- DTrace: Dynamic Tracing in Oracle Solaris, Mac OS X and FreeBSD
-
http://www.amazon.com/DTrace-Dynamic-Tracing-Solaris-FreeBSD/dp/0132091518/
- Devel::DTrace::Provider
-
この CPAN モジュールは、Perl で書かれたアプリケーションレベルの DTrace プローブを作れるようにします。
Shawn M Moore sartak@gmail.com