Front page | perl.perl5.porters |
Postings from November 2008
[perl #60890] perl5db.pl corrupts $SIG{__DIE__} in BEGIN blocks
Thread Next
From:
John Siracusa
Date:
November 28, 2008 05:19
Subject:
[perl #60890] perl5db.pl corrupts $SIG{__DIE__} in BEGIN blocks
Message ID:
rt-3.6.HEAD-10965-1227828090-347.60890-75-0@perl.org
# New Ticket Created by John Siracusa
# Please include the string: [perl #60890]
# in the subject line of all future correspondence about this issue.
# <URL: http://rt.perl.org/rt3/Ticket/Display.html?id=60890 >
This is a bug report for perl from siracusa@gmail.com,
generated with the help of perlbug 1.36 running under perl 5.10.0.
-----------------------------------------------------------------
Much of this report is copied and pasted from the following URL:
http://stackoverflow.com/questions/322173
Consider the following code:
BEGIN
{
package MyEx;
sub new { bless {}, shift }
package main;
eval { die MyEx->new };
if($@)
{
die "Really die" unless($@->isa('MyEx'));
}
}
print "OK\n";
Run it and it prints "OK" as expected. Run it in the debugger, however,
and it dies with this error:
Can't call method "isa" without a package or object reference ...
The upshot is that $@ is not an object when the code runs under the
debugger. Instead, it's an unblessed scalar containing this string:
" at somefile.pl line 9
eval {...} called at somefile.pl line 9
main::BEGIN() called at somefile.pl line 16
eval {...} called at somefile.pl line 16
"
(Internal newlines and spacing preserved. That's the literal text of the
string, including the "..."s.)
Setting dieLevel to 0, either through the use of a ~/.perldb file containing:
parse_options('dieLevel=0')
or by setting the PERLDB_OPT environment variablt to "dieLevel=0", did not
solve the problem.
local()izing $SIG{__DIE__} inside the eval block is a workaround, but
should not be necessary and is not done in much real code. This makes it
impossible to use the debugger during the development of such code (e.g.,
several of my larger CPAN modules).
Here's an explanation of the bug from brian d foy:
---
This is a problem with perl5db.pl creating __DIE__ handlers. If I localize
$SIG{__DIE__} in your eval, things work as you expect.
eval
{
local $SIG{__DIE__};
die MyEx->new;
};
If you don't do that, you're getting the handler from DB::dbdie, which uses
Carp::longmess. That shouldn't happen if dieLevel is 0, but by default it
is 1, and it gets set to 1 if it is not defined. This was a patch to
perl5db.pl back in 2001, and previously the default had been 0.
You're supposed to turn this off with:
PERLDB_OPT="dieLevel=0" perl5.10.0 -d program
But there is still a code reference in $SIG{__DIE__} after that, and it's a
reference to dbdie. I think this is a bug in handling the global variable
$prevdie in perl5db.pl's dieLevel. At the end of that subroutine, there is:
# perl5db.pl dieLevel, around line 7777
elsif ($prevdie) {
$SIG{__DIE__} = $prevdie;
print $OUT "Default die handler restored.\n";
}
But notice that after restoring $SIG{__DIE__}, it keeps the previous value
in $prevdie, meaning whatever is in there leaks to another call. When I run
that command line, there are two calls to dieLevel before it handles
PERLDB_OPT, so $prevdie is probably dirty.
So, that's as far as I got before I didn't want to think about perl5db.pl
anymore.
---
It seems like another workaround could be to change the default dieLevel
back to 0 instead of 1.
BTW, the "perldoc perldebug" documentation seems to imply that the default
value of dieLevel is still 0:
"By default, the debugger leaves your exceptions and warnings alone,
because altering them can break correctly running programs."
so apparently that patch in 2001 that brian refers to only updated the
code, but not the docs.
-John
-----------------------------------------------------------------
---
Flags:
category=utilities
severity=high
---
Site configuration information for perl 5.10.0:
Configured by john at Sat Sep 20 20:27:53 EDT 2008.
Summary of my perl5 (revision 5 version 10 subversion 0) configuration:
Platform:
osname=darwin, osvers=9.5.0, archname=darwin-2level
uname='darwin link.local 9.5.0 darwin kernel version 9.5.0: wed
sep 3 11:29:43 pdt 2008; root:xnu-1228.7.58~1release_i386 i386 '
config_args=''
hint=recommended, useposix=true, d_sigaction=define
useithreads=undef, usemultiplicity=undef
useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
use64bitint=undef, use64bitall=undef, uselongdouble=undef
usemymalloc=n, bincompat5005=undef
Compiler:
cc='cc', ccflags ='-fno-common -DPERL_DARWIN -no-cpp-precomp
-fno-strict-aliasing -pipe -I/usr/local/include',
optimize='-O3',
cppflags='-no-cpp-precomp -fno-common -DPERL_DARWIN
-no-cpp-precomp -fno-strict-aliasing -pipe -I/usr/local/include'
ccversion='', gccversion='4.0.1 (Apple Inc. build 5488)', gccosandvers=''
intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16
ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t',
lseeksize=8
alignbytes=8, prototype=define
Linker and Libraries:
ld='env MACOSX_DEPLOYMENT_TARGET=10.3 cc', ldflags =' -L/usr/local/lib'
libpth=/usr/local/lib /usr/lib
libs=-ldbm -ldl -lm -lutil -lc
perllibs=-ldl -lm -lutil -lc
libc=/usr/lib/libc.dylib, so=dylib, useshrplib=false, libperl=libperl.a
gnulibc_version=''
Dynamic Linking:
dlsrc=dl_dlopen.xs, dlext=bundle, d_dlsymun=undef, ccdlflags=' '
cccdlflags=' ', lddlflags=' -bundle -undefined dynamic_lookup
-L/usr/local/lib'
Locally applied patches:
---
@INC for perl 5.10.0:
/usr/local/lib/perl5/5.10.0/darwin-2level
/usr/local/lib/perl5/5.10.0
/usr/local/lib/perl5/site_perl/5.10.0/darwin-2level
/usr/local/lib/perl5/site_perl/5.10.0
.
---
Environment for perl 5.10.0:
DYLD_LIBRARY_PATH (unset)
HOME=/Users/john
LANG=en_US
LANGUAGE (unset)
LC_ALL=C
LD_LIBRARY_PATH (unset)
LOGDIR (unset)
PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin:/usr/X11R6/bin:/usr/local/mysql/bin:/usr/local/pgsql/bin:/Developer/Tools:/Users/john/bin:/usr/local/teTeX/bin/powerpc-apple-darwin6.8:.
PERLDB_OPT=dieLevel=0
PERL_BADLANG (unset)
PERL_READLINE_NOWARN=
SHELL=/bin/tcsh
Thread Next
-
[perl #60890] perl5db.pl corrupts $SIG{__DIE__} in BEGIN blocks
by John Siracusa