summaryrefslogtreecommitdiff
path: root/cop.h
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2013-10-28 21:59:14 -0700
committerFather Chrysostomos <sprout@cpan.org>2013-12-21 18:09:54 -0800
commitc1cec775e9019cc8ae244d4db239a7ea5c0b343e (patch)
treef2c2393343552b8a6e74bce1257e8770413d1839 /cop.h
parentbb02e0c10a57ab28b9ec6ca218c7aa6aac53a90c (diff)
downloadperl-c1cec775e9019cc8ae244d4db239a7ea5c0b343e.tar.gz
[perl #119801] Stop @DB::dbline modifications from crashing
The cop address for each breakable line was being stored in the IVX slot of ${"_<$file"}[$line]. This value itself, writable from Perl space, was being used as the address of the op to be flagged, whenever a breakpoint was set. This meant writing to ${"_<$file"}[$line] and assigning a number (like 42) would cause perl to use 42 as an op address, and crash when trying to flag the op. Furthermore, since the array holding the lines could outlive the ops, setting a breakpoint on the op could write to freed memory or to an unrelated op (even a different type), potentially changing the beha- viour of unrelated code. This commit solves those pitfalls by moving breakpoints into a global breakpoint bitfield. Dbstate ops now have an extra field on the end holding a sequence number, representing which bit holds the breakpoint for that op.
Diffstat (limited to 'cop.h')
-rw-r--r--cop.h44
1 files changed, 29 insertions, 15 deletions
diff --git a/cop.h b/cop.h
index 6950814613..d74da17e93 100644
--- a/cop.h
+++ b/cop.h
@@ -370,27 +370,41 @@ string/length pair.
#include "mydtrace.h"
-struct cop {
- BASEOP
- /* On LP64 putting this here takes advantage of the fact that BASEOP isn't
- an exact multiple of 8 bytes to save structure padding. */
- line_t cop_line; /* line # of this command */
- /* label for this construct is now stored in cop_hints_hash */
#ifdef USE_ITHREADS
- PADOFFSET cop_stashoff; /* offset into PL_stashpad, for the
- package the line was compiled in */
+# define _COP_STASH_N_FILE \
+ PADOFFSET cop_stashoff; /* offset into PL_stashpad, for the \
+ package the line was compiled in */ \
char * cop_file; /* file name the following line # is from */
#else
- HV * cop_stash; /* package line was compiled in */
+# define _COP_STASH_N_FILE \
+ HV * cop_stash; /* package line was compiled in */ \
GV * cop_filegv; /* file the following line # is from */
#endif
- U32 cop_hints; /* hints bits from pragmata */
- U32 cop_seq; /* parse sequence number */
- /* Beware. mg.c and warnings.pl assume the type of this is STRLEN *: */
- STRLEN * cop_warnings; /* lexical warnings bitmask */
- /* compile time state of %^H. See the comment in op.c for how this is
- used to recreate a hash to return from caller. */
+
+#define _COP_FIELDS \
+ /* On LP64 putting this here takes advantage of the fact that BASEOP \
+ isn't an exact multiple of 8 bytes to save structure padding. */ \
+ line_t cop_line; /* line # of this command */ \
+ /* label for this construct is now stored in cop_hints_hash */ \
+ _COP_STASH_N_FILE \
+ U32 cop_hints; /* hints bits from pragmata */ \
+ U32 cop_seq; /* parse sequence number */ \
+ /* Beware. mg.c and warnings.pl assume the type of this \
+ is STRLEN *: */ \
+ STRLEN * cop_warnings; /* lexical warnings bitmask */ \
+ /* compile time state of %^H. See the comment in op.c for how this \
+ is used to recreate a hash to return from caller. */ \
COPHH * cop_hints_hash;
+
+struct cop {
+ BASEOP
+ _COP_FIELDS
+};
+
+struct dbop {
+ BASEOP
+ _COP_FIELDS
+ size_t dbop_seq; /* sequence number for breakpoint */
};
#ifdef USE_ITHREADS