summaryrefslogtreecommitdiff
path: root/cop.h
diff options
context:
space:
mode:
authorDavid Mitchell <davem@iabyn.com>2017-07-03 13:43:27 +0100
committerDavid Mitchell <davem@iabyn.com>2017-07-03 13:43:27 +0100
commit9449f0d6ae2e0e6852c0b9be8be63c3525747345 (patch)
tree49f911acf97719ac285fd4d3b68326e7668ffeff /cop.h
parent6efb583a3779086d6dce2899767ca920f0eda754 (diff)
downloadperl-9449f0d6ae2e0e6852c0b9be8be63c3525747345.tar.gz
save si_stack_hwm across JMPENV_PUSH
When continuing after an exception (JMPENV_PUSH() returns 3), restore the value of PL_curstackinfo->si_stack_hwm. This is a recently added variable on debugging builds that detects attempts to push stuff on the stack without extending it. After an exception its value may be invalid and trigger a false panic.
Diffstat (limited to 'cop.h')
-rw-r--r--cop.h18
1 files changed, 18 insertions, 0 deletions
diff --git a/cop.h b/cop.h
index 2be8fb1e9d..be23b3dfcd 100644
--- a/cop.h
+++ b/cop.h
@@ -35,10 +35,25 @@ struct jmpenv {
int je_ret; /* last exception thrown */
bool je_mustcatch; /* need to call longjmp()? */
U16 je_old_delaymagic; /* saved PL_delaymagic */
+#if defined DEBUGGING && !defined DEBUGGING_RE_ONLY
+ SSize_t je_old_stack_hwm;
+#endif
};
typedef struct jmpenv JMPENV;
+#if defined DEBUGGING && !defined DEBUGGING_RE_ONLY
+# define JE_OLD_STACK_HWM_zero PL_start_env.je_old_stack_hwm = 0
+# 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
+#else
+# define JE_OLD_STACK_HWM_zero NOOP
+# define JE_OLD_STACK_HWM_save(je) NOOP
+# define JE_OLD_STACK_HWM_restore(je) NOOP
+#endif
+
/*
* How to build the first jmpenv.
*
@@ -57,6 +72,7 @@ typedef struct jmpenv JMPENV;
PL_start_env.je_ret = -1; \
PL_start_env.je_mustcatch = TRUE; \
PL_start_env.je_old_delaymagic = 0; \
+ JE_OLD_STACK_HWM_zero; \
} STMT_END
/*
@@ -102,7 +118,9 @@ typedef struct jmpenv JMPENV;
Perl_deb(aTHX_ "JUMPENV_PUSH level=%d at %s:%d\n", \
i, __FILE__, __LINE__);}) \
cur_env.je_prev = PL_top_env; \
+ JE_OLD_STACK_HWM_save(cur_env); \
cur_env.je_ret = PerlProc_setjmp(cur_env.je_buf, SCOPE_SAVES_SIGNAL_MASK); \
+ JE_OLD_STACK_HWM_restore(cur_env); \
PL_top_env = &cur_env; \
cur_env.je_mustcatch = FALSE; \
cur_env.je_old_delaymagic = PL_delaymagic; \