diff options
author | David Mitchell <davem@iabyn.com> | 2017-07-03 13:43:27 +0100 |
---|---|---|
committer | David Mitchell <davem@iabyn.com> | 2017-07-03 13:43:27 +0100 |
commit | 9449f0d6ae2e0e6852c0b9be8be63c3525747345 (patch) | |
tree | 49f911acf97719ac285fd4d3b68326e7668ffeff /cop.h | |
parent | 6efb583a3779086d6dce2899767ca920f0eda754 (diff) | |
download | perl-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.h | 18 |
1 files changed, 18 insertions, 0 deletions
@@ -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; \ |