PL_curstackinfo->si_stack_hwm: gently restore
authorDavid Mitchell <davem@iabyn.com>
Sun, 16 Jul 2017 19:00:01 +0000 (20:00 +0100)
committerDavid Mitchell <davem@iabyn.com>
Sun, 16 Jul 2017 19:00:01 +0000 (20:00 +0100)
RT #131732

With v5.27.1-66-g87058c3, I introduced a DEBUGGING-only mechanism in the
runops loop for checking whether an op extended the stack by as many slots
as values it returned on the stack.  It did this by setting a
high-water-mark just before calling each pp function, and checking its
result on return.

It saved and restored the old value of PL_curstackinfo->si_stack_hwm
whenever it entered or left a runops loop or did a JMPENV_PUSH /
JMPENV_POP.  However, the restoring could restore to an old value that was
smaller than the current value, leading to false-positive stack-extend
panics. So only restore if the old value was larger.

In particular this was causing false positives in DBI.

cop.h
dump.c

diff --git a/cop.h b/cop.h
index be23b3d..f621cd2 100644 (file)
--- a/cop.h
+++ b/cop.h
@@ -47,7 +47,8 @@ typedef struct jmpenv JMPENV;
 #  define JE_OLD_STACK_HWM_save(je)  \
         (je).je_old_stack_hwm = PL_curstackinfo->si_stack_hwm
 #  define JE_OLD_STACK_HWM_restore(je)  \
-        PL_curstackinfo->si_stack_hwm = (je).je_old_stack_hwm
+        if (PL_curstackinfo->si_stack_hwm < (je).je_old_stack_hwm) \
+            PL_curstackinfo->si_stack_hwm = (je).je_old_stack_hwm
 #else
 #  define JE_OLD_STACK_HWM_zero        NOOP
 #  define JE_OLD_STACK_HWM_save(je)    NOOP
diff --git a/dump.c b/dump.c
index a817b43..c4bb3ce 100644 (file)
--- a/dump.c
+++ b/dump.c
@@ -2467,7 +2467,8 @@ Perl_runops_debug(pTHX)
     PERL_ASYNC_CHECK();
 
 #if defined DEBUGGING && !defined DEBUGGING_RE_ONLY
-    PL_curstackinfo->si_stack_hwm = orig_stack_hwm;
+    if (PL_curstackinfo->si_stack_hwm < orig_stack_hwm)
+        PL_curstackinfo->si_stack_hwm = orig_stack_hwm;
 #endif
     TAINT_NOT;
     return 0;