Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WG: DESTROY() interferes with die() #31

Closed
p5pRT opened this issue Jun 1, 1999 · 3 comments

Comments

@p5pRT
Copy link
Collaborator

@p5pRT p5pRT commented Jun 1, 1999

Migrated from rt.perl.org#831 (status was 'resolved')

Searchable as RT831$

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Jun 1, 1999

From Richard.Foley@m.dasa.de

Created by dean@brettle.com

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 Info


Site configuration information for perl 5.00405:

Configured by root at Mon May 31 15:33:19 PDT 1999.

Summary of my perl5 (5.0 patchlevel 4 subversion 5) configuration:
  Platform:
    osname=linux, osvers=2.0.36, archname=i386-linux
    uname='linux server 2.0.36 #2 sun may 23 13:15:45 pdt 1999 i586 unknown
'
    hint=recommended, useposix=true, d_sigaction=define
    bincompat3=y useperlio=undef d_sfio=undef
  Compiler:
    cc='cc', optimize='-O2', gccversion=2.7.2.3
    cppflags='-Dbool=char -DHAS_BOOL'
    ccflags ='-Dbool=char -DHAS_BOOL'
    stdchar='char', d_stdstdio=define, usevfork=false
    intsize=4, longsize=4, ptrsize=undef, doublesize=undef
    alignbytes=4, usemymalloc=n, prototype=define
  Linker and Libraries:
    ld='cc', ldflags =' -L/usr/local/lib'
    libpth=/usr/local/lib /lib /usr/lib
    libs=-lnsl -lndbm -lgdbm -ldb -ldl -lm -lc -lposix -lcrypt
    libc=, so=so
    useshrplib=false, libperl=libperl.a
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-rdynamic'
    cccdlflags='-fpic', lddlflags='-shared -L/usr/local/lib'

Locally applied patches:
    MAINT_TRIAL_7 - 5.004_05 maintenance trial 7


@INC for perl 5.00405:
    /usr/lib/perl5/i386-linux/5.00405
    /usr/lib/perl5
    /usr/lib/perl5/site_perl/i386-linux
    /usr/lib/perl5/site_perl
    .


Environment for perl 5.00405:
    HOME=/home/brettle
    LANG (unset)
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin
    PERL_BADLANG (unset)
    SHELL=/bin/bash


@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Jun 1, 1999

From [Unknown Contact. See original ticket]

Created by dean@brettle.com

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 Info


Site configuration information for perl 5.00405:

Configured by root at Mon May 31 15:33:19 PDT 1999.

Summary of my perl5 (5.0 patchlevel 4 subversion 5) configuration:
  Platform:
    osname=linux, osvers=2.0.36, archname=i386-linux
    uname='linux server 2.0.36 #2 sun may 23 13:15:45 pdt 1999 i586 unknown
'
    hint=recommended, useposix=true, d_sigaction=define
    bincompat3=y useperlio=undef d_sfio=undef
  Compiler:
    cc='cc', optimize='-O2', gccversion=2.7.2.3
    cppflags='-Dbool=char -DHAS_BOOL'
    ccflags ='-Dbool=char -DHAS_BOOL'
    stdchar='char', d_stdstdio=define, usevfork=false
    intsize=4, longsize=4, ptrsize=undef, doublesize=undef
    alignbytes=4, usemymalloc=n, prototype=define
  Linker and Libraries:
    ld='cc', ldflags =' -L/usr/local/lib'
    libpth=/usr/local/lib /lib /usr/lib
    libs=-lnsl -lndbm -lgdbm -ldb -ldl -lm -lc -lposix -lcrypt
    libc=, so=so
    useshrplib=false, libperl=libperl.a
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-rdynamic'
    cccdlflags='-fpic', lddlflags='-shared -L/usr/local/lib'

Locally applied patches:
    MAINT_TRIAL_7 - 5.004_05 maintenance trial 7


@INC for perl 5.00405:
    /usr/lib/perl5/i386-linux/5.00405
    /usr/lib/perl5
    /usr/lib/perl5/site_perl/i386-linux
    /usr/lib/perl5/site_perl
    .


Environment for perl 5.00405:
    HOME=/home/brettle
    LANG (unset)
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin
    PERL_BADLANG (unset)
    SHELL=/bin/bash




@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Mar 20, 2000

From [Unknown Contact. See original ticket]

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

@p5pRT p5pRT closed this Nov 28, 2003
This was referenced Oct 18, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
1 participant
You can’t perform that action at this time.