summaryrefslogtreecommitdiff
path: root/cop.h
diff options
context:
space:
mode:
authorDavid Mitchell <davem@iabyn.com>2017-06-13 09:11:13 +0100
committerDavid Mitchell <davem@iabyn.com>2017-06-24 09:38:14 +0100
commit87058c31e9fa350bda8d797127c9c175d0b1a893 (patch)
treea30a1b8e831b83950e5a4a7a6b64bec517b1455a /cop.h
parent23c687d9d091a545afb2b769447c17fba98ba87a (diff)
downloadperl-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.h13
1 files changed, 13 insertions, 0 deletions
diff --git a/cop.h b/cop.h
index 0443e24c66..42257c7e4e 100644
--- a/cop.h
+++ b/cop.h
@@ -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; \