This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
remove 'hfreeentries failed to free hash' panic
authorDavid Mitchell <davem@iabyn.com>
Tue, 10 May 2011 16:24:29 +0000 (17:24 +0100)
committerDavid Mitchell <davem@iabyn.com>
Thu, 19 May 2011 13:49:43 +0000 (14:49 +0100)
Currently perl attempts to clear a hash 100 times before panicking.
So for example, if a naughty destructor keeps adding things back into the
hash, this will eventually panic.

Note that this can usually only occur with %h=() or undef(%h), since
when freeing a hash, there's usually no reference to the hash that a
destructor can use to mess with the hash.

Remove this limit (so it may potentially loop forever).

My reasoning is that (a) if the user wants to keep adding things back into
the hash, who are we to stop her? (b) as part of of the process of making
sv_clear() non-recursive when freeing hashes, I'm trying to reduce the
amount of state that must be maintained between each iteration.

Note that arrays currently don't have a limit.

hv.c
pod/perldiag.pod

diff --git a/hv.c b/hv.c
index e78f84f..8b186de 100644 (file)
--- a/hv.c
+++ b/hv.c
@@ -1630,7 +1630,6 @@ S_clear_placeholders(pTHX_ HV *hv, U32 items)
 STATIC void
 S_hfreeentries(pTHX_ HV *hv)
 {
-    int attempts = 100;
     STRLEN i = 0;
     const bool mpm = PL_phase != PERL_PHASE_DESTRUCT && HvENAME(hv);
 
@@ -1689,12 +1688,8 @@ S_hfreeentries(pTHX_ HV *hv)
             * re-allocated, HvMAX changed etc */
            continue;
        }
-       if (i++ >= HvMAX(hv)) {
+       if (i++ >= HvMAX(hv))
            i = 0;
-           if (--attempts == 0) {
-               Perl_die(aTHX_ "panic: hfreeentries failed to free hash - something is repeatedly re-creating entries");
-           }
-       }
     } /* while */
 }
 
index 8f2ad29..b90a141 100644 (file)
@@ -3423,13 +3423,6 @@ repeatedly, but each time something re-created entries in the glob. Most
 likely the glob contains an object with a reference back to the glob and a
 destructor that adds a new object to the glob.
 
-=item panic: hfreeentries failed to free hash
-
-(P) The internal routine used to clear a hash's entries tried repeatedly,
-but each time something added more entries to the hash. Most likely the hash
-contains an object with a reference back to the hash and a destructor that
-adds a new object to the hash.
-
 =item panic: INTERPCASEMOD
 
 (P) The lexer got into a bad state at a case modifier.