Heya,
  I got bitten by this bug today.  I'm not altogether satisfied by the
last and only comment on the bug, which summarizes to "but there's a
workaround, so it's not perl's fault!"
  Attached is a patch which restores $@ after any DESTROY blocks have
run.
 - Alex

-- 
Networking -- only one letter away from not working
diff -ru perl-current/pp_ctl.c perl-patched/pp_ctl.c
--- perl-current/pp_ctl.c	2005-07-08 13:03:02.000000000 -0400
+++ perl-patched/pp_ctl.c	2005-07-08 15:39:59.000000000 -0400
@@ -1432,6 +1432,7 @@
 	    else {
 		sv_setpvn(ERRSV, message, msglen);
 	    }
+	    message = SvPV_const(ERRSV, msglen);
 	}
 
 	while ((cxix = dopoptoeval(cxstack_ix)) < 0
@@ -1471,6 +1472,12 @@
 	     * minimal fix --GSAR */
 	    PL_curcop = cx->blk_oldcop;
 
+	    /* Leaving the block could run DESTROY blocks which might
+	     * have altered $@; reset it here just in case */
+	    if (message) {
+		sv_setpvn(ERRSV, message, msglen);
+	    }
+
 	    if (optype == OP_REQUIRE) {
                 const char* msg = SvPVx_nolen_const(ERRSV);
 		SV * const nsv = cx->blk_eval.old_namesv;
diff -ru perl-current/t/op/die.t perl-patched/t/op/die.t
--- perl-current/t/op/die.t	2005-07-06 16:38:38.000000000 -0400
+++ perl-patched/t/op/die.t	2005-07-08 15:42:12.000000000 -0400
@@ -1,6 +1,6 @@
 #!./perl
 
-print "1..15\n";
+print "1..16\n";
 
 $SIG{__DIE__} = sub { print ref($_[0]) ? ("ok ",$_[0]->[0]++,"\n") : @_ } ;
 
@@ -72,3 +72,27 @@
     print "not " unless $ok;
     print "ok 15\n";
 }
+
+# [perl #17650] DESTROY can unset $@
+{
+  package SomeClass;
+
+  sub new {
+    my $self = {};
+    bless $self;
+  }
+
+  sub DESTROY {
+    eval { 1; };
+  }
+}
+
+{
+  local $SIG{__DIE__};
+  eval {
+    my $x = new SomeClass;
+    die;
+  };
+  print($@ ? "ok 16\n" : "not ok 16\n");
+}
+

Reply via email to