develooper Front page | perl.perl5.porters | Postings from April 2004

Perl bugs hitting &DB::sub, affecting Devel::Profile

From:
Chip Salzenberg
Date:
April 29, 2004 13:13
Subject:
Perl bugs hitting &DB::sub, affecting Devel::Profile
Message ID:
20040429201258.GQ16913@perlsupport.com
I've just discovered that Perl, up through 5.8.3 at least, enforces
(by accident) a couple of restrictions on &DB::sub:

 * no calling XSUBs (before calling target sub, anyway)
 * no using regexes

The penalty for violating the first restriction is that PL_curcop is
wrong in the target XSUB, causing unqualified symbol lookups to go to
the wrong package (DB).  That can be worked around by making all such
symbol lookups fully qualified, so PL_curcop isn't used.  This hasn't
been a big problem with Devel::Profile presumably because symbolic
lookups in XSUBs are rare.

(Grep Perl for "PL_curcopdb" and you'll see that the first XSUB called
by &DB::sub is ass_u_med to be the target function for debugging.
That call gets the right PL_curcop; other XSUB calls don't.  And since
Devel::Profile uses Time::HiRes, it always makes extra XSUB calls.)

The penalty for violating the second restriction is a core dump (if
!DEBUGGING) or a panic (if DEBUGGING).  I think it only triggers when
the substitution expression in an s///e includes a function call.

Below is a patch to Devel::Profile to avoid regex usage in &DB::sub.
With this patch I'm profiling some Big Code without incident.  OTOH,
I still had to make some symbolic lookups in XS code fully qualified,
because I haven't fixed either of the basic bugs.  OTGH, this patch
makes Devel::Profile a bit faster, so there's no harm in applying it.

--- Devel/Profile.pm.P	2003-12-08 18:43:05.000000000 -0500
+++ Devel/Profile.pm	2004-04-29 14:14:08.330970000 -0400
@@ -114,6 +114,6 @@
     
     my $st = $tacc;	# accum time at start
-    my $sx = "$sub";
-    if( $sx =~ /CODE/ ){
+    my $sx = $sub;
+    if( ref $sx ){
 	my @c = caller;
 	# was 0, now 1
@@ -262,5 +262,5 @@
 	my $sp = $s;
 
-	if( $sp =~ /^<anon>/ ){
+	if( substr($sp, 0, 6) eq '<anon>' ){
 	    # make prettier
 	    if( length($sp) > 35 ){

-- 
Chip Salzenberg            - a.k.a. -             <chip@pobox.com>
'"Bob" is two dimensional, and that is what gives Him such depth.'



nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About