Front page | perl.perl5.porters |
Postings from July 2011
[perl #94234] [PATCH] New DTrace probe for changes to global phase
From:
Shawn M Moore
Date:
July 7, 2011 00:31
Subject:
[perl #94234] [PATCH] New DTrace probe for changes to global phase
Message ID:
rt-3.6.HEAD-30268-1310011137-215.94234-75-0@perl.org
# New Ticket Created by Shawn M Moore
# Please include the string: [perl #94234]
# in the subject line of all future correspondence about this issue.
# <URL: https://rt.perl.org:443/rt3/Ticket/Display.html?id=94234 >
Hi porters,
I've recently developed somewhat of a DTrace kick, and I figured what better
way to shake that out of my system than by improving Perl's DTrace support?
As of 5.10.1, we have probes for subroutine entry and exit, which *does* get
us a long way, but we could do even better. There are some patches floating
around (like at
http://fosiki.com/blog/2008/02/15/blead-perl-dtrace-probes/) to
improve Perl's DTrace support in other ways. For this first new probe
(an easy and useful one: global phase changes) I decided to piggy-back on
top of Florian++'s new ${^GLOBAL_PHASE} variable, since that provides more
visibility than the aforelinked patch, and is easily understood in terms of
tangible Perl features.
My first patch does a tiny bit of refactoring to change all those literal:
PL_phase = PERL_PHASE_END;
assignments to use a new macro instead:
PERL_SET_PHASE(PERL_PHASE_END);
The second patch, the one with the actual meat in it, adds to that new
PERL_SET_PHASE macro a DTrace probe. This new probe gives DTrace users
additional visibility into _when_ certain things happen. For example, this
DTrace invocation:
sudo dtrace -qZn ':perl::phase-change /copyinstr(arg0) == "END"/ {
self->cleaning_up = 1 } :perl::sub-entry /self->cleaning_up &&
copyinstr(arg0) != "END"/ { printf("%s::%s at %s line %d\n",
copyinstr(arg3), copyinstr(arg0), copyinstr(arg1), arg2) }'
will list all of the function calls made during interpreter cleanup
(excluding the sneaky sorta-function "END"). You might use this to help
diagnose why the interpreter doesn't exit immediately after the main
processing is done. You can play with it by running this one-liner in
another shell:
perl -MFile::Temp -MTest::Builder -e 'sub foo {} sub bar {} END { foo } bar'
which for me gives:
main::foo at -e line 1
Test::Builder::_ending at
/Users/sartak/.perl/perls/dtrace/lib/5.15.0/Test/Builder.pm line 2389
Test::Builder::__ANON__ at
/Users/sartak/.perl/perls/dtrace/lib/5.15.0/Test/Builder.pm line 1592
File::Temp::cleanup at
/Users/sartak/.perl/perls/dtrace/lib/5.15.0/File/Temp.pm line 877
Test::Builder::DESTROY at
/Users/sartak/.perl/perls/dtrace/lib/5.15.0/Test/Builder.pm line 376
Test::Builder::parent at
/Users/sartak/.perl/perls/dtrace/lib/5.15.0/Test/Builder.pm line 361
Other use cases might be to investigate how many system calls are being made
at compile time, for performance tuning something like Moose (which is my
actual interest here). This DTrace invocation:
dtrace -qZn ':perl::phase-change /copyinstr(arg0) == "START"/ {
self->interesting = 1 } :perl::phase-change /copyinstr(arg0) == "RUN"/ {
self->interesting = 0 } syscall::: /self->interesting/ { @[probefunc] =
count() } END { trunc(@, 3) }'
produces the top three most-used syscalls for the above Perl one-liner:
read 152
ioctl 156
stat64 470
Please let me know if there are any reservations about these patches. Keep
in mind that unless you specifically use -Dusedtrace, DTrace support carries
NO performance penalty. DTrace does quite a bit of gymnastics to ensure that
there is no performance penalty during runtime, but as I understand it,
Perl's DTrace support is not quite at that ideal yet. I'll have to
investigate that one, since from what I can see in the perl source there
should be no latent penalty.
Cheers,
Shawn
P.S. Is there a leading DTrace expert already on p5p, or did I just
volunteer myself for the position? :P
-
[perl #94234] [PATCH] New DTrace probe for changes to global phase
by Shawn M Moore