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
30 my $repeat_todo = $_[4];
32 if (open(OUT,">peek$$")) {
33 open(STDERR, ">&OUT") or die "Can't dup OUT: $!";
35 print STDERR "*****\n";
36 Dump($_[1]); # second dump to compare with the first to make sure nothing changed.
37 open(STDERR, ">&SAVERR") or die "Can't restore STDERR: $!";
39 if (open(IN, "peek$$")) {
41 $pattern =~ s/\$ADDR/0x[[:xdigit:]]+/g;
42 $pattern =~ s/\$FLOAT/(?:\\d*\\.\\d+(?:e[-+]\\d+)?|\\d+)/g;
43 # handle DEBUG_LEAKING_SCALARS prefix
44 $pattern =~ s/^(\s*)(SV =.* at )/(?:$1ALLOCATED at .*?\n)?$1$2/mg;
46 # Need some clear generic mechanism to eliminate (or add) lines
47 # of dump output dependant on perl version. The (previous) use of
48 # things like $IVNV gave the illusion that the string passed in was
49 # a regexp into which variables were interpolated, but this wasn't
50 # actually true as those 'variables' actually also ate the
51 # whitespace on the line. So it seems better to mark lines that
52 # need to be eliminated. I considered (?# ... ) and (?{ ... }),
53 # but whilst embedded code or comment syntax would keep it as a
54 # legitimate regexp, it still isn't true. Seems easier and clearer
55 # things that look like comments.
57 my $version_condition = qr/\$] [<>]=? 5\.\d\d\d/;
58 # Could do this is in a s///mge but seems clearer like this:
59 $pattern = join '', map {
60 # If we identify the version condition, take *it* out whatever
61 s/\s*# ($version_condition(?: && $version_condition)?)$//
63 : $_ # Didn't match, so this line is in
64 } split /^/, $pattern;
66 $pattern =~ s/\$PADMY/
67 ($] < 5.009) ? 'PADBUSY,PADMY' : 'PADMY';
69 $pattern =~ s/\$PADTMP/
70 ($] < 5.009) ? 'PADBUSY,PADTMP' : 'PADTMP';
73 ($] < 5.011) ? 'RV' : 'IV';
76 print $pattern, "\n" if $DEBUG;
77 my ($dump, $dump2) = split m/\*\*\*\*\*\n/, scalar <IN>;
78 print $dump, "\n" if $DEBUG;
79 like( $dump, qr/\A$pattern\Z/ms, $_[0])
80 or note("line " . (caller)[2]);
82 local $TODO = $repeat_todo;
83 is($dump2, $dump, "$_[0] (unchanged by dump)")
84 or note("line " . (caller)[2]);
90 die "$0: failed to open peek$$: !\n";
93 die "$0: failed to create peek$$: $!\n";
103 1 while unlink("peek$$");
106 do_test('assignment of immediate constant (string)',
108 'SV = PV\\($ADDR\\) at $ADDR
110 FLAGS = \\(POK,pPOK\\)
116 do_test('immediate constant (string)',
118 'SV = PV\\($ADDR\\) at $ADDR
120 FLAGS = \\(.*POK,READONLY,pPOK\\)
125 do_test('assignment of immediate constant (integer)',
127 'SV = IV\\($ADDR\\) at $ADDR
129 FLAGS = \\(IOK,pIOK\\)
132 do_test('immediate constant (integer)',
134 'SV = IV\\($ADDR\\) at $ADDR
136 FLAGS = \\(.*IOK,READONLY,pIOK\\)
139 do_test('assignment of immediate constant (integer)',
141 'SV = IV\\($ADDR\\) at $ADDR
143 FLAGS = \\($PADMY,IOK,pIOK\\)
146 # If perl is built with PERL_PRESERVE_IVUV then maths is done as integers
147 # where possible and this scalar will be an IV. If NO_PERL_PRESERVE_IVUV then
148 # maths is done in floating point always, and this scalar will be an NV.
149 # ([NI]) captures the type, referred to by \1 in this regexp and $type for
150 # building subsequent regexps.
151 my $type = do_test('result of addition',
153 'SV = ([NI])V\\($ADDR\\) at $ADDR
155 FLAGS = \\(PADTMP,\1OK,p\1OK\\)
160 do_test('floating point value',
162 'SV = PVNV\\($ADDR\\) at $ADDR
164 FLAGS = \\(NOK,pNOK\\)
166 NV = 789\\.(?:1(?:000+\d+)?|0999+\d+)
171 do_test('integer constant',
173 'SV = IV\\($ADDR\\) at $ADDR
175 FLAGS = \\(.*IOK,READONLY,pIOK\\)
180 'SV = NULL\\(0x0\\) at $ADDR
184 do_test('reference to scalar',
186 'SV = $RV\\($ADDR\\) at $ADDR
190 SV = PV\\($ADDR\\) at $ADDR
192 FLAGS = \\(POK,pPOK\\)
200 SV = PVNV\\($ADDR\\) at $ADDR
202 FLAGS = \\(IOK,NOK,pIOK,pNOK\\)
208 SV = IV\\($ADDR\\) at $ADDR
210 FLAGS = \\(IOK,pIOK\\)
213 do_test('reference to array',
215 'SV = $RV\\($ADDR\\) at $ADDR
219 SV = PVAV\\($ADDR\\) at $ADDR
230 SV = IV\\($ADDR\\) at $ADDR
232 FLAGS = \\(IOK,pIOK\\)
234 Elt No. 1' . $c_pattern);
236 do_test('reference to hash',
238 'SV = $RV\\($ADDR\\) at $ADDR
242 SV = PVHV\\($ADDR\\) at $ADDR
244 FLAGS = \\(SHAREKEYS\\)
246 NV = $FLOAT # $] < 5.009
247 ARRAY = $ADDR \\(0:7, 1:1\\)
248 hash quality = 100.0%
254 Elt "123" HASH = $ADDR' . $c_pattern,
256 $] > 5.009 && $] < 5.015
257 && 'The hash iterator used in dump.c sets the OOK flag');
259 do_test('reference to anon sub with empty prototype',
261 'SV = $RV\\($ADDR\\) at $ADDR
265 SV = PVCV\\($ADDR\\) at $ADDR
267 FLAGS = \\($PADMY,POK,pPOK,ANON,WEAKOUTSIDE,CVGV_RC\\)
271 COMP_STASH = $ADDR\\t"main"
272 START = $ADDR ===> \\d+
274 XSUB = 0x0 # $] < 5.009
275 XSUBANY = 0 # $] < 5.009
276 GVGV::GV = $ADDR\\t"main" :: "__ANON__[^"]*"
277 FILE = ".*\\b(?i:peek\\.t)"
281 FLAGS = 0x404 # $] < 5.009
282 FLAGS = 0x490 # $] >= 5.009
285 PADNAME = $ADDR\\($ADDR\\) PAD = $ADDR\\($ADDR\\)
286 OUTSIDE = $ADDR \\(MAIN\\)');
288 do_test('reference to named subroutine without prototype',
290 'SV = $RV\\($ADDR\\) at $ADDR
294 SV = PVCV\\($ADDR\\) at $ADDR
299 COMP_STASH = $ADDR\\t"main"
300 START = $ADDR ===> \\d+
302 XSUB = 0x0 # $] < 5.009
303 XSUBANY = 0 # $] < 5.009
304 GVGV::GV = $ADDR\\t"main" :: "do_test"
305 FILE = ".*\\b(?i:peek\\.t)"
312 PADNAME = $ADDR\\($ADDR\\) PAD = $ADDR\\($ADDR\\)
313 \\d+\\. $ADDR<\\d+> \\(\\d+,\\d+\\) "\\$todo"
314 \\d+\\. $ADDR<\\d+> \\(\\d+,\\d+\\) "\\$repeat_todo"
315 \\d+\\. $ADDR<\\d+> \\(\\d+,\\d+\\) "\\$pattern"
316 \\d+\\. $ADDR<\\d+> \\(\\d+,\\d+\\) "\\$version_condition"
317 \\d+\\. $ADDR<\\d+> FAKE "\\$DEBUG" # $] < 5.009
318 \\d+\\. $ADDR<\\d+> FAKE "\\$DEBUG" flags=0x0 index=0 # $] >= 5.009
319 \\d+\\. $ADDR<\\d+> \\(\\d+,\\d+\\) "\\$dump"
320 \\d+\\. $ADDR<\\d+> \\(\\d+,\\d+\\) "\\$dump2"
321 OUTSIDE = $ADDR \\(MAIN\\)');
324 do_test('reference to regexp',
326 'SV = $RV\\($ADDR\\) at $ADDR
330 SV = REGEXP\\($ADDR\\) at $ADDR
332 FLAGS = \\(OBJECT,POK,FAKE,pPOK\\)
333 PV = $ADDR "\\(\\?\\^:tic\\)"
336 STASH = $ADDR\\t"Regexp"'
339 EXTFLAGS = 0x680000 \(CHECK_ALL,USE_INTUIT_NOML,USE_INTUIT_ML\)
359 do_test('reference to regexp',
361 'SV = $RV\\($ADDR\\) at $ADDR
365 SV = PVMG\\($ADDR\\) at $ADDR
367 FLAGS = \\(OBJECT,SMG\\)
373 MG_TYPE = PERL_MAGIC_qr\(r\)
375 PAT = "\(\?^:tic\)" # $] >= 5.009
376 REFCNT = 2 # $] >= 5.009
377 STASH = $ADDR\\t"Regexp"');
380 do_test('reference to blessed hash',
382 'SV = $RV\\($ADDR\\) at $ADDR
386 SV = PVHV\\($ADDR\\) at $ADDR
388 FLAGS = \\(OBJECT,SHAREKEYS\\)
391 STASH = $ADDR\\t"Tac"
401 : 'The hash iterator used in dump.c sets the OOK flag'
402 : "Something causes the HV's array to become allocated");
406 'SV = PVGV\\($ADDR\\) at $ADDR
408 FLAGS = \\(MULTI(?:,IN_PAD)?\\) # $] >= 5.009
409 FLAGS = \\(GMG,SMG,MULTI(?:,IN_PAD)?\\) # $] < 5.009
413 MAGIC = $ADDR # $] < 5.009
414 MG_VIRTUAL = &PL_vtbl_glob # $] < 5.009
415 MG_TYPE = PERL_MAGIC_glob\(\*\) # $] < 5.009
416 MG_OBJ = $ADDR # $] < 5.009
419 GvSTASH = $ADDR\\t"main"
429 GPFLAGS = 0x0 # $] < 5.009
431 FILE = ".*\\b(?i:peek\\.t)"
435 if (ord('A') == 193) {
436 do_test('string with Unicode',
437 chr(256).chr(0).chr(512),
438 'SV = PV\\($ADDR\\) at $ADDR
440 FLAGS = \\((?:$PADTMP,)?POK,READONLY,pPOK,UTF8\\)
441 PV = $ADDR "\\\214\\\101\\\0\\\235\\\101"\\\0 \[UTF8 "\\\x\{100\}\\\x\{0\}\\\x\{200\}"\]
445 do_test('string with Unicode',
446 chr(256).chr(0).chr(512),
447 'SV = PV\\($ADDR\\) at $ADDR
449 FLAGS = \\((?:$PADTMP,)?POK,READONLY,pPOK,UTF8\\)
450 PV = $ADDR "\\\304\\\200\\\0\\\310\\\200"\\\0 \[UTF8 "\\\x\{100\}\\\x\{0\}\\\x\{200\}"\]
455 if (ord('A') == 193) {
456 do_test('reference to hash containing Unicode',
457 {chr(256)=>chr(512)},
458 'SV = $RV\\($ADDR\\) at $ADDR
462 SV = PVHV\\($ADDR\\) at $ADDR
464 FLAGS = \\(SHAREKEYS,HASKFLAGS\\)
466 NV = $FLOAT # $] < 5.009
467 ARRAY = $ADDR \\(0:7, 1:1\\)
468 hash quality = 100.0%
474 Elt "\\\214\\\101" \[UTF8 "\\\x\{100\}"\] HASH = $ADDR
475 SV = PV\\($ADDR\\) at $ADDR
477 FLAGS = \\(POK,pPOK,UTF8\\)
478 PV = $ADDR "\\\235\\\101"\\\0 \[UTF8 "\\\x\{200\}"\]
484 : 'The hash iterator used in dump.c sets the OOK flag'
485 : 'sv_length has been called on the element, and cached the result in MAGIC');
487 do_test('reference to hash containing Unicode',
488 {chr(256)=>chr(512)},
489 'SV = $RV\\($ADDR\\) at $ADDR
493 SV = PVHV\\($ADDR\\) at $ADDR
495 FLAGS = \\(SHAREKEYS,HASKFLAGS\\)
498 ARRAY = $ADDR \\(0:7, 1:1\\)
499 hash quality = 100.0%
505 Elt "\\\304\\\200" \[UTF8 "\\\x\{100\}"\] HASH = $ADDR
506 SV = PV\\($ADDR\\) at $ADDR
508 FLAGS = \\(POK,pPOK,UTF8\\)
509 PV = $ADDR "\\\310\\\200"\\\0 \[UTF8 "\\\x\{200\}"\]
515 : 'The hash iterator used in dump.c sets the OOK flag'
516 : 'sv_length has been called on the element, and cached the result in MAGIC');
521 do_test('scalar with pos magic',
523 'SV = PVMG\\($ADDR\\) at $ADDR
525 FLAGS = \\($PADMY,SMG,POK,pPOK\\)
532 MG_VIRTUAL = &PL_vtbl_mglob
533 MG_TYPE = PERL_MAGIC_regex_global\\(g\\)
538 # TAINTEDDIR is not set on: OS2, AMIGAOS, WIN32, MSDOS
539 # environment variables may be invisibly case-forced, hence the (?i:PATH)
540 # C<scalar(@ARGV)> is turned into an IV on VMS hence the (?:IV)?
541 # VMS is setting FAKE and READONLY flags. What VMS uses for storing
542 # ENV hashes is also not always null terminated.
544 do_test('tainted value in %ENV',
545 $ENV{PATH}=@ARGV, # scalar(@ARGV) is a handy known tainted value
546 'SV = PVMG\\($ADDR\\) at $ADDR
548 FLAGS = \\(GMG,SMG,RMG,pIOK,pPOK\\)
555 MG_VIRTUAL = &PL_vtbl_envelem
556 MG_TYPE = PERL_MAGIC_envelem\\(e\\)
560 MG_PTR = $ADDR (?:"(?i:PATH)"|=> HEf_SVKEY
561 SV = PV(?:IV)?\\($ADDR\\) at $ADDR
563 FLAGS = \\(TEMP,POK,(?:FAKE,READONLY,)?pPOK\\)
565 )? PV = $ADDR "(?i:PATH)"(?:\\\0)?
569 MG_VIRTUAL = &PL_vtbl_taint
570 MG_TYPE = PERL_MAGIC_taint\\(t\\)');
572 do_test('blessed reference',
573 bless(\\undef, 'Foobar'),
574 'SV = $RV\\($ADDR\\) at $ADDR
578 SV = PVMG\\($ADDR\\) at $ADDR
580 FLAGS = \\(OBJECT,ROK\\)
584 SV = NULL\\(0x0\\) at $ADDR
586 FLAGS = \\(READONLY\\)
590 STASH = $ADDR\s+"Foobar"');
596 do_test('constant subroutine',
598 'SV = $RV\\($ADDR\\) at $ADDR
602 SV = PVCV\\($ADDR\\) at $ADDR
604 FLAGS = \\(POK,pPOK,CONST,ISXSUB\\)
609 ROOT = 0x0 # $] < 5.009
611 XSUBANY = $ADDR \\(CONST SV\\)
612 SV = PV\\($ADDR\\) at $ADDR
614 FLAGS = \\(.*POK,READONLY,pPOK\\)
615 PV = $ADDR "Perl rules"\\\0
618 GVGV::GV = $ADDR\\t"main" :: "const"
619 FILE = ".*\\b(?i:peek\\.t)"
623 FLAGS = 0x200 # $] < 5.009
624 FLAGS = 0xc00 # $] >= 5.009 && $] < 5.013
625 FLAGS = 0xc # $] >= 5.013
628 OUTSIDE = 0x0 \\(null\\)');
630 do_test('isUV should show on PVMG',
631 do { my $v = $1; $v = ~0; $v },
632 'SV = PVMG\\($ADDR\\) at $ADDR
634 FLAGS = \\(IOK,pIOK,IsUV\\)
641 'SV = $RV\\($ADDR\\) at $ADDR
645 SV = PVIO\\($ADDR\\) at $ADDR
650 STASH = $ADDR\s+"IO::File"
661 SUBPROCESS = 0 # $] < 5.009
667 'SV = $RV\\($ADDR\\) at $ADDR
671 SV = PVFM\\($ADDR\\) at $ADDR
678 START = $ADDR ===> \\d+
680 XSUB = 0x0 # $] < 5.009
681 XSUBANY = 0 # $] < 5.009
682 GVGV::GV = $ADDR\\t"main" :: "PIE"
683 FILE = ".*\\b(?i:peek\\.t)"
691 PADNAME = $ADDR\\($ADDR\\) PAD = $ADDR\\($ADDR\\)
692 OUTSIDE = $ADDR \\(MAIN\\)');
694 do_test('blessing to a class with embedded NUL characters',
695 (bless {}, "\0::foo::\n::baz::\t::\0"),
696 'SV = $RV\\($ADDR\\) at $ADDR
700 SV = PVHV\\($ADDR\\) at $ADDR
702 FLAGS = \\(OBJECT,SHAREKEYS\\)
705 STASH = $ADDR\\t"\\\\0::foo::\\\\n::baz::\\\\t::\\\\0"
715 : 'The hash iterator used in dump.c sets the OOK flag'
716 : "Something causes the HV's array to become allocated");
718 do_test('ENAME on a stash',
720 'SV = $RV\\($ADDR\\) at $ADDR
724 SV = PVHV\\($ADDR\\) at $ADDR
726 FLAGS = \\(OOK,SHAREKEYS\\)
728 NV = $FLOAT # $] < 5.009
736 ENAME = "RWOM" # $] > 5.012
741 do_test('ENAMEs on a stash',
743 'SV = $RV\\($ADDR\\) at $ADDR
747 SV = PVHV\\($ADDR\\) at $ADDR
749 FLAGS = \\(OOK,SHAREKEYS\\)
751 NV = $FLOAT # $] < 5.009
759 NAMECOUNT = 2 # $] > 5.012
760 ENAME = "RWOM", "KLANK" # $] > 5.012
765 do_test('ENAMEs on a stash with no NAME',
767 'SV = $RV\\($ADDR\\) at $ADDR
771 SV = PVHV\\($ADDR\\) at $ADDR
773 FLAGS = \\(OOK,SHAREKEYS\\)
775 NV = $FLOAT # $] < 5.009
782 NAMECOUNT = -3 # $] > 5.012
783 ENAME = "RWOM", "KLANK" # $] > 5.012
787 skip "Not built with usemymalloc", 1
788 unless $Config{usemymalloc} eq 'y';
790 ok eval { fill_mstats($x); 1 }, 'fill_mstats on COW scalar'
794 # This is more a test of fbm_compile/pp_study (non) interaction than dumping
795 # prowess, but short of duplicating all the gubbins of this file, I can't see
796 # a way to make a better place for it:
803 unless ($Config{useithreads}) {
804 # These end up as copies in pads under ithreads, which rather defeats the
805 # the point of what we're trying to test here.
807 do_test('regular string constant', perl,
808 'SV = PV\\($ADDR\\) at $ADDR
810 FLAGS = \\(PADMY,POK,READONLY,pPOK\\)
811 PV = $ADDR "rules"\\\0
816 eval 'index "", perl';
818 # FIXME - really this shouldn't say EVALED. It's a false posistive on
819 # 0x40000000 being used for several things, not a flag for "I'm in a string
822 do_test('string constant now an FBM', perl,
823 'SV = PVMG\\($ADDR\\) at $ADDR
825 FLAGS = \\(PADMY,SMG,POK,READONLY,pPOK,VALID,EVALED\\)
826 PV = $ADDR "rules"\\\0
830 MG_VIRTUAL = &PL_vtbl_regexp
831 MG_TYPE = PERL_MAGIC_bm\\(B\\)
833 MG_PTR = $ADDR "(?:\\\\\d){256}"
839 is(study perl, '', "Not allowed to study an FBM");
841 do_test('string constant still an FBM', perl,
842 'SV = PVMG\\($ADDR\\) at $ADDR
844 FLAGS = \\(PADMY,SMG,POK,READONLY,pPOK,VALID,EVALED\\)
845 PV = $ADDR "rules"\\\0
849 MG_VIRTUAL = &PL_vtbl_regexp
850 MG_TYPE = PERL_MAGIC_bm\\(B\\)
852 MG_PTR = $ADDR "(?:\\\\\d){256}"
858 do_test('regular string constant', beer,
859 'SV = PV\\($ADDR\\) at $ADDR
861 FLAGS = \\(PADMY,POK,READONLY,pPOK\\)
862 PV = $ADDR "foamy"\\\0
867 my $want = 'SV = PVMG\\($ADDR\\) at $ADDR
869 FLAGS = \\(PADMY,SMG,POK,READONLY,pPOK,SCREAM\\)
872 PV = $ADDR "foamy"\\\0
876 MG_VIRTUAL = &PL_vtbl_regexp
877 MG_TYPE = PERL_MAGIC_study\\(G\\)
879 MG_PTR = $ADDR "\\\\377\\\\377\\\\377\\\\377.*"
882 is(study beer, 1, "Our studies were successful");
884 do_test('string constant now studied', beer, $want);
886 is (eval 'index "not too foamy", beer', 8, 'correct index');
888 do_test('string constant still studied', beer, $want);
892 is(study $pie, 1, "Our studies were successful");
894 do_test('string constant still studied', beer, $want);
896 do_test('second string also studied', $pie, 'SV = PVMG\\($ADDR\\) at $ADDR
898 FLAGS = \\(PADMY,SMG,POK,pPOK,SCREAM\\)
901 PV = $ADDR "good"\\\0
905 MG_VIRTUAL = &PL_vtbl_regexp
906 MG_TYPE = PERL_MAGIC_study\\(G\\)
908 MG_PTR = $ADDR "\\\\377\\\\377\\\\377\\\\377.*"