6 require Config; import Config;
7 if ($Config{'extensions'} !~ /\bDevel\/Peek\b/) {
8 print "1..0 # Skip: Devel::Peek was not built\n";
13 BEGIN { require "./test.pl"; }
20 open(SAVERR, ">&STDERR") or die "Can't dup STDERR: $!";
22 # If I reference any lexicals in this, I get the entire outer subroutine (or
23 # MAIN) dumped too, which isn't really what I want, as it's a lot of faff to
34 my $repeat_todo = $_[4];
36 if (open(OUT,">peek$$")) {
37 open(STDERR, ">&OUT") or die "Can't dup OUT: $!";
39 print STDERR "*****\n";
40 Dump($_[1]); # second dump to compare with the first to make sure nothing changed.
41 open(STDERR, ">&SAVERR") or die "Can't restore STDERR: $!";
43 if (open(IN, "peek$$")) {
45 $pattern =~ s/\$ADDR/0x[[:xdigit:]]+/g;
46 $pattern =~ s/\$FLOAT/(?:\\d*\\.\\d+(?:e[-+]\\d+)?|\\d+)/g;
47 # handle DEBUG_LEAKING_SCALARS prefix
48 $pattern =~ s/^(\s*)(SV =.* at )/(?:$1ALLOCATED at .*?\n)?$1$2/mg;
50 # Need some clear generic mechanism to eliminate (or add) lines
51 # of dump output dependant on perl version. The (previous) use of
52 # things like $IVNV gave the illusion that the string passed in was
53 # a regexp into which variables were interpolated, but this wasn't
54 # actually true as those 'variables' actually also ate the
55 # whitspace on the line. So it seems better to mark lines that
56 # need to be eliminated. I considered (?# ... ) and (?{ ... }),
57 # but whilst embedded code or comment syntax would keep it as a
58 # legitimate regexp, it still isn't true. Seems easier and clearer
59 # things that look like comments.
61 # Could do this is in a s///mge but seems clearer like this:
62 $pattern = join '', map {
63 # If we identify the version condition, take *it* out whatever
64 s/\s*# (\$] [<>]=? 5\.\d\d\d)$//
66 : $_ # Didn't match, so this line is in
67 } split /^/, $pattern;
69 $pattern =~ s/\$PADMY/
70 ($] < 5.009) ? 'PADBUSY,PADMY' : 'PADMY';
72 $pattern =~ s/\$PADTMP/
73 ($] < 5.009) ? 'PADBUSY,PADTMP' : 'PADTMP';
76 ($] < 5.011) ? 'RV' : 'IV';
79 print $pattern, "\n" if $DEBUG;
80 my ($dump, $dump2) = split m/\*\*\*\*\*\n/, scalar <IN>;
81 print $dump, "\n" if $DEBUG;
82 like( $dump, qr/\A$pattern\Z/ms );
84 local $TODO = $repeat_todo;
91 die "$0: failed to open peek$$: !\n";
94 die "$0: failed to create peek$$: $!\n";
104 1 while unlink("peek$$");
109 'SV = PV\\($ADDR\\) at $ADDR
111 FLAGS = \\(POK,pPOK\\)
119 'SV = PV\\($ADDR\\) at $ADDR
121 FLAGS = \\(.*POK,READONLY,pPOK\\)
128 'SV = IV\\($ADDR\\) at $ADDR
130 FLAGS = \\(IOK,pIOK\\)
135 'SV = IV\\($ADDR\\) at $ADDR
137 FLAGS = \\(.*IOK,READONLY,pIOK\\)
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( 6,
154 'SV = ([NI])V\\($ADDR\\) at $ADDR
156 FLAGS = \\(PADTMP,\1OK,p\1OK\\)
163 'SV = PVNV\\($ADDR\\) at $ADDR
165 FLAGS = \\(NOK,pNOK\\)
167 NV = 789\\.(?:1(?:000+\d+)?|0999+\d+)
174 'SV = IV\\($ADDR\\) at $ADDR
176 FLAGS = \\(.*IOK,READONLY,pIOK\\)
181 'SV = NULL\\(0x0\\) at $ADDR
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\\)
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);
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 && 'The hash iterator used in dump.c sets the OOK flag');
261 'SV = $RV\\($ADDR\\) at $ADDR
265 SV = PVCV\\($ADDR\\) at $ADDR
267 FLAGS = \\($PADMY,POK,pPOK,ANON,WEAKOUTSIDE\\)
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 = 0x90 # $] >= 5.009
285 PADNAME = $ADDR\\($ADDR\\) PAD = $ADDR\\($ADDR\\)
286 OUTSIDE = $ADDR \\(MAIN\\)');
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+> FAKE "\\$DEBUG" # $] < 5.009
317 \\d+\\. $ADDR<\\d+> FAKE "\\$DEBUG" flags=0x0 index=0 # $] >= 5.009
318 \\d+\\. $ADDR<\\d+> \\(\\d+,\\d+\\) "\\$dump"
319 \\d+\\. $ADDR<\\d+> \\(\\d+,\\d+\\) "\\$dump2"
320 OUTSIDE = $ADDR \\(MAIN\\)');
325 'SV = $RV\\($ADDR\\) at $ADDR
329 SV = REGEXP\\($ADDR\\) at $ADDR
331 FLAGS = \\(OBJECT,POK,pPOK\\)
333 PV = $ADDR "\\(\\?-xism:tic\\)"\\\0
336 STASH = $ADDR\\t"Regexp"');
340 'SV = $RV\\($ADDR\\) at $ADDR
344 SV = PVMG\\($ADDR\\) at $ADDR
346 FLAGS = \\(OBJECT,SMG\\)
352 MG_TYPE = PERL_MAGIC_qr\(r\)
354 PAT = "\(\?-xism:tic\)" # $] >= 5.009
355 REFCNT = 2 # $] >= 5.009
356 STASH = $ADDR\\t"Regexp"');
361 'SV = $RV\\($ADDR\\) at $ADDR
365 SV = PVHV\\($ADDR\\) at $ADDR
367 FLAGS = \\(OBJECT,SHAREKEYS\\)
370 STASH = $ADDR\\t"Tac"
377 $] > 5.009 ? 'The hash iterator used in dump.c sets the OOK flag'
378 : "Something causes the HV's array to become allocated");
382 'SV = PVGV\\($ADDR\\) at $ADDR
384 FLAGS = \\(MULTI(?:,IN_PAD)?\\) # $] >= 5.009
385 FLAGS = \\(GMG,SMG,MULTI(?:,IN_PAD)?\\) # $] < 5.009
389 MAGIC = $ADDR # $] < 5.009
390 MG_VIRTUAL = &PL_vtbl_glob # $] < 5.009
391 MG_TYPE = PERL_MAGIC_glob\(\*\) # $] < 5.009
392 MG_OBJ = $ADDR # $] < 5.009
395 GvSTASH = $ADDR\\t"main"
405 GPFLAGS = 0x0 # $] < 5.009
407 FILE = ".*\\b(?i:peek\\.t)"
411 if (ord('A') == 193) {
413 chr(256).chr(0).chr(512),
414 'SV = PV\\($ADDR\\) at $ADDR
416 FLAGS = \\((?:$PADTMP,)?POK,READONLY,pPOK,UTF8\\)
417 PV = $ADDR "\\\214\\\101\\\0\\\235\\\101"\\\0 \[UTF8 "\\\x\{100\}\\\x\{0\}\\\x\{200\}"\]
422 chr(256).chr(0).chr(512),
423 'SV = PV\\($ADDR\\) at $ADDR
425 FLAGS = \\((?:$PADTMP,)?POK,READONLY,pPOK,UTF8\\)
426 PV = $ADDR "\\\304\\\200\\\0\\\310\\\200"\\\0 \[UTF8 "\\\x\{100\}\\\x\{0\}\\\x\{200\}"\]
431 if (ord('A') == 193) {
433 {chr(256)=>chr(512)},
434 'SV = $RV\\($ADDR\\) at $ADDR
438 SV = PVHV\\($ADDR\\) at $ADDR
440 FLAGS = \\(SHAREKEYS,HASKFLAGS\\)
442 NV = $FLOAT # $] < 5.009
443 ARRAY = $ADDR \\(0:7, 1:1\\)
444 hash quality = 100.0%
450 Elt "\\\214\\\101" \[UTF8 "\\\x\{100\}"\] HASH = $ADDR
451 SV = PV\\($ADDR\\) at $ADDR
453 FLAGS = \\(POK,pPOK,UTF8\\)
454 PV = $ADDR "\\\235\\\101"\\\0 \[UTF8 "\\\x\{200\}"\]
457 $] > 5.009 ? 'The hash iterator used in dump.c sets the OOK flag'
458 : 'sv_length has been called on the element, and cached the result in MAGIC');
461 {chr(256)=>chr(512)},
462 'SV = $RV\\($ADDR\\) at $ADDR
466 SV = PVHV\\($ADDR\\) at $ADDR
468 FLAGS = \\(SHAREKEYS,HASKFLAGS\\)
471 ARRAY = $ADDR \\(0:7, 1:1\\)
472 hash quality = 100.0%
478 Elt "\\\304\\\200" \[UTF8 "\\\x\{100\}"\] HASH = $ADDR
479 SV = PV\\($ADDR\\) at $ADDR
481 FLAGS = \\(POK,pPOK,UTF8\\)
482 PV = $ADDR "\\\310\\\200"\\\0 \[UTF8 "\\\x\{200\}"\]
485 $] > 5.009 ? 'The hash iterator used in dump.c sets the OOK flag'
486 : 'sv_length has been called on the element, and cached the result in MAGIC');
493 'SV = PVMG\\($ADDR\\) at $ADDR
495 FLAGS = \\($PADMY,SMG,POK,pPOK\\)
502 MG_VIRTUAL = &PL_vtbl_mglob
503 MG_TYPE = PERL_MAGIC_regex_global\\(g\\)
508 # TAINTEDDIR is not set on: OS2, AMIGAOS, WIN32, MSDOS
509 # environment variables may be invisibly case-forced, hence the (?i:PATH)
510 # C<scalar(@ARGV)> is turned into an IV on VMS hence the (?:IV)?
511 # VMS is setting FAKE and READONLY flags. What VMS uses for storing
512 # ENV hashes is also not always null terminated.
515 $ENV{PATH}=@ARGV, # scalar(@ARGV) is a handy known tainted value
516 'SV = PVMG\\($ADDR\\) at $ADDR
518 FLAGS = \\(GMG,SMG,RMG,pIOK,pPOK\\)
525 MG_VIRTUAL = &PL_vtbl_envelem
526 MG_TYPE = PERL_MAGIC_envelem\\(e\\)
530 MG_PTR = $ADDR (?:"(?i:PATH)"|=> HEf_SVKEY
531 SV = PV(?:IV)?\\($ADDR\\) at $ADDR
533 FLAGS = \\(TEMP,POK,(?:FAKE,READONLY,)?pPOK\\)
535 )? PV = $ADDR "(?i:PATH)"(?:\\\0)?
539 MG_VIRTUAL = &PL_vtbl_taint
540 MG_TYPE = PERL_MAGIC_taint\\(t\\)');
544 bless(\\undef, 'Foobar'),
545 'SV = $RV\\($ADDR\\) at $ADDR
549 SV = PVMG\\($ADDR\\) at $ADDR
551 FLAGS = \\(OBJECT,ROK\\)
555 SV = NULL\\(0x0\\) at $ADDR
557 FLAGS = \\(READONLY\\)
561 STASH = $ADDR\s+"Foobar"');
563 # Constant subroutines
571 'SV = $RV\\($ADDR\\) at $ADDR
575 SV = PVCV\\($ADDR\\) at $ADDR
577 FLAGS = \\(POK,pPOK,CONST\\)
582 ROOT = 0x0 # $] < 5.009
584 XSUBANY = $ADDR \\(CONST SV\\)
585 SV = PV\\($ADDR\\) at $ADDR
587 FLAGS = \\(.*POK,READONLY,pPOK\\)
588 PV = $ADDR "Perl rules"\\\0
591 GVGV::GV = $ADDR\\t"main" :: "const"
592 FILE = ".*\\b(?i:peek\\.t)"
596 FLAGS = 0x200 # $] < 5.009
597 FLAGS = 0xc00 # $] >= 5.009
600 OUTSIDE = 0x0 \\(null\\)');
602 # isUV should show on PVMG
604 do { my $v = $1; $v = ~0; $v },
605 'SV = PVMG\\($ADDR\\) at $ADDR
607 FLAGS = \\(IOK,pIOK,IsUV\\)
614 'SV = $RV\\($ADDR\\) at $ADDR
618 SV = PVIO\\($ADDR\\) at $ADDR
623 STASH = $ADDR\s+"IO::Handle"
634 SUBPROCESS = 0 # $] < 5.009
640 'SV = $RV\\($ADDR\\) at $ADDR
644 SV = PVFM\\($ADDR\\) at $ADDR
651 START = $ADDR ===> \\d+
653 XSUB = 0x0 # $] < 5.009
654 XSUBANY = 0 # $] < 5.009
655 GVGV::GV = $ADDR\\t"main" :: "PIE"
656 FILE = ".*\\b(?i:peek\\.t)"
664 PADNAME = $ADDR\\($ADDR\\) PAD = $ADDR\\($ADDR\\)
665 OUTSIDE = $ADDR \\(MAIN\\)');