Throw away uncleanable scopes when exiting a pseudo-forked process.
Jan Dubois [Tue, 8 Dec 2009 01:19:18 +0000 (17:19 -0800)]
Commit adab9969 tried to clean up those additional scopes, but failed
because some of the memory was allocated from a different pool. To
avoid triggering the assert() in perl_destruct() this change instead
moves the one remaining scope back to the root of the stack, effectively
discarding the additional frames without any further processing.

win32/perlhost.h

index 5e89f85..7464c7a 100644 (file)
@@ -1771,9 +1771,14 @@ restart:
            CALLRUNOPS(aTHX);
             /* We may have additional unclosed scopes if fork() was called
              * from within a BEGIN block.  See perlfork.pod for more details.
+             * We cannot clean up these other scopes because they belong to a
+             * different interpreter, but we also cannot leave PL_scopestack_ix
+             * dangling because that can trigger an assertion in perl_destruct().
              */
-           while (PL_scopestack_ix > oldscope)
-               LEAVE;
+            if (PL_scopestack_ix > oldscope) {
+                PL_scopestack[oldscope-1] = PL_scopestack[PL_scopestack_ix-1];
+                PL_scopestack_ix = oldscope;
+            }
            status = 0;
            break;
        case 2: