summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Mitchell <davem@iabyn.com>2017-07-16 20:00:01 +0100
committerDavid Mitchell <davem@iabyn.com>2017-07-16 20:00:01 +0100
commit978b185906e439ce6a0fcb8e90c8e3f328556a8a (patch)
tree30340c56c37949f3a8c9bbfa6b4eb0f8ccde6bb2
parentab9a6a636dbb66ae5bf3f7546a87872aa295f96d (diff)
downloadperl-978b185906e439ce6a0fcb8e90c8e3f328556a8a.tar.gz
PL_curstackinfo->si_stack_hwm: gently restore
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.
-rw-r--r--cop.h3
-rw-r--r--dump.c3
2 files changed, 4 insertions, 2 deletions
diff --git a/cop.h b/cop.h
index be23b3dfcd..f621cd2cd2 100644
--- 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 a817b43cce..c4bb3ce09c 100644
--- 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;