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\\)
337 PV = $ADDR "\\(\\?\\^:tic\\)"
340 STASH = $ADDR\\t"Regexp"'
343 EXTFLAGS = 0x680000 \(CHECK_ALL,USE_INTUIT_NOML,USE_INTUIT_ML\)
365 do_test('reference to regexp',
367 'SV = $RV\\($ADDR\\) at $ADDR
371 SV = PVMG\\($ADDR\\) at $ADDR
373 FLAGS = \\(OBJECT,SMG\\)
379 MG_TYPE = PERL_MAGIC_qr\(r\)
381 PAT = "\(\?^:tic\)" # $] >= 5.009
382 REFCNT = 2 # $] >= 5.009
383 STASH = $ADDR\\t"Regexp"');
386 do_test('reference to blessed hash',
388 'SV = $RV\\($ADDR\\) at $ADDR
392 SV = PVHV\\($ADDR\\) at $ADDR
394 FLAGS = \\(OBJECT,SHAREKEYS\\)
397 STASH = $ADDR\\t"Tac"
407 : 'The hash iterator used in dump.c sets the OOK flag'
408 : "Something causes the HV's array to become allocated");
412 'SV = PVGV\\($ADDR\\) at $ADDR
414 FLAGS = \\(MULTI(?:,IN_PAD)?\\) # $] >= 5.009
415 FLAGS = \\(GMG,SMG,MULTI(?:,IN_PAD)?\\) # $] < 5.009
419 MAGIC = $ADDR # $] < 5.009
420 MG_VIRTUAL = &PL_vtbl_glob # $] < 5.009
421 MG_TYPE = PERL_MAGIC_glob\(\*\) # $] < 5.009
422 MG_OBJ = $ADDR # $] < 5.009
425 GvSTASH = $ADDR\\t"main"
435 GPFLAGS = 0x0 # $] < 5.009
437 FILE = ".*\\b(?i:peek\\.t)"
441 if (ord('A') == 193) {
442 do_test('string with Unicode',
443 chr(256).chr(0).chr(512),
444 'SV = PV\\($ADDR\\) at $ADDR
446 FLAGS = \\((?:$PADTMP,)?POK,READONLY,pPOK,UTF8\\)
447 PV = $ADDR "\\\214\\\101\\\0\\\235\\\101"\\\0 \[UTF8 "\\\x\{100\}\\\x\{0\}\\\x\{200\}"\]
451 do_test('string with Unicode',
452 chr(256).chr(0).chr(512),
453 'SV = PV\\($ADDR\\) at $ADDR
455 FLAGS = \\((?:$PADTMP,)?POK,READONLY,pPOK,UTF8\\)
456 PV = $ADDR "\\\304\\\200\\\0\\\310\\\200"\\\0 \[UTF8 "\\\x\{100\}\\\x\{0\}\\\x\{200\}"\]
461 if (ord('A') == 193) {
462 do_test('reference to hash containing Unicode',
463 {chr(256)=>chr(512)},
464 'SV = $RV\\($ADDR\\) at $ADDR
468 SV = PVHV\\($ADDR\\) at $ADDR
470 FLAGS = \\(SHAREKEYS,HASKFLAGS\\)
472 NV = $FLOAT # $] < 5.009
473 ARRAY = $ADDR \\(0:7, 1:1\\)
474 hash quality = 100.0%
480 Elt "\\\214\\\101" \[UTF8 "\\\x\{100\}"\] HASH = $ADDR
481 SV = PV\\($ADDR\\) at $ADDR
483 FLAGS = \\(POK,pPOK,UTF8\\)
484 PV = $ADDR "\\\235\\\101"\\\0 \[UTF8 "\\\x\{200\}"\]
490 : 'The hash iterator used in dump.c sets the OOK flag'
491 : 'sv_length has been called on the element, and cached the result in MAGIC');
493 do_test('reference to hash containing Unicode',
494 {chr(256)=>chr(512)},
495 'SV = $RV\\($ADDR\\) at $ADDR
499 SV = PVHV\\($ADDR\\) at $ADDR
501 FLAGS = \\(SHAREKEYS,HASKFLAGS\\)
504 ARRAY = $ADDR \\(0:7, 1:1\\)
505 hash quality = 100.0%
511 Elt "\\\304\\\200" \[UTF8 "\\\x\{100\}"\] HASH = $ADDR
512 SV = PV\\($ADDR\\) at $ADDR
514 FLAGS = \\(POK,pPOK,UTF8\\)
515 PV = $ADDR "\\\310\\\200"\\\0 \[UTF8 "\\\x\{200\}"\]
521 : 'The hash iterator used in dump.c sets the OOK flag'
522 : 'sv_length has been called on the element, and cached the result in MAGIC');
527 do_test('scalar with pos magic',
529 'SV = PVMG\\($ADDR\\) at $ADDR
531 FLAGS = \\($PADMY,SMG,POK,pPOK\\)
538 MG_VIRTUAL = &PL_vtbl_mglob
539 MG_TYPE = PERL_MAGIC_regex_global\\(g\\)
544 # TAINTEDDIR is not set on: OS2, AMIGAOS, WIN32, MSDOS
545 # environment variables may be invisibly case-forced, hence the (?i:PATH)
546 # C<scalar(@ARGV)> is turned into an IV on VMS hence the (?:IV)?
547 # Perl 5.18 ensures all env vars end up as strings only, hence the (?:,pIOK)?
548 # Perl 5.18 ensures even magic vars have public OK, hence the (?:,POK)?
549 # VMS is setting FAKE and READONLY flags. What VMS uses for storing
550 # ENV hashes is also not always null terminated.
552 do_test('tainted value in %ENV',
553 $ENV{PATH}=@ARGV, # scalar(@ARGV) is a handy known tainted value
554 'SV = PVMG\\($ADDR\\) at $ADDR
556 FLAGS = \\(GMG,SMG,RMG(?:,POK)?(?:,pIOK)?,pPOK\\)
563 MG_VIRTUAL = &PL_vtbl_envelem
564 MG_TYPE = PERL_MAGIC_envelem\\(e\\)
568 MG_PTR = $ADDR (?:"(?i:PATH)"|=> HEf_SVKEY
569 SV = PV(?:IV)?\\($ADDR\\) at $ADDR
571 FLAGS = \\(TEMP,POK,(?:FAKE,READONLY,)?pPOK\\)
573 )? PV = $ADDR "(?i:PATH)"(?:\\\0)?
577 MG_VIRTUAL = &PL_vtbl_taint
578 MG_TYPE = PERL_MAGIC_taint\\(t\\)');
580 do_test('blessed reference',
581 bless(\\undef, 'Foobar'),
582 'SV = $RV\\($ADDR\\) at $ADDR
586 SV = PVMG\\($ADDR\\) at $ADDR
588 FLAGS = \\(OBJECT,ROK\\)
592 SV = NULL\\(0x0\\) at $ADDR
594 FLAGS = \\(READONLY\\)
598 STASH = $ADDR\s+"Foobar"');
604 do_test('constant subroutine',
606 'SV = $RV\\($ADDR\\) at $ADDR
610 SV = PVCV\\($ADDR\\) at $ADDR
612 FLAGS = \\(POK,pPOK,CONST,ISXSUB\\) # $] < 5.015
613 FLAGS = \\(POK,pPOK,CONST,DYNFILE,ISXSUB\\) # $] >= 5.015
618 ROOT = 0x0 # $] < 5.009
620 XSUBANY = $ADDR \\(CONST SV\\)
621 SV = PV\\($ADDR\\) at $ADDR
623 FLAGS = \\(.*POK,READONLY,pPOK\\)
624 PV = $ADDR "Perl rules"\\\0
627 GVGV::GV = $ADDR\\t"main" :: "const"
628 FILE = ".*\\b(?i:peek\\.t)"
632 FLAGS = 0x200 # $] < 5.009
633 FLAGS = 0xc00 # $] >= 5.009 && $] < 5.013
634 FLAGS = 0xc # $] >= 5.013 && $] < 5.015
635 FLAGS = 0x100c # $] >= 5.015
638 OUTSIDE = 0x0 \\(null\\)');
640 do_test('isUV should show on PVMG',
641 do { my $v = $1; $v = ~0; $v },
642 'SV = PVMG\\($ADDR\\) at $ADDR
644 FLAGS = \\(IOK,pIOK,IsUV\\)
651 'SV = $RV\\($ADDR\\) at $ADDR
655 SV = PVIO\\($ADDR\\) at $ADDR
660 STASH = $ADDR\s+"IO::File"
671 SUBPROCESS = 0 # $] < 5.009
677 'SV = $RV\\($ADDR\\) at $ADDR
681 SV = PVFM\\($ADDR\\) at $ADDR
683 FLAGS = \\(\\) # $] < 5.015 || !thr
684 FLAGS = \\(DYNFILE\\) # $] >= 5.015 && thr
689 START = $ADDR ===> \\d+
691 XSUB = 0x0 # $] < 5.009
692 XSUBANY = 0 # $] < 5.009
693 GVGV::GV = $ADDR\\t"main" :: "PIE"
694 FILE = ".*\\b(?i:peek\\.t)"(?:
698 FLAGS = 0x0 # $] < 5.015 || !thr
699 FLAGS = 0x1000 # $] >= 5.015 && thr
701 LINES = 0 # $] < 5.017_003
703 PADNAME = $ADDR\\($ADDR\\) PAD = $ADDR\\($ADDR\\)
704 OUTSIDE = $ADDR \\(MAIN\\)');
706 do_test('blessing to a class with embedded NUL characters',
707 (bless {}, "\0::foo::\n::baz::\t::\0"),
708 'SV = $RV\\($ADDR\\) at $ADDR
712 SV = PVHV\\($ADDR\\) at $ADDR
714 FLAGS = \\(OBJECT,SHAREKEYS\\)
717 STASH = $ADDR\\t"\\\\0::foo::\\\\n::baz::\\\\t::\\\\0"
727 : 'The hash iterator used in dump.c sets the OOK flag'
728 : "Something causes the HV's array to become allocated");
730 do_test('ENAME on a stash',
732 'SV = $RV\\($ADDR\\) at $ADDR
736 SV = PVHV\\($ADDR\\) at $ADDR
738 FLAGS = \\(OOK,SHAREKEYS\\)
740 NV = $FLOAT # $] < 5.009
748 ENAME = "RWOM" # $] > 5.012
753 do_test('ENAMEs on a stash',
755 'SV = $RV\\($ADDR\\) at $ADDR
759 SV = PVHV\\($ADDR\\) at $ADDR
761 FLAGS = \\(OOK,SHAREKEYS\\)
763 NV = $FLOAT # $] < 5.009
771 NAMECOUNT = 2 # $] > 5.012
772 ENAME = "RWOM", "KLANK" # $] > 5.012
777 do_test('ENAMEs on a stash with no NAME',
779 'SV = $RV\\($ADDR\\) at $ADDR
783 SV = PVHV\\($ADDR\\) at $ADDR
785 FLAGS = \\(OOK,SHAREKEYS\\) # $] < 5.017
786 FLAGS = \\(OOK,OVERLOAD,SHAREKEYS\\) # $] >=5.017
788 NV = $FLOAT # $] < 5.009
795 NAMECOUNT = -3 # $] > 5.012
796 ENAME = "RWOM", "KLANK" # $] > 5.012
800 skip "Not built with usemymalloc", 1
801 unless $Config{usemymalloc} eq 'y';
803 ok eval { fill_mstats($x); 1 }, 'fill_mstats on COW scalar'
807 # This is more a test of fbm_compile/pp_study (non) interaction than dumping
808 # prowess, but short of duplicating all the gubbins of this file, I can't see
809 # a way to make a better place for it:
816 unless ($Config{useithreads}) {
817 # These end up as copies in pads under ithreads, which rather defeats the
818 # the point of what we're trying to test here.
820 do_test('regular string constant', perl,
821 'SV = PV\\($ADDR\\) at $ADDR
823 FLAGS = \\(PADMY,POK,READONLY,pPOK\\)
824 PV = $ADDR "rules"\\\0
829 eval 'index "", perl';
831 # FIXME - really this shouldn't say EVALED. It's a false posistive on
832 # 0x40000000 being used for several things, not a flag for "I'm in a string
835 do_test('string constant now an FBM', perl,
836 'SV = PVMG\\($ADDR\\) at $ADDR
838 FLAGS = \\(PADMY,SMG,POK,READONLY,pPOK,VALID,EVALED\\)
839 PV = $ADDR "rules"\\\0
843 MG_VIRTUAL = &PL_vtbl_regexp
844 MG_TYPE = PERL_MAGIC_bm\\(B\\)
846 MG_PTR = $ADDR "(?:\\\\\d){256}"
852 is(study perl, '', "Not allowed to study an FBM");
854 do_test('string constant still an FBM', perl,
855 'SV = PVMG\\($ADDR\\) at $ADDR
857 FLAGS = \\(PADMY,SMG,POK,READONLY,pPOK,VALID,EVALED\\)
858 PV = $ADDR "rules"\\\0
862 MG_VIRTUAL = &PL_vtbl_regexp
863 MG_TYPE = PERL_MAGIC_bm\\(B\\)
865 MG_PTR = $ADDR "(?:\\\\\d){256}"
871 do_test('regular string constant', beer,
872 'SV = PV\\($ADDR\\) at $ADDR
874 FLAGS = \\(PADMY,POK,READONLY,pPOK\\)
875 PV = $ADDR "foamy"\\\0
880 is(study beer, 1, "Our studies were successful");
882 do_test('string constant quite unaffected', beer, 'SV = PV\\($ADDR\\) at $ADDR
884 FLAGS = \\(PADMY,POK,READONLY,pPOK\\)
885 PV = $ADDR "foamy"\\\0
890 my $want = 'SV = PVMG\\($ADDR\\) at $ADDR
892 FLAGS = \\(PADMY,SMG,POK,READONLY,pPOK,VALID,EVALED\\)
893 PV = $ADDR "foamy"\\\0
897 MG_VIRTUAL = &PL_vtbl_regexp
898 MG_TYPE = PERL_MAGIC_bm\\(B\\)
900 MG_PTR = $ADDR "(?:\\\\\d){256}"
906 is (eval 'index "not too foamy", beer', 8, 'correct index');
908 do_test('string constant now FBMed', beer, $want);
912 is(study $pie, 1, "Our studies were successful");
914 do_test('string constant still FBMed', beer, $want);
916 do_test('second string also unaffected', $pie, 'SV = PV\\($ADDR\\) at $ADDR
918 FLAGS = \\(PADMY,POK,pPOK\\)
919 PV = $ADDR "good"\\\0
925 # (One block of study tests removed when study was made a no-op.)
928 open(OUT,">peek$$") or die "Failed to open peek $$: $!";
929 open(STDERR, ">&OUT") or die "Can't dup OUT: $!";
931 open(STDERR, ">&SAVERR") or die "Can't restore STDERR: $!";
932 pass "no crash with DeadCode";