Closed p5pRT closed 20 years ago
This report has been registered with perlbug.
Von: perlbug@perl.org [mailto:perlbug@perl.org] Gesendet am: Tuesday\, June 01\, 1999 3:09 AM An: brettle@his.com Betreff: perlbug rejection: DESTROY() interferes with die()
This email address is for reporting bugs to the perl community via
perlbug@perl.org.
Please address your mail appropriately and include output from the
perlbug program as per the distributed documentation.
Hint: mail should include 'perl -v' and it's output.
From brettle@his.com Mon May 31 21:08:57 1999
Received: from jhereg.perl.com (IDENT:root@perl.com [199.45.135.9]) by
defender.perl.org (8.9.3/8.9.3/Debian/GNU) with ESMTP id VAA30256 for
\perlbugtron@​perl\.org; Mon\, 31 May 1999 21:08:53 -0400
From: brettle@his.com
Received: from smtp1.mindspring.com (smtp1.mindspring.com [207.69.200.31])
by jhereg.perl.com (8.9.0/8.9.0) with ESMTP id QAA30568 for
\perlbug@​perl\.com; Mon\, 31 May 1999 16:56:27 -0600
Received: from server.brettle.com (user-33qsua6.dialup.mindspring.com
[199.174.121.70]) by smtp1.mindspring.com (8.8.5/8.8.5) with ESMTP id
SAA13505; Mon\, 31 May 1999 18:56:38 -0400 (EDT)
Received: (from brettle@localhost) by server.brettle.com (8.8.7/8.8.7) id
PAA19201; Mon\, 31 May 1999 15:55:46 -0700
Date: Mon\, 31 May 1999 15:55:46 -0700
Message-Id: \199905312255\.PAA19201@​server\.brettle\.com
To: perlbug@perl.com
Subject: DESTROY() interferes with die()
Cc: dean@brettle.com
Reply-To: dean@brettle.com
This is a bug report for perl from dean@brettle.com\, generated with the help of perlbug 1.26 running under perl 5.00405.
-----------------------------------------------------------------
Hi all\,
Here is a little perl which illustrates the problem. Commentary follows.
package C;
sub new { my $self = bless {}; return $self; }
sub DESTROY { eval { print "This eval resets \$\@\, which is BAD\n"; }; }
eval { my $o = new C; die "This error should be caught but isn't"; };
if ($@) { print "Caught: $@"; } else { print "Error missed due to perl bug\n"; }
Here is what is going on:
0. We eval some code\, expecting to catch errors.
1. We create a C in some scope within the eval. In our example the scope is just the scope of the eval\, but it could really be any scope contained within the eval.
2. Later in the scope\, we die. This sets $@ and goes to the next line past our eval\, exiting our scope in the process.
3. When Perl exits the scope\, it invokes C->DESTROY() to clean up our object.
4. C->DESTROY() happens to contain an eval which doesn't die(). This *clears* $@. Oooops!
5. When we check $@ after our eval\, it's empty. :-(
This is a *really* evil bug because it means that anytime you create an object using someone else's package\, you run the risk of completely hosing any exception handling you are doing.
This bug was discussed approximately 1 year ago. Here's a link to the discussion:
http://x43.deja.com/getdoc.xp?AN=389699069&CONTEXT=926789340.1861025869
I've found the bug in 5.004_04\, 5.004_05 (both i386-linux)\, and according to Chuck O'Donnell it also exists in 5.005_03 (i386-freefsd). For my complete 'perl -V' see below.
FWIW\, I've run into this twice in the last 2 weeks. In both cases\, I worked around it by patching the modules which triggered the problem. Unfortunately\, due to $@'s unintuitive scoping\, the workaround isn't quite as simple as adding 'local $@' at the beginning of each DESTROY. Instead\, I needed to write a this psuedo-control construct which I wrap around the code executed in each DESTROY.
# "carefully BLOCK LIST" executes BLOCK (with @_ = LIST) without # clearing $@. This is critical for DESTROY methods since they might # accidentally clear $@ by using an eval. sub carefully(&@) { my $block = shift; my $new_err; my @result;
# $@ has strange scoping so just doing "local $@" is not # sufficient. For discussion see: # http://x28.deja.com/getdoc.xp?AN=339328324&CONTEXT=926784629.777191445 { local $@; @result = eval { $block->(@_); }; $new_err = $@; }
die $new_err if ($new_err && !$@); warn $new_err if ($new_err && $@); return @result; }
Any idea when the die/DESTROY bug will be fixed?
Many thanks to all of you for all the time and energy you put into perl!
Cheers\,
--Dean
+--------------------------------------------------------------------+ | Dean Brettle Computer Consulting http://www.brettle.com/ | | Contract development and support of software and systems | +--------------------------------------------------------------------+
Perlbugtron missed this\, I shall fix this immediately.
This report has been registered with perlbug.
Von: perlbug@perl.org [mailto:perlbug@perl.org] Gesendet am: Tuesday\, June 01\, 1999 3:09 AM An: brettle@his.com Betreff: perlbug rejection: DESTROY() interferes with die()
This email address is for reporting bugs to the perl community via
perlbug@perl.org.
Please address your mail appropriately and include output from the
perlbug program as per the distributed documentation.
Hint: mail should include 'perl -v' and it's output.
From brettle@his.com Mon May 31 21:08:57 1999
Received: from jhereg.perl.com (IDENT:root@perl.com [199.45.135.9]) by
defender.perl.org (8.9.3/8.9.3/Debian/GNU) with ESMTP id VAA30256 for
\perlbugtron@​perl\.org; Mon\, 31 May 1999 21:08:53 -0400
From: brettle@his.com
Received: from smtp1.mindspring.com (smtp1.mindspring.com [207.69.200.31])
by jhereg.perl.com (8.9.0/8.9.0) with ESMTP id QAA30568 for
\perlbug@​perl\.com; Mon\, 31 May 1999 16:56:27 -0600
Received: from server.brettle.com (user-33qsua6.dialup.mindspring.com
[199.174.121.70]) by smtp1.mindspring.com (8.8.5/8.8.5) with ESMTP id
SAA13505; Mon\, 31 May 1999 18:56:38 -0400 (EDT)
Received: (from brettle@localhost) by server.brettle.com (8.8.7/8.8.7) id
PAA19201; Mon\, 31 May 1999 15:55:46 -0700
Date: Mon\, 31 May 1999 15:55:46 -0700
Message-Id: \199905312255\.PAA19201@​server\.brettle\.com
To: perlbug@perl.com
Subject: DESTROY() interferes with die()
Cc: dean@brettle.com
Reply-To: dean@brettle.com
This is a bug report for perl from dean@brettle.com\, generated with the help of perlbug 1.26 running under perl 5.00405.
-----------------------------------------------------------------
Hi all\,
Here is a little perl which illustrates the problem. Commentary follows.
package C;
sub new { my $self = bless {}; return $self; }
sub DESTROY { eval { print "This eval resets \$\@\, which is BAD\n"; }; }
eval { my $o = new C; die "This error should be caught but isn't"; };
if ($@) { print "Caught: $@"; } else { print "Error missed due to perl bug\n"; }
Here is what is going on:
0. We eval some code\, expecting to catch errors.
1. We create a C in some scope within the eval. In our example the scope is just the scope of the eval\, but it could really be any scope contained within the eval.
2. Later in the scope\, we die. This sets $@ and goes to the next line past our eval\, exiting our scope in the process.
3. When Perl exits the scope\, it invokes C->DESTROY() to clean up our object.
4. C->DESTROY() happens to contain an eval which doesn't die(). This *clears* $@. Oooops!
5. When we check $@ after our eval\, it's empty. :-(
This is a *really* evil bug because it means that anytime you create an object using someone else's package\, you run the risk of completely hosing any exception handling you are doing.
This bug was discussed approximately 1 year ago. Here's a link to the discussion:
http://x43.deja.com/getdoc.xp?AN=389699069&CONTEXT=926789340.1861025869
I've found the bug in 5.004_04\, 5.004_05 (both i386-linux)\, and according to Chuck O'Donnell it also exists in 5.005_03 (i386-freefsd). For my complete 'perl -V' see below.
FWIW\, I've run into this twice in the last 2 weeks. In both cases\, I worked around it by patching the modules which triggered the problem. Unfortunately\, due to $@'s unintuitive scoping\, the workaround isn't quite as simple as adding 'local $@' at the beginning of each DESTROY. Instead\, I needed to write a this psuedo-control construct which I wrap around the code executed in each DESTROY.
# "carefully BLOCK LIST" executes BLOCK (with @_ = LIST) without # clearing $@. This is critical for DESTROY methods since they might # accidentally clear $@ by using an eval. sub carefully(&@) { my $block = shift; my $new_err; my @result;
# $@ has strange scoping so just doing "local $@" is not # sufficient. For discussion see: # http://x28.deja.com/getdoc.xp?AN=339328324&CONTEXT=926784629.777191445 { local $@; @result = eval { $block->(@_); }; $new_err = $@; }
die $new_err if ($new_err && !$@); warn $new_err if ($new_err && $@); return @result; }
Any idea when the die/DESTROY bug will be fixed?
Many thanks to all of you for all the time and energy you put into perl!
Cheers\,
--Dean
+--------------------------------------------------------------------+ | Dean Brettle Computer Consulting http://www.brettle.com/ | | Contract development and support of software and systems | +--------------------------------------------------------------------+
Perl 5.6 will fix this. die() within DESTROY() is turned into a warn()\, and so won't interfere with $@. I've marked the bug as closed.
Thanks for your bug report\,
Nat
Migrated from rt.perl.org#831 (status was 'resolved')
Searchable as RT831$