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.
554 do_test('tainted value in %ENV',
555 $ENV{PATH}=@ARGV, # scalar(@ARGV) is a handy known tainted value
556 'SV = PVMG\\($ADDR\\) at $ADDR
558 FLAGS = \\(GMG,SMG,RMG(?:,POK)?(?:,pIOK)?,pPOK\\)
565 MG_VIRTUAL = &PL_vtbl_envelem
566 MG_TYPE = PERL_MAGIC_envelem\\(e\\)
570 MG_PTR = $ADDR (?:"(?i:PATH)"|=> HEf_SVKEY
571 SV = PV(?:IV)?\\($ADDR\\) at $ADDR
573 FLAGS = \\(TEMP,POK,(?:FAKE,READONLY,)?pPOK\\)
575 )? PV = $ADDR "(?i:PATH)"(?:\\\0)?
579 MG_VIRTUAL = &PL_vtbl_taint
580 MG_TYPE = PERL_MAGIC_taint\\(t\\)');
583 do_test('blessed reference',
584 bless(\\undef, 'Foobar'),
585 'SV = $RV\\($ADDR\\) at $ADDR
589 SV = PVMG\\($ADDR\\) at $ADDR
591 FLAGS = \\(OBJECT,ROK\\)
595 SV = NULL\\(0x0\\) at $ADDR
597 FLAGS = \\(READONLY\\)
601 STASH = $ADDR\s+"Foobar"');
607 do_test('constant subroutine',
609 'SV = $RV\\($ADDR\\) at $ADDR
613 SV = PVCV\\($ADDR\\) at $ADDR
615 FLAGS = \\(POK,pPOK,CONST,ISXSUB\\) # $] < 5.015
616 FLAGS = \\(POK,pPOK,CONST,DYNFILE,ISXSUB\\) # $] >= 5.015
621 ROOT = 0x0 # $] < 5.009
623 XSUBANY = $ADDR \\(CONST SV\\)
624 SV = PV\\($ADDR\\) at $ADDR
626 FLAGS = \\(.*POK,READONLY,pPOK\\)
627 PV = $ADDR "Perl rules"\\\0
630 GVGV::GV = $ADDR\\t"main" :: "const"
631 FILE = ".*\\b(?i:peek\\.t)"
635 FLAGS = 0x200 # $] < 5.009
636 FLAGS = 0xc00 # $] >= 5.009 && $] < 5.013
637 FLAGS = 0xc # $] >= 5.013 && $] < 5.015
638 FLAGS = 0x100c # $] >= 5.015
641 OUTSIDE = 0x0 \\(null\\)');
643 do_test('isUV should show on PVMG',
644 do { my $v = $1; $v = ~0; $v },
645 'SV = PVMG\\($ADDR\\) at $ADDR
647 FLAGS = \\(IOK,pIOK,IsUV\\)
654 'SV = $RV\\($ADDR\\) at $ADDR
658 SV = PVIO\\($ADDR\\) at $ADDR
663 STASH = $ADDR\s+"IO::File"
674 SUBPROCESS = 0 # $] < 5.009
680 'SV = $RV\\($ADDR\\) at $ADDR
684 SV = PVFM\\($ADDR\\) at $ADDR
686 FLAGS = \\(\\) # $] < 5.015 || !thr
687 FLAGS = \\(DYNFILE\\) # $] >= 5.015 && thr
692 START = $ADDR ===> \\d+
694 XSUB = 0x0 # $] < 5.009
695 XSUBANY = 0 # $] < 5.009
696 GVGV::GV = $ADDR\\t"main" :: "PIE"
697 FILE = ".*\\b(?i:peek\\.t)"(?:
701 FLAGS = 0x0 # $] < 5.015 || !thr
702 FLAGS = 0x1000 # $] >= 5.015 && thr
704 LINES = 0 # $] < 5.017_003
706 PADNAME = $ADDR\\($ADDR\\) PAD = $ADDR\\($ADDR\\)
707 OUTSIDE = $ADDR \\(MAIN\\)');
709 do_test('blessing to a class with embedded NUL characters',
710 (bless {}, "\0::foo::\n::baz::\t::\0"),
711 'SV = $RV\\($ADDR\\) at $ADDR
715 SV = PVHV\\($ADDR\\) at $ADDR
717 FLAGS = \\(OBJECT,SHAREKEYS\\)
720 STASH = $ADDR\\t"\\\\0::foo::\\\\n::baz::\\\\t::\\\\0"
730 : 'The hash iterator used in dump.c sets the OOK flag'
731 : "Something causes the HV's array to become allocated");
733 do_test('ENAME on a stash',
735 'SV = $RV\\($ADDR\\) at $ADDR
739 SV = PVHV\\($ADDR\\) at $ADDR
741 FLAGS = \\(OOK,SHAREKEYS\\)
743 NV = $FLOAT # $] < 5.009
751 ENAME = "RWOM" # $] > 5.012
756 do_test('ENAMEs on a stash',
758 'SV = $RV\\($ADDR\\) at $ADDR
762 SV = PVHV\\($ADDR\\) at $ADDR
764 FLAGS = \\(OOK,SHAREKEYS\\)
766 NV = $FLOAT # $] < 5.009
774 NAMECOUNT = 2 # $] > 5.012
775 ENAME = "RWOM", "KLANK" # $] > 5.012
780 do_test('ENAMEs on a stash with no NAME',
782 'SV = $RV\\($ADDR\\) at $ADDR
786 SV = PVHV\\($ADDR\\) at $ADDR
788 FLAGS = \\(OOK,SHAREKEYS\\) # $] < 5.017
789 FLAGS = \\(OOK,OVERLOAD,SHAREKEYS\\) # $] >=5.017
791 NV = $FLOAT # $] < 5.009
798 NAMECOUNT = -3 # $] > 5.012
799 ENAME = "RWOM", "KLANK" # $] > 5.012
803 skip "Not built with usemymalloc", 1
804 unless $Config{usemymalloc} eq 'y';
806 ok eval { fill_mstats($x); 1 }, 'fill_mstats on COW scalar'
810 # This is more a test of fbm_compile/pp_study (non) interaction than dumping
811 # prowess, but short of duplicating all the gubbins of this file, I can't see
812 # a way to make a better place for it:
819 unless ($Config{useithreads}) {
820 # These end up as copies in pads under ithreads, which rather defeats the
821 # the point of what we're trying to test here.
823 do_test('regular string constant', perl,
824 'SV = PV\\($ADDR\\) at $ADDR
826 FLAGS = \\(PADMY,POK,READONLY,pPOK\\)
827 PV = $ADDR "rules"\\\0
832 eval 'index "", perl';
834 # FIXME - really this shouldn't say EVALED. It's a false posistive on
835 # 0x40000000 being used for several things, not a flag for "I'm in a string
838 do_test('string constant now an FBM', perl,
839 'SV = PVMG\\($ADDR\\) at $ADDR
841 FLAGS = \\(PADMY,SMG,POK,READONLY,pPOK,VALID,EVALED\\)
842 PV = $ADDR "rules"\\\0
846 MG_VIRTUAL = &PL_vtbl_regexp
847 MG_TYPE = PERL_MAGIC_bm\\(B\\)
849 MG_PTR = $ADDR "(?:\\\\\d){256}"
855 is(study perl, '', "Not allowed to study an FBM");
857 do_test('string constant still an FBM', perl,
858 'SV = PVMG\\($ADDR\\) at $ADDR
860 FLAGS = \\(PADMY,SMG,POK,READONLY,pPOK,VALID,EVALED\\)
861 PV = $ADDR "rules"\\\0
865 MG_VIRTUAL = &PL_vtbl_regexp
866 MG_TYPE = PERL_MAGIC_bm\\(B\\)
868 MG_PTR = $ADDR "(?:\\\\\d){256}"
874 do_test('regular string constant', beer,
875 'SV = PV\\($ADDR\\) at $ADDR
877 FLAGS = \\(PADMY,POK,READONLY,pPOK\\)
878 PV = $ADDR "foamy"\\\0
883 is(study beer, 1, "Our studies were successful");
885 do_test('string constant quite unaffected', beer, 'SV = PV\\($ADDR\\) at $ADDR
887 FLAGS = \\(PADMY,POK,READONLY,pPOK\\)
888 PV = $ADDR "foamy"\\\0
893 my $want = 'SV = PVMG\\($ADDR\\) at $ADDR
895 FLAGS = \\(PADMY,SMG,POK,READONLY,pPOK,VALID,EVALED\\)
896 PV = $ADDR "foamy"\\\0
900 MG_VIRTUAL = &PL_vtbl_regexp
901 MG_TYPE = PERL_MAGIC_bm\\(B\\)
903 MG_PTR = $ADDR "(?:\\\\\d){256}"
909 is (eval 'index "not too foamy", beer', 8, 'correct index');
911 do_test('string constant now FBMed', beer, $want);
915 is(study $pie, 1, "Our studies were successful");
917 do_test('string constant still FBMed', beer, $want);
919 do_test('second string also unaffected', $pie, 'SV = PV\\($ADDR\\) at $ADDR
921 FLAGS = \\(PADMY,POK,pPOK\\)
922 PV = $ADDR "good"\\\0
928 # (One block of study tests removed when study was made a no-op.)
931 open(OUT,">peek$$") or die "Failed to open peek $$: $!";
932 open(STDERR, ">&OUT") or die "Can't dup OUT: $!";
934 open(STDERR, ">&SAVERR") or die "Can't restore STDERR: $!";
935 pass "no crash with DeadCode";