diff options
author | David Mitchell <davem@iabyn.com> | 2017-06-13 09:11:13 +0100 |
---|---|---|
committer | David Mitchell <davem@iabyn.com> | 2017-06-24 09:38:14 +0100 |
commit | 87058c31e9fa350bda8d797127c9c175d0b1a893 (patch) | |
tree | a30a1b8e831b83950e5a4a7a6b64bec517b1455a /cop.h | |
parent | 23c687d9d091a545afb2b769447c17fba98ba87a (diff) | |
download | perl-87058c31e9fa350bda8d797127c9c175d0b1a893.tar.gz |
add PL_curstackinfo->si_stack_hwm
On debugging builds only, add a mechanism for checking pp function calls
for insufficient stack extending. It works by:
* make the runops loop set a high-water-mark (HWM) variable equal to
PL_stack_sp just before calling each pp function;
* make EXTEND() etc update this HWM;
* on return from the pp function, panic if PL_stack_sp is > HWM.
This detects whether pp functions are pushing more items onto the stack
than they are requesting space for.
There's a possibility of false positives if the code is doing weird stuff
like direct manipulation of stacks via PL_curstack, SWITCHSTACK() etc.
It's also possible that one pp function "knows" that a previous pp
function will have already grown the stack enough. Currently the only
place in core that seems to do this is pp_enteriter, which allocates 1
stack slot so that pp_iter doesn't have to check each time it returns
&PL_sv_yes/no. To accommodate this, the new macro EXTEND_SKIP() has been
added, that tells perl that it's safely skipping an EXTEND() here.
Diffstat (limited to 'cop.h')
-rw-r--r-- | cop.h | 13 |
1 files changed, 13 insertions, 0 deletions
@@ -994,6 +994,12 @@ struct stackinfo { I32 si_markoff; /* offset where markstack begins for us. * currently used only with DEBUGGING, * but not #ifdef-ed for bincompat */ +#ifdef DEBUGGING && !defined DEBUGGING_RE_ONLY +/* high water mark: for checking if the stack was correctly extended / + * tested for extension by each pp function */ + SSize_t si_stack_hwm; +#endif + }; typedef struct stackinfo PERL_SI; @@ -1009,6 +1015,12 @@ typedef struct stackinfo PERL_SI; # define SET_MARK_OFFSET NOOP #endif +#if defined DEBUGGING && !defined DEBUGGING_RE_ONLY +# define PUSHSTACK_INIT_HWM(si) si->si_stack_hwm = 0 +#else +# define PUSHSTACK_INIT_HWM(si) NOOP +#endif + #define PUSHSTACKi(type) \ STMT_START { \ PERL_SI *next = PL_curstackinfo->si_next; \ @@ -1024,6 +1036,7 @@ typedef struct stackinfo PERL_SI; } \ next->si_type = type; \ next->si_cxix = -1; \ + PUSHSTACK_INIT_HWM(next); \ AvFILLp(next->si_stack) = 0; \ SWITCHSTACK(PL_curstack,next->si_stack); \ PL_curstackinfo = next; \ |