4 require Config; import Config;
5 if ($Config{'extensions'} !~ /\bDevel\/Peek\b/) {
6 print "1..0 # Skip: Devel::Peek was not built\n";
16 open(SAVERR, ">&STDERR") or die "Can't dup STDERR: $!";
18 # If I reference any lexicals in this, I get the entire outer subroutine (or
19 # MAIN) dumped too, which isn't really what I want, as it's a lot of faff to
28 use constant thr => $Config{useithreads};
32 my $repeat_todo = $_[4];
34 if (open(OUT,">peek$$")) {
35 open(STDERR, ">&OUT") or die "Can't dup OUT: $!";
37 print STDERR "*****\n";
38 Dump($_[1]); # second dump to compare with the first to make sure nothing changed.
39 open(STDERR, ">&SAVERR") or die "Can't restore STDERR: $!";
41 if (open(IN, "peek$$")) {
43 $pattern =~ s/\$ADDR/0x[[:xdigit:]]+/g;
44 $pattern =~ s/\$FLOAT/(?:\\d*\\.\\d+(?:e[-+]\\d+)?|\\d+)/g;
45 # handle DEBUG_LEAKING_SCALARS prefix
46 $pattern =~ s/^(\s*)(SV =.* at )/(?:$1ALLOCATED at .*?\n)?$1$2/mg;
48 # Need some clear generic mechanism to eliminate (or add) lines
49 # of dump output dependant on perl version. The (previous) use of
50 # things like $IVNV gave the illusion that the string passed in was
51 # a regexp into which variables were interpolated, but this wasn't
52 # actually true as those 'variables' actually also ate the
53 # whitespace on the line. So it seems better to mark lines that
54 # need to be eliminated. I considered (?# ... ) and (?{ ... }),
55 # but whilst embedded code or comment syntax would keep it as a
56 # legitimate regexp, it still isn't true. Seems easier and clearer
57 # things that look like comments.
59 # Could do this is in a s///mge but seems clearer like this:
60 $pattern = join '', map {
61 # If we identify the version condition, take *it* out whatever
64 : $_ # Didn't match, so this line is in
65 } split /^/, $pattern;
67 $pattern =~ s/\$PADMY/
68 ($] < 5.009) ? 'PADBUSY,PADMY' : 'PADMY';
70 $pattern =~ s/\$PADTMP/
71 ($] < 5.009) ? 'PADBUSY,PADTMP' : 'PADTMP';
74 ($] < 5.011) ? 'RV' : 'IV';
77 print $pattern, "\n" if $DEBUG;
78 my ($dump, $dump2) = split m/\*\*\*\*\*\n/, scalar <IN>;
79 print $dump, "\n" if $DEBUG;
80 like( $dump, qr/\A$pattern\Z/ms, $_[0])
81 or note("line " . (caller)[2]);
83 local $TODO = $repeat_todo;
84 is($dump2, $dump, "$_[0] (unchanged by dump)")
85 or note("line " . (caller)[2]);
91 die "$0: failed to open peek$$: !\n";
94 die "$0: failed to create peek$$: $!\n";
104 1 while unlink("peek$$");
107 do_test('assignment of immediate constant (string)',
109 'SV = PV\\($ADDR\\) at $ADDR
111 FLAGS = \\(POK,pPOK\\)
117 do_test('immediate constant (string)',
119 'SV = PV\\($ADDR\\) at $ADDR
121 FLAGS = \\(.*POK,READONLY,pPOK\\)
126 do_test('assignment of immediate constant (integer)',
128 'SV = IV\\($ADDR\\) at $ADDR
130 FLAGS = \\(IOK,pIOK\\)
133 do_test('immediate constant (integer)',
135 'SV = IV\\($ADDR\\) at $ADDR
137 FLAGS = \\(.*IOK,READONLY,pIOK\\)
140 do_test('assignment of immediate constant (integer)',
142 'SV = IV\\($ADDR\\) at $ADDR
144 FLAGS = \\($PADMY,IOK,pIOK\\)
147 # If perl is built with PERL_PRESERVE_IVUV then maths is done as integers
148 # where possible and this scalar will be an IV. If NO_PERL_PRESERVE_IVUV then
149 # maths is done in floating point always, and this scalar will be an NV.
150 # ([NI]) captures the type, referred to by \1 in this regexp and $type for
151 # building subsequent regexps.
152 my $type = do_test('result of addition',
154 'SV = ([NI])V\\($ADDR\\) at $ADDR
156 FLAGS = \\(PADTMP,\1OK,p\1OK\\)
161 do_test('floating point value',
163 'SV = PVNV\\($ADDR\\) at $ADDR
165 FLAGS = \\(NOK,pNOK\\)
167 NV = 789\\.(?:1(?:000+\d+)?|0999+\d+)
172 do_test('integer constant',
174 'SV = IV\\($ADDR\\) at $ADDR
176 FLAGS = \\(.*IOK,READONLY,pIOK\\)
181 'SV = NULL\\(0x0\\) at $ADDR
185 do_test('reference to scalar',
187 'SV = $RV\\($ADDR\\) at $ADDR
191 SV = PV\\($ADDR\\) at $ADDR
193 FLAGS = \\(POK,pPOK\\)
201 SV = PVNV\\($ADDR\\) at $ADDR
203 FLAGS = \\(IOK,NOK,pIOK,pNOK\\)
209 SV = IV\\($ADDR\\) at $ADDR
211 FLAGS = \\(IOK,pIOK\\)
214 do_test('reference to array',
216 'SV = $RV\\($ADDR\\) at $ADDR
220 SV = PVAV\\($ADDR\\) at $ADDR
231 SV = IV\\($ADDR\\) at $ADDR
233 FLAGS = \\(IOK,pIOK\\)
235 Elt No. 1' . $c_pattern);
237 do_test('reference to hash',
239 'SV = $RV\\($ADDR\\) at $ADDR
243 SV = PVHV\\($ADDR\\) at $ADDR
245 FLAGS = \\(SHAREKEYS\\)
247 NV = $FLOAT # $] < 5.009
248 ARRAY = $ADDR \\(0:7, 1:1\\)
249 hash quality = 100.0%
255 Elt "123" HASH = $ADDR' . $c_pattern,
257 $] > 5.009 && $] < 5.015
258 && 'The hash iterator used in dump.c sets the OOK flag');
260 do_test('reference to anon sub with empty prototype',
262 'SV = $RV\\($ADDR\\) at $ADDR
266 SV = PVCV\\($ADDR\\) at $ADDR
268 FLAGS = \\($PADMY,POK,pPOK,ANON,WEAKOUTSIDE,CVGV_RC\\) # $] < 5.015 || !thr
269 FLAGS = \\($PADMY,POK,pPOK,ANON,WEAKOUTSIDE,CVGV_RC,DYNFILE\\) # $] >= 5.015 && thr
273 COMP_STASH = $ADDR\\t"main"
274 START = $ADDR ===> \\d+
276 XSUB = 0x0 # $] < 5.009
277 XSUBANY = 0 # $] < 5.009
278 GVGV::GV = $ADDR\\t"main" :: "__ANON__[^"]*"
279 FILE = ".*\\b(?i:peek\\.t)"
283 FLAGS = 0x404 # $] < 5.009
284 FLAGS = 0x490 # $] >= 5.009 && ($] < 5.015 || !thr)
285 FLAGS = 0x1490 # $] >= 5.015 && thr
288 PADNAME = $ADDR\\($ADDR\\) PAD = $ADDR\\($ADDR\\)
289 OUTSIDE = $ADDR \\(MAIN\\)');
291 do_test('reference to named subroutine without prototype',
293 'SV = $RV\\($ADDR\\) at $ADDR
297 SV = PVCV\\($ADDR\\) at $ADDR
299 FLAGS = \\((?:HASEVAL)?\\) # $] < 5.015 || !thr
300 FLAGS = \\(DYNFILE(?:,HASEVAL)?\\) # $] >= 5.015 && thr
303 COMP_STASH = $ADDR\\t"main"
304 START = $ADDR ===> \\d+
306 XSUB = 0x0 # $] < 5.009
307 XSUBANY = 0 # $] < 5.009
308 GVGV::GV = $ADDR\\t"main" :: "do_test"
309 FILE = ".*\\b(?i:peek\\.t)"
313 FLAGS = 0x(?:400)?0 # $] < 5.015 || !thr
314 FLAGS = 0x[145]000 # $] >= 5.015 && thr
317 PADNAME = $ADDR\\($ADDR\\) PAD = $ADDR\\($ADDR\\)
318 \\d+\\. $ADDR<\\d+> \\(\\d+,\\d+\\) "\\$todo"
319 \\d+\\. $ADDR<\\d+> \\(\\d+,\\d+\\) "\\$repeat_todo"
320 \\d+\\. $ADDR<\\d+> \\(\\d+,\\d+\\) "\\$pattern"
321 \\d+\\. $ADDR<\\d+> FAKE "\\$DEBUG" # $] < 5.009
322 \\d+\\. $ADDR<\\d+> FAKE "\\$DEBUG" flags=0x0 index=0 # $] >= 5.009
323 \\d+\\. $ADDR<\\d+> \\(\\d+,\\d+\\) "\\$dump"
324 \\d+\\. $ADDR<\\d+> \\(\\d+,\\d+\\) "\\$dump2"
325 OUTSIDE = $ADDR \\(MAIN\\)');
328 do_test('reference to regexp',
330 'SV = $RV\\($ADDR\\) at $ADDR
334 SV = REGEXP\\($ADDR\\) at $ADDR
336 FLAGS = \\(OBJECT,POK,FAKE,pPOK\\) # $] < 5.017006
337 FLAGS = \\(OBJECT,FAKE\\) # $] >= 5.017006
338 PV = $ADDR "\\(\\?\\^:tic\\)"
340 LEN = 0 # $] < 5.017006
341 STASH = $ADDR\\t"Regexp"'
344 EXTFLAGS = 0x680000 \(CHECK_ALL,USE_INTUIT_NOML,USE_INTUIT_ML\)
366 do_test('reference to regexp',
368 'SV = $RV\\($ADDR\\) at $ADDR
372 SV = PVMG\\($ADDR\\) at $ADDR
374 FLAGS = \\(OBJECT,SMG\\)
380 MG_TYPE = PERL_MAGIC_qr\(r\)
382 PAT = "\(\?^:tic\)" # $] >= 5.009
383 REFCNT = 2 # $] >= 5.009
384 STASH = $ADDR\\t"Regexp"');
387 do_test('reference to blessed hash',
389 'SV = $RV\\($ADDR\\) at $ADDR
393 SV = PVHV\\($ADDR\\) at $ADDR
395 FLAGS = \\(OBJECT,SHAREKEYS\\)
398 STASH = $ADDR\\t"Tac"
408 : 'The hash iterator used in dump.c sets the OOK flag'
409 : "Something causes the HV's array to become allocated");
413 'SV = PVGV\\($ADDR\\) at $ADDR
415 FLAGS = \\(MULTI(?:,IN_PAD)?\\) # $] >= 5.009
416 FLAGS = \\(GMG,SMG,MULTI(?:,IN_PAD)?\\) # $] < 5.009
420 MAGIC = $ADDR # $] < 5.009
421 MG_VIRTUAL = &PL_vtbl_glob # $] < 5.009
422 MG_TYPE = PERL_MAGIC_glob\(\*\) # $] < 5.009
423 MG_OBJ = $ADDR # $] < 5.009
426 GvSTASH = $ADDR\\t"main"
436 GPFLAGS = 0x0 # $] < 5.009
438 FILE = ".*\\b(?i:peek\\.t)"
442 if (ord('A') == 193) {
443 do_test('string with Unicode',
444 chr(256).chr(0).chr(512),
445 'SV = PV\\($ADDR\\) at $ADDR
447 FLAGS = \\((?:$PADTMP,)?POK,READONLY,pPOK,UTF8\\)
448 PV = $ADDR "\\\214\\\101\\\0\\\235\\\101"\\\0 \[UTF8 "\\\x\{100\}\\\x\{0\}\\\x\{200\}"\]
452 do_test('string with Unicode',
453 chr(256).chr(0).chr(512),
454 'SV = PV\\($ADDR\\) at $ADDR
456 FLAGS = \\((?:$PADTMP,)?POK,READONLY,pPOK,UTF8\\)
457 PV = $ADDR "\\\304\\\200\\\0\\\310\\\200"\\\0 \[UTF8 "\\\x\{100\}\\\x\{0\}\\\x\{200\}"\]
462 if (ord('A') == 193) {
463 do_test('reference to hash containing Unicode',
464 {chr(256)=>chr(512)},
465 'SV = $RV\\($ADDR\\) at $ADDR
469 SV = PVHV\\($ADDR\\) at $ADDR
471 FLAGS = \\(SHAREKEYS,HASKFLAGS\\)
473 NV = $FLOAT # $] < 5.009
474 ARRAY = $ADDR \\(0:7, 1:1\\)
475 hash quality = 100.0%
481 Elt "\\\214\\\101" \[UTF8 "\\\x\{100\}"\] HASH = $ADDR
482 SV = PV\\($ADDR\\) at $ADDR
484 FLAGS = \\(POK,pPOK,UTF8\\)
485 PV = $ADDR "\\\235\\\101"\\\0 \[UTF8 "\\\x\{200\}"\]
491 : 'The hash iterator used in dump.c sets the OOK flag'
492 : 'sv_length has been called on the element, and cached the result in MAGIC');
494 do_test('reference to hash containing Unicode',
495 {chr(256)=>chr(512)},
496 'SV = $RV\\($ADDR\\) at $ADDR
500 SV = PVHV\\($ADDR\\) at $ADDR
502 FLAGS = \\(SHAREKEYS,HASKFLAGS\\)
505 ARRAY = $ADDR \\(0:7, 1:1\\)
506 hash quality = 100.0%
512 Elt "\\\304\\\200" \[UTF8 "\\\x\{100\}"\] HASH = $ADDR
513 SV = PV\\($ADDR\\) at $ADDR
515 FLAGS = \\(POK,pPOK,UTF8\\)
516 PV = $ADDR "\\\310\\\200"\\\0 \[UTF8 "\\\x\{200\}"\]
522 : 'The hash iterator used in dump.c sets the OOK flag'
523 : 'sv_length has been called on the element, and cached the result in MAGIC');
528 do_test('scalar with pos magic',
530 'SV = PVMG\\($ADDR\\) at $ADDR
532 FLAGS = \\($PADMY,SMG,POK,pPOK\\)
539 MG_VIRTUAL = &PL_vtbl_mglob
540 MG_TYPE = PERL_MAGIC_regex_global\\(g\\)
545 # TAINTEDDIR is not set on: OS2, AMIGAOS, WIN32, MSDOS
546 # environment variables may be invisibly case-forced, hence the (?i:PATH)
547 # C<scalar(@ARGV)> is turned into an IV on VMS hence the (?:IV)?
548 # Perl 5.18 ensures all env vars end up as strings only, hence the (?:,pIOK)?
549 # Perl 5.18 ensures even magic vars have public OK, hence the (?:,POK)?
550 # VMS is setting FAKE and READONLY flags. What VMS uses for storing
551 # ENV hashes is also not always null terminated.
553 do_test('tainted value in %ENV',
554 $ENV{PATH}=@ARGV, # scalar(@ARGV) is a handy known tainted value
555 'SV = PVMG\\($ADDR\\) at $ADDR
557 FLAGS = \\(GMG,SMG,RMG(?:,POK)?(?:,pIOK)?,pPOK\\)
564 MG_VIRTUAL = &PL_vtbl_envelem
565 MG_TYPE = PERL_MAGIC_envelem\\(e\\)
569 MG_PTR = $ADDR (?:"(?i:PATH)"|=> HEf_SVKEY
570 SV = PV(?:IV)?\\($ADDR\\) at $ADDR
572 FLAGS = \\(TEMP,POK,(?:FAKE,READONLY,)?pPOK\\)
574 )? PV = $ADDR "(?i:PATH)"(?:\\\0)?
578 MG_VIRTUAL = &PL_vtbl_taint
579 MG_TYPE = PERL_MAGIC_taint\\(t\\)');
581 do_test('blessed reference',
582 bless(\\undef, 'Foobar'),
583 'SV = $RV\\($ADDR\\) at $ADDR
587 SV = PVMG\\($ADDR\\) at $ADDR
589 FLAGS = \\(OBJECT,ROK\\)
593 SV = NULL\\(0x0\\) at $ADDR
595 FLAGS = \\(READONLY\\)
599 STASH = $ADDR\s+"Foobar"');
605 do_test('constant subroutine',
607 'SV = $RV\\($ADDR\\) at $ADDR
611 SV = PVCV\\($ADDR\\) at $ADDR
613 FLAGS = \\(POK,pPOK,CONST,ISXSUB\\) # $] < 5.015
614 FLAGS = \\(POK,pPOK,CONST,DYNFILE,ISXSUB\\) # $] >= 5.015
619 ROOT = 0x0 # $] < 5.009
621 XSUBANY = $ADDR \\(CONST SV\\)
622 SV = PV\\($ADDR\\) at $ADDR
624 FLAGS = \\(.*POK,READONLY,pPOK\\)
625 PV = $ADDR "Perl rules"\\\0
628 GVGV::GV = $ADDR\\t"main" :: "const"
629 FILE = ".*\\b(?i:peek\\.t)"
633 FLAGS = 0x200 # $] < 5.009
634 FLAGS = 0xc00 # $] >= 5.009 && $] < 5.013
635 FLAGS = 0xc # $] >= 5.013 && $] < 5.015
636 FLAGS = 0x100c # $] >= 5.015
639 OUTSIDE = 0x0 \\(null\\)');
641 do_test('isUV should show on PVMG',
642 do { my $v = $1; $v = ~0; $v },
643 'SV = PVMG\\($ADDR\\) at $ADDR
645 FLAGS = \\(IOK,pIOK,IsUV\\)
652 'SV = $RV\\($ADDR\\) at $ADDR
656 SV = PVIO\\($ADDR\\) at $ADDR
661 STASH = $ADDR\s+"IO::File"
672 SUBPROCESS = 0 # $] < 5.009
678 'SV = $RV\\($ADDR\\) at $ADDR
682 SV = PVFM\\($ADDR\\) at $ADDR
684 FLAGS = \\(\\) # $] < 5.015 || !thr
685 FLAGS = \\(DYNFILE\\) # $] >= 5.015 && thr
690 START = $ADDR ===> \\d+
692 XSUB = 0x0 # $] < 5.009
693 XSUBANY = 0 # $] < 5.009
694 GVGV::GV = $ADDR\\t"main" :: "PIE"
695 FILE = ".*\\b(?i:peek\\.t)"(?:
699 FLAGS = 0x0 # $] < 5.015 || !thr
700 FLAGS = 0x1000 # $] >= 5.015 && thr
702 LINES = 0 # $] < 5.017_003
704 PADNAME = $ADDR\\($ADDR\\) PAD = $ADDR\\($ADDR\\)
705 OUTSIDE = $ADDR \\(MAIN\\)');
707 do_test('blessing to a class with embedded NUL characters',
708 (bless {}, "\0::foo::\n::baz::\t::\0"),
709 'SV = $RV\\($ADDR\\) at $ADDR
713 SV = PVHV\\($ADDR\\) at $ADDR
715 FLAGS = \\(OBJECT,SHAREKEYS\\)
718 STASH = $ADDR\\t"\\\\0::foo::\\\\n::baz::\\\\t::\\\\0"
728 : 'The hash iterator used in dump.c sets the OOK flag'
729 : "Something causes the HV's array to become allocated");
731 do_test('ENAME on a stash',
733 'SV = $RV\\($ADDR\\) at $ADDR
737 SV = PVHV\\($ADDR\\) at $ADDR
739 FLAGS = \\(OOK,SHAREKEYS\\)
741 NV = $FLOAT # $] < 5.009
749 ENAME = "RWOM" # $] > 5.012
754 do_test('ENAMEs on a stash',
756 'SV = $RV\\($ADDR\\) at $ADDR
760 SV = PVHV\\($ADDR\\) at $ADDR
762 FLAGS = \\(OOK,SHAREKEYS\\)
764 NV = $FLOAT # $] < 5.009
772 NAMECOUNT = 2 # $] > 5.012
773 ENAME = "RWOM", "KLANK" # $] > 5.012
778 do_test('ENAMEs on a stash with no NAME',
780 'SV = $RV\\($ADDR\\) at $ADDR
784 SV = PVHV\\($ADDR\\) at $ADDR
786 FLAGS = \\(OOK,SHAREKEYS\\) # $] < 5.017
787 FLAGS = \\(OOK,OVERLOAD,SHAREKEYS\\) # $] >=5.017
789 NV = $FLOAT # $] < 5.009
796 NAMECOUNT = -3 # $] > 5.012
797 ENAME = "RWOM", "KLANK" # $] > 5.012
801 skip "Not built with usemymalloc", 1
802 unless $Config{usemymalloc} eq 'y';
804 ok eval { fill_mstats($x); 1 }, 'fill_mstats on COW scalar'
808 # This is more a test of fbm_compile/pp_study (non) interaction than dumping
809 # prowess, but short of duplicating all the gubbins of this file, I can't see
810 # a way to make a better place for it:
817 unless ($Config{useithreads}) {
818 # These end up as copies in pads under ithreads, which rather defeats the
819 # the point of what we're trying to test here.
821 do_test('regular string constant', perl,
822 'SV = PV\\($ADDR\\) at $ADDR
824 FLAGS = \\(PADMY,POK,READONLY,pPOK\\)
825 PV = $ADDR "rules"\\\0
830 eval 'index "", perl';
832 # FIXME - really this shouldn't say EVALED. It's a false posistive on
833 # 0x40000000 being used for several things, not a flag for "I'm in a string
836 do_test('string constant now an FBM', perl,
837 'SV = PVMG\\($ADDR\\) at $ADDR
839 FLAGS = \\(PADMY,SMG,POK,READONLY,pPOK,VALID,EVALED\\)
840 PV = $ADDR "rules"\\\0
844 MG_VIRTUAL = &PL_vtbl_regexp
845 MG_TYPE = PERL_MAGIC_bm\\(B\\)
847 MG_PTR = $ADDR "(?:\\\\\d){256}"
853 is(study perl, '', "Not allowed to study an FBM");
855 do_test('string constant still an FBM', perl,
856 'SV = PVMG\\($ADDR\\) at $ADDR
858 FLAGS = \\(PADMY,SMG,POK,READONLY,pPOK,VALID,EVALED\\)
859 PV = $ADDR "rules"\\\0
863 MG_VIRTUAL = &PL_vtbl_regexp
864 MG_TYPE = PERL_MAGIC_bm\\(B\\)
866 MG_PTR = $ADDR "(?:\\\\\d){256}"
872 do_test('regular string constant', beer,
873 'SV = PV\\($ADDR\\) at $ADDR
875 FLAGS = \\(PADMY,POK,READONLY,pPOK\\)
876 PV = $ADDR "foamy"\\\0
881 is(study beer, 1, "Our studies were successful");
883 do_test('string constant quite unaffected', beer, 'SV = PV\\($ADDR\\) at $ADDR
885 FLAGS = \\(PADMY,POK,READONLY,pPOK\\)
886 PV = $ADDR "foamy"\\\0
891 my $want = 'SV = PVMG\\($ADDR\\) at $ADDR
893 FLAGS = \\(PADMY,SMG,POK,READONLY,pPOK,VALID,EVALED\\)
894 PV = $ADDR "foamy"\\\0
898 MG_VIRTUAL = &PL_vtbl_regexp
899 MG_TYPE = PERL_MAGIC_bm\\(B\\)
901 MG_PTR = $ADDR "(?:\\\\\d){256}"
907 is (eval 'index "not too foamy", beer', 8, 'correct index');
909 do_test('string constant now FBMed', beer, $want);
913 is(study $pie, 1, "Our studies were successful");
915 do_test('string constant still FBMed', beer, $want);
917 do_test('second string also unaffected', $pie, 'SV = PV\\($ADDR\\) at $ADDR
919 FLAGS = \\(PADMY,POK,pPOK\\)
920 PV = $ADDR "good"\\\0
926 # (One block of study tests removed when study was made a no-op.)
929 open(OUT,">peek$$") or die "Failed to open peek $$: $!";
930 open(STDERR, ">&OUT") or die "Can't dup OUT: $!";
932 open(STDERR, ">&SAVERR") or die "Can't restore STDERR: $!";
933 pass "no crash with DeadCode";