4 require Config; import Config;
5 if ($Config{'extensions'} !~ /\bDevel\/Peek\b/) {
6 print "1..0 # Skip: Devel::Peek was not built\n";
11 BEGIN { require "../../t/test.pl"; }
18 open(SAVERR, ">&STDERR") or die "Can't dup STDERR: $!";
20 # If I reference any lexicals in this, I get the entire outer subroutine (or
21 # MAIN) dumped too, which isn't really what I want, as it's a lot of faff to
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 # whitspace 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
62 s/\s*# (\$] [<>]=? 5\.\d\d\d)$//
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 );
82 local $TODO = $repeat_todo;
89 die "$0: failed to open peek$$: !\n";
92 die "$0: failed to create peek$$: $!\n";
102 1 while unlink("peek$$");
107 'SV = PV\\($ADDR\\) at $ADDR
109 FLAGS = \\(POK,pPOK\\)
117 'SV = PV\\($ADDR\\) at $ADDR
119 FLAGS = \\(.*POK,READONLY,pPOK\\)
126 'SV = IV\\($ADDR\\) at $ADDR
128 FLAGS = \\(IOK,pIOK\\)
133 'SV = IV\\($ADDR\\) at $ADDR
135 FLAGS = \\(.*IOK,READONLY,pIOK\\)
140 'SV = IV\\($ADDR\\) at $ADDR
142 FLAGS = \\($PADMY,IOK,pIOK\\)
145 # If perl is built with PERL_PRESERVE_IVUV then maths is done as integers
146 # where possible and this scalar will be an IV. If NO_PERL_PRESERVE_IVUV then
147 # maths is done in floating point always, and this scalar will be an NV.
148 # ([NI]) captures the type, referred to by \1 in this regexp and $type for
149 # building subsequent regexps.
150 my $type = do_test( 6,
152 'SV = ([NI])V\\($ADDR\\) at $ADDR
154 FLAGS = \\(PADTMP,\1OK,p\1OK\\)
161 'SV = PVNV\\($ADDR\\) at $ADDR
163 FLAGS = \\(NOK,pNOK\\)
165 NV = 789\\.(?:1(?:000+\d+)?|0999+\d+)
172 'SV = IV\\($ADDR\\) at $ADDR
174 FLAGS = \\(.*IOK,READONLY,pIOK\\)
179 'SV = NULL\\(0x0\\) at $ADDR
185 'SV = $RV\\($ADDR\\) at $ADDR
189 SV = PV\\($ADDR\\) at $ADDR
191 FLAGS = \\(POK,pPOK\\)
199 SV = PVNV\\($ADDR\\) at $ADDR
201 FLAGS = \\(IOK,NOK,pIOK,pNOK\\)
207 SV = IV\\($ADDR\\) at $ADDR
209 FLAGS = \\(IOK,pIOK\\)
214 'SV = $RV\\($ADDR\\) at $ADDR
218 SV = PVAV\\($ADDR\\) at $ADDR
229 SV = IV\\($ADDR\\) at $ADDR
231 FLAGS = \\(IOK,pIOK\\)
233 Elt No. 1' . $c_pattern);
237 'SV = $RV\\($ADDR\\) at $ADDR
241 SV = PVHV\\($ADDR\\) at $ADDR
243 FLAGS = \\(SHAREKEYS\\)
245 NV = $FLOAT # $] < 5.009
246 ARRAY = $ADDR \\(0:7, 1:1\\)
247 hash quality = 100.0%
253 Elt "123" HASH = $ADDR' . $c_pattern,
255 $] > 5.009 && 'The hash iterator used in dump.c sets the OOK flag');
259 'SV = $RV\\($ADDR\\) at $ADDR
263 SV = PVCV\\($ADDR\\) at $ADDR
265 FLAGS = \\($PADMY,POK,pPOK,ANON,WEAKOUTSIDE\\)
269 COMP_STASH = $ADDR\\t"main"
270 START = $ADDR ===> \\d+
272 XSUB = 0x0 # $] < 5.009
273 XSUBANY = 0 # $] < 5.009
274 GVGV::GV = $ADDR\\t"main" :: "__ANON__[^"]*"
275 FILE = ".*\\b(?i:peek\\.t)"
279 FLAGS = 0x404 # $] < 5.009
280 FLAGS = 0x90 # $] >= 5.009
283 PADNAME = $ADDR\\($ADDR\\) PAD = $ADDR\\($ADDR\\)
284 OUTSIDE = $ADDR \\(MAIN\\)');
288 'SV = $RV\\($ADDR\\) at $ADDR
292 SV = PVCV\\($ADDR\\) at $ADDR
297 COMP_STASH = $ADDR\\t"main"
298 START = $ADDR ===> \\d+
300 XSUB = 0x0 # $] < 5.009
301 XSUBANY = 0 # $] < 5.009
302 GVGV::GV = $ADDR\\t"main" :: "do_test"
303 FILE = ".*\\b(?i:peek\\.t)"
310 PADNAME = $ADDR\\($ADDR\\) PAD = $ADDR\\($ADDR\\)
311 \\d+\\. $ADDR<\\d+> \\(\\d+,\\d+\\) "\\$todo"
312 \\d+\\. $ADDR<\\d+> \\(\\d+,\\d+\\) "\\$repeat_todo"
313 \\d+\\. $ADDR<\\d+> \\(\\d+,\\d+\\) "\\$pattern"
314 \\d+\\. $ADDR<\\d+> FAKE "\\$DEBUG" # $] < 5.009
315 \\d+\\. $ADDR<\\d+> FAKE "\\$DEBUG" flags=0x0 index=0 # $] >= 5.009
316 \\d+\\. $ADDR<\\d+> \\(\\d+,\\d+\\) "\\$dump"
317 \\d+\\. $ADDR<\\d+> \\(\\d+,\\d+\\) "\\$dump2"
318 OUTSIDE = $ADDR \\(MAIN\\)');
323 'SV = $RV\\($ADDR\\) at $ADDR
327 SV = REGEXP\\($ADDR\\) at $ADDR
329 FLAGS = \\(OBJECT,POK,FAKE,pPOK\\)
330 PV = $ADDR "\\(\\?-xism:tic\\)"
333 STASH = $ADDR\\t"Regexp"');
337 'SV = $RV\\($ADDR\\) at $ADDR
341 SV = PVMG\\($ADDR\\) at $ADDR
343 FLAGS = \\(OBJECT,SMG\\)
349 MG_TYPE = PERL_MAGIC_qr\(r\)
351 PAT = "\(\?-xism:tic\)" # $] >= 5.009
352 REFCNT = 2 # $] >= 5.009
353 STASH = $ADDR\\t"Regexp"');
358 'SV = $RV\\($ADDR\\) at $ADDR
362 SV = PVHV\\($ADDR\\) at $ADDR
364 FLAGS = \\(OBJECT,SHAREKEYS\\)
367 STASH = $ADDR\\t"Tac"
374 $] > 5.009 ? 'The hash iterator used in dump.c sets the OOK flag'
375 : "Something causes the HV's array to become allocated");
379 'SV = PVGV\\($ADDR\\) at $ADDR
381 FLAGS = \\(MULTI(?:,IN_PAD)?\\) # $] >= 5.009
382 FLAGS = \\(GMG,SMG,MULTI(?:,IN_PAD)?\\) # $] < 5.009
386 MAGIC = $ADDR # $] < 5.009
387 MG_VIRTUAL = &PL_vtbl_glob # $] < 5.009
388 MG_TYPE = PERL_MAGIC_glob\(\*\) # $] < 5.009
389 MG_OBJ = $ADDR # $] < 5.009
392 GvSTASH = $ADDR\\t"main"
402 GPFLAGS = 0x0 # $] < 5.009
404 FILE = ".*\\b(?i:peek\\.t)"
408 if (ord('A') == 193) {
410 chr(256).chr(0).chr(512),
411 'SV = PV\\($ADDR\\) at $ADDR
413 FLAGS = \\((?:$PADTMP,)?POK,READONLY,pPOK,UTF8\\)
414 PV = $ADDR "\\\214\\\101\\\0\\\235\\\101"\\\0 \[UTF8 "\\\x\{100\}\\\x\{0\}\\\x\{200\}"\]
419 chr(256).chr(0).chr(512),
420 'SV = PV\\($ADDR\\) at $ADDR
422 FLAGS = \\((?:$PADTMP,)?POK,READONLY,pPOK,UTF8\\)
423 PV = $ADDR "\\\304\\\200\\\0\\\310\\\200"\\\0 \[UTF8 "\\\x\{100\}\\\x\{0\}\\\x\{200\}"\]
428 if (ord('A') == 193) {
430 {chr(256)=>chr(512)},
431 'SV = $RV\\($ADDR\\) at $ADDR
435 SV = PVHV\\($ADDR\\) at $ADDR
437 FLAGS = \\(SHAREKEYS,HASKFLAGS\\)
439 NV = $FLOAT # $] < 5.009
440 ARRAY = $ADDR \\(0:7, 1:1\\)
441 hash quality = 100.0%
447 Elt "\\\214\\\101" \[UTF8 "\\\x\{100\}"\] HASH = $ADDR
448 SV = PV\\($ADDR\\) at $ADDR
450 FLAGS = \\(POK,pPOK,UTF8\\)
451 PV = $ADDR "\\\235\\\101"\\\0 \[UTF8 "\\\x\{200\}"\]
454 $] > 5.009 ? 'The hash iterator used in dump.c sets the OOK flag'
455 : 'sv_length has been called on the element, and cached the result in MAGIC');
458 {chr(256)=>chr(512)},
459 'SV = $RV\\($ADDR\\) at $ADDR
463 SV = PVHV\\($ADDR\\) at $ADDR
465 FLAGS = \\(SHAREKEYS,HASKFLAGS\\)
468 ARRAY = $ADDR \\(0:7, 1:1\\)
469 hash quality = 100.0%
475 Elt "\\\304\\\200" \[UTF8 "\\\x\{100\}"\] HASH = $ADDR
476 SV = PV\\($ADDR\\) at $ADDR
478 FLAGS = \\(POK,pPOK,UTF8\\)
479 PV = $ADDR "\\\310\\\200"\\\0 \[UTF8 "\\\x\{200\}"\]
482 $] > 5.009 ? 'The hash iterator used in dump.c sets the OOK flag'
483 : 'sv_length has been called on the element, and cached the result in MAGIC');
490 'SV = PVMG\\($ADDR\\) at $ADDR
492 FLAGS = \\($PADMY,SMG,POK,pPOK\\)
499 MG_VIRTUAL = &PL_vtbl_mglob
500 MG_TYPE = PERL_MAGIC_regex_global\\(g\\)
505 # TAINTEDDIR is not set on: OS2, AMIGAOS, WIN32, MSDOS
506 # environment variables may be invisibly case-forced, hence the (?i:PATH)
507 # C<scalar(@ARGV)> is turned into an IV on VMS hence the (?:IV)?
508 # VMS is setting FAKE and READONLY flags. What VMS uses for storing
509 # ENV hashes is also not always null terminated.
512 $ENV{PATH}=@ARGV, # scalar(@ARGV) is a handy known tainted value
513 'SV = PVMG\\($ADDR\\) at $ADDR
515 FLAGS = \\(GMG,SMG,RMG,pIOK,pPOK\\)
522 MG_VIRTUAL = &PL_vtbl_envelem
523 MG_TYPE = PERL_MAGIC_envelem\\(e\\)
527 MG_PTR = $ADDR (?:"(?i:PATH)"|=> HEf_SVKEY
528 SV = PV(?:IV)?\\($ADDR\\) at $ADDR
530 FLAGS = \\(TEMP,POK,(?:FAKE,READONLY,)?pPOK\\)
532 )? PV = $ADDR "(?i:PATH)"(?:\\\0)?
536 MG_VIRTUAL = &PL_vtbl_taint
537 MG_TYPE = PERL_MAGIC_taint\\(t\\)');
541 bless(\\undef, 'Foobar'),
542 'SV = $RV\\($ADDR\\) at $ADDR
546 SV = PVMG\\($ADDR\\) at $ADDR
548 FLAGS = \\(OBJECT,ROK\\)
552 SV = NULL\\(0x0\\) at $ADDR
554 FLAGS = \\(READONLY\\)
558 STASH = $ADDR\s+"Foobar"');
560 # Constant subroutines
568 'SV = $RV\\($ADDR\\) at $ADDR
572 SV = PVCV\\($ADDR\\) at $ADDR
574 FLAGS = \\(POK,pPOK,CONST\\)
579 ROOT = 0x0 # $] < 5.009
581 XSUBANY = $ADDR \\(CONST SV\\)
582 SV = PV\\($ADDR\\) at $ADDR
584 FLAGS = \\(.*POK,READONLY,pPOK\\)
585 PV = $ADDR "Perl rules"\\\0
588 GVGV::GV = $ADDR\\t"main" :: "const"
589 FILE = ".*\\b(?i:peek\\.t)"
593 FLAGS = 0x200 # $] < 5.009
594 FLAGS = 0xc00 # $] >= 5.009
597 OUTSIDE = 0x0 \\(null\\)');
599 # isUV should show on PVMG
601 do { my $v = $1; $v = ~0; $v },
602 'SV = PVMG\\($ADDR\\) at $ADDR
604 FLAGS = \\(IOK,pIOK,IsUV\\)
611 'SV = $RV\\($ADDR\\) at $ADDR
615 SV = PVIO\\($ADDR\\) at $ADDR
620 STASH = $ADDR\s+"IO::File"
631 SUBPROCESS = 0 # $] < 5.009
637 'SV = $RV\\($ADDR\\) at $ADDR
641 SV = PVFM\\($ADDR\\) at $ADDR
648 START = $ADDR ===> \\d+
650 XSUB = 0x0 # $] < 5.009
651 XSUBANY = 0 # $] < 5.009
652 GVGV::GV = $ADDR\\t"main" :: "PIE"
653 FILE = ".*\\b(?i:peek\\.t)"
661 PADNAME = $ADDR\\($ADDR\\) PAD = $ADDR\\($ADDR\\)
662 OUTSIDE = $ADDR \\(MAIN\\)');