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: $!";
24 my $repeat_todo = $_[4];
26 if (open(OUT,">peek$$")) {
27 open(STDERR, ">&OUT") or die "Can't dup OUT: $!";
29 print STDERR "*****\n";
30 Dump($_[1]); # second dump to compare with the first to make sure nothing changed.
31 open(STDERR, ">&SAVERR") or die "Can't restore STDERR: $!";
33 if (open(IN, "peek$$")) {
35 $pattern =~ s/\$ADDR/0x[[:xdigit:]]+/g;
36 $pattern =~ s/\$FLOAT/(?:\\d*\\.\\d+(?:e[-+]\\d+)?|\\d+)/g;
37 # handle DEBUG_LEAKING_SCALARS prefix
38 $pattern =~ s/^(\s*)(SV =.* at )/(?:$1ALLOCATED at .*?\n)?$1$2/mg;
40 # Need some clear generic mechanism to eliminate (or add) lines
41 # of dump output dependant on perl version. The (previous) use of
42 # things like $IVNV gave the illusion that the string passed in was
43 # a regexp into which variables were interpolated, but this wasn't
44 # actually true as those 'variables' actually also ate the
45 # whitspace on the line. So it seems better to mark lines that
46 # need to be eliminated. I considered (?# ... ) and (?{ ... }),
47 # but whilst embedded code or comment syntax would keep it as a
48 # legitimate regexp, it still isn't true. Seems easier and clearer
49 # things that look like comments.
51 # Could do this is in a s///mge but seems clearer like this:
52 $pattern = join '', map {
53 # If we identify the version condition, take *it* out whatever
54 s/\s*# (\$] [<>]=? 5\.\d\d\d)$//
56 : $_ # Didn't match, so this line is in
57 } split /^/, $pattern;
59 $pattern =~ s/\$PADMY/
60 ($] < 5.009) ? 'PADBUSY,PADMY' : 'PADMY';
62 $pattern =~ s/\$PADTMP/
63 ($] < 5.009) ? 'PADBUSY,PADTMP' : 'PADTMP';
65 $pattern =~ s/^ *\$XSUB *\n/
66 ($] < 5.009) ? " XSUB = 0x0\n XSUBANY = 0\n" : '';
68 $pattern =~ s/^ *\$ROOT *\n/
69 ($] < 5.009) ? " ROOT = 0x0\n" : '';
71 $pattern =~ s/^ *\$IVNV *\n/
72 ($] < 5.009) ? " IV = 0\n NV = 0\n" : '';
75 ($] < 5.011) ? 'RV' : 'IV';
77 $pattern =~ s/^ *\$NV *\n/
78 ($] < 5.011) ? " NV = 0\n" : '';
80 $pattern =~ s/^ *\$SUBPROCESS *\n/
81 ($] < 5.009) ? " SUBPROCESS = 0\n" : '';
85 print $pattern, "\n" if $DEBUG;
86 my ($dump, $dump2) = split m/\*\*\*\*\*\n/, scalar <IN>;
87 print $dump, "\n" if $DEBUG;
88 like( $dump, qr/\A$pattern\Z/ms );
90 local $TODO = $repeat_todo;
97 die "$0: failed to open peek$$: !\n";
100 die "$0: failed to create peek$$: $!\n";
110 1 while unlink("peek$$");
115 'SV = PV\\($ADDR\\) at $ADDR
117 FLAGS = \\(POK,pPOK\\)
125 'SV = PV\\($ADDR\\) at $ADDR
127 FLAGS = \\(.*POK,READONLY,pPOK\\)
134 'SV = IV\\($ADDR\\) at $ADDR
136 FLAGS = \\(IOK,pIOK\\)
141 'SV = IV\\($ADDR\\) at $ADDR
143 FLAGS = \\(.*IOK,READONLY,pIOK\\)
148 'SV = IV\\($ADDR\\) at $ADDR
150 FLAGS = \\($PADMY,IOK,pIOK\\)
153 # If perl is built with PERL_PRESERVE_IVUV then maths is done as integers
154 # where possible and this scalar will be an IV. If NO_PERL_PRESERVE_IVUV then
155 # maths is done in floating point always, and this scalar will be an NV.
156 # ([NI]) captures the type, referred to by \1 in this regexp and $type for
157 # building subsequent regexps.
158 my $type = do_test( 6,
160 'SV = ([NI])V\\($ADDR\\) at $ADDR
162 FLAGS = \\(PADTMP,\1OK,p\1OK\\)
169 'SV = PVNV\\($ADDR\\) at $ADDR
171 FLAGS = \\(NOK,pNOK\\)
173 NV = 789\\.(?:1(?:000+\d+)?|0999+\d+)
180 'SV = IV\\($ADDR\\) at $ADDR
182 FLAGS = \\(.*IOK,READONLY,pIOK\\)
187 'SV = NULL\\(0x0\\) at $ADDR
193 'SV = $RV\\($ADDR\\) at $ADDR
197 SV = PV\\($ADDR\\) at $ADDR
199 FLAGS = \\(POK,pPOK\\)
207 SV = PVNV\\($ADDR\\) at $ADDR
209 FLAGS = \\(IOK,NOK,pIOK,pNOK\\)
215 SV = IV\\($ADDR\\) at $ADDR
217 FLAGS = \\(IOK,pIOK\\)
222 'SV = $RV\\($ADDR\\) at $ADDR
226 SV = PVAV\\($ADDR\\) at $ADDR
237 SV = IV\\($ADDR\\) at $ADDR
239 FLAGS = \\(IOK,pIOK\\)
241 Elt No. 1' . $c_pattern);
245 'SV = $RV\\($ADDR\\) at $ADDR
249 SV = PVHV\\($ADDR\\) at $ADDR
251 FLAGS = \\(SHAREKEYS\\)
253 NV = $FLOAT # $] < 5.009
254 ARRAY = $ADDR \\(0:7, 1:1\\)
255 hash quality = 100.0%
261 Elt "123" HASH = $ADDR' . $c_pattern,
263 $] > 5.009 && 'The hash iterator used in dump.c sets the OOK flag');
267 'SV = $RV\\($ADDR\\) at $ADDR
271 SV = PVCV\\($ADDR\\) at $ADDR
273 FLAGS = \\($PADMY,POK,pPOK,ANON,WEAKOUTSIDE\\)
276 COMP_STASH = $ADDR\\t"main"
277 START = $ADDR ===> \\d+
280 GVGV::GV = $ADDR\\t"main" :: "__ANON__[^"]*"
281 FILE = ".*\\b(?i:peek\\.t)"
285 FLAGS = 0x404 # $] < 5.009
286 FLAGS = 0x90 # $] >= 5.009
289 PADNAME = $ADDR\\($ADDR\\) PAD = $ADDR\\($ADDR\\)
290 OUTSIDE = $ADDR \\(MAIN\\)');
294 'SV = $RV\\($ADDR\\) at $ADDR
298 SV = PVCV\\($ADDR\\) at $ADDR
302 COMP_STASH = $ADDR\\t"main"
303 START = $ADDR ===> \\d+
306 GVGV::GV = $ADDR\\t"main" :: "do_test"
307 FILE = ".*\\b(?i:peek\\.t)"
314 PADNAME = $ADDR\\($ADDR\\) PAD = $ADDR\\($ADDR\\)
315 \\d+\\. $ADDR<\\d+> \\(\\d+,\\d+\\) "\\$todo"
316 \\d+\\. $ADDR<\\d+> \\(\\d+,\\d+\\) "\\$repeat_todo"
317 \\d+\\. $ADDR<\\d+> \\(\\d+,\\d+\\) "\\$pattern"
318 \\d+\\. $ADDR<\\d+> FAKE "\\$DEBUG" # $] < 5.009
319 \\d+\\. $ADDR<\\d+> FAKE "\\$DEBUG" flags=0x0 index=0 # $] >= 5.009
320 \\d+\\. $ADDR<\\d+> \\(\\d+,\\d+\\) "\\$dump"
321 \\d+\\. $ADDR<\\d+> \\(\\d+,\\d+\\) "\\$dump2"
322 OUTSIDE = $ADDR \\(MAIN\\)');
327 'SV = $RV\\($ADDR\\) at $ADDR
331 SV = REGEXP\\($ADDR\\) at $ADDR
333 FLAGS = \\(OBJECT,POK,pPOK\\)
335 PV = $ADDR "\\(\\?-xism:tic\\)"\\\0
338 STASH = $ADDR\\t"Regexp"');
342 'SV = $RV\\($ADDR\\) at $ADDR
346 SV = PVMG\\($ADDR\\) at $ADDR
348 FLAGS = \\(OBJECT,SMG\\)
354 MG_TYPE = PERL_MAGIC_qr\(r\)
356 PAT = "\(\?-xism:tic\)" # $] >= 5.009
357 REFCNT = 2 # $] >= 5.009
358 STASH = $ADDR\\t"Regexp"');
363 'SV = $RV\\($ADDR\\) at $ADDR
367 SV = PVHV\\($ADDR\\) at $ADDR
369 FLAGS = \\(OBJECT,SHAREKEYS\\)
372 STASH = $ADDR\\t"Tac"
379 $] > 5.009 ? 'The hash iterator used in dump.c sets the OOK flag'
380 : "Something causes the HV's array to become allocated");
384 'SV = PVGV\\($ADDR\\) at $ADDR
386 FLAGS = \\(MULTI(?:,IN_PAD)?\\) # $] >= 5.009
387 FLAGS = \\(GMG,SMG,MULTI(?:,IN_PAD)?\\) # $] < 5.009
391 MAGIC = $ADDR # $] < 5.009
392 MG_VIRTUAL = &PL_vtbl_glob # $] < 5.009
393 MG_TYPE = PERL_MAGIC_glob\(\*\) # $] < 5.009
394 MG_OBJ = $ADDR # $] < 5.009
397 GvSTASH = $ADDR\\t"main"
407 GPFLAGS = 0x0 # $] < 5.009
409 FILE = ".*\\b(?i:peek\\.t)"
413 if (ord('A') == 193) {
415 chr(256).chr(0).chr(512),
416 'SV = PV\\($ADDR\\) at $ADDR
418 FLAGS = \\((?:$PADTMP,)?POK,READONLY,pPOK,UTF8\\)
419 PV = $ADDR "\\\214\\\101\\\0\\\235\\\101"\\\0 \[UTF8 "\\\x\{100\}\\\x\{0\}\\\x\{200\}"\]
424 chr(256).chr(0).chr(512),
425 'SV = PV\\($ADDR\\) at $ADDR
427 FLAGS = \\((?:$PADTMP,)?POK,READONLY,pPOK,UTF8\\)
428 PV = $ADDR "\\\304\\\200\\\0\\\310\\\200"\\\0 \[UTF8 "\\\x\{100\}\\\x\{0\}\\\x\{200\}"\]
433 if (ord('A') == 193) {
435 {chr(256)=>chr(512)},
436 'SV = $RV\\($ADDR\\) at $ADDR
440 SV = PVHV\\($ADDR\\) at $ADDR
442 FLAGS = \\(SHAREKEYS,HASKFLAGS\\)
444 NV = $FLOAT # $] < 5.009
445 ARRAY = $ADDR \\(0:7, 1:1\\)
446 hash quality = 100.0%
452 Elt "\\\214\\\101" \[UTF8 "\\\x\{100\}"\] HASH = $ADDR
453 SV = PV\\($ADDR\\) at $ADDR
455 FLAGS = \\(POK,pPOK,UTF8\\)
456 PV = $ADDR "\\\235\\\101"\\\0 \[UTF8 "\\\x\{200\}"\]
459 $] > 5.009 ? 'The hash iterator used in dump.c sets the OOK flag'
460 : 'sv_length has been called on the element, and cached the result in MAGIC');
463 {chr(256)=>chr(512)},
464 'SV = $RV\\($ADDR\\) at $ADDR
468 SV = PVHV\\($ADDR\\) at $ADDR
470 FLAGS = \\(SHAREKEYS,HASKFLAGS\\)
473 ARRAY = $ADDR \\(0:7, 1:1\\)
474 hash quality = 100.0%
480 Elt "\\\304\\\200" \[UTF8 "\\\x\{100\}"\] HASH = $ADDR
481 SV = PV\\($ADDR\\) at $ADDR
483 FLAGS = \\(POK,pPOK,UTF8\\)
484 PV = $ADDR "\\\310\\\200"\\\0 \[UTF8 "\\\x\{200\}"\]
487 $] > 5.009 ? 'The hash iterator used in dump.c sets the OOK flag'
488 : 'sv_length has been called on the element, and cached the result in MAGIC');
495 'SV = PVMG\\($ADDR\\) at $ADDR
497 FLAGS = \\($PADMY,SMG,POK,pPOK\\)
504 MG_VIRTUAL = &PL_vtbl_mglob
505 MG_TYPE = PERL_MAGIC_regex_global\\(g\\)
510 # TAINTEDDIR is not set on: OS2, AMIGAOS, WIN32, MSDOS
511 # environment variables may be invisibly case-forced, hence the (?i:PATH)
512 # C<scalar(@ARGV)> is turned into an IV on VMS hence the (?:IV)?
513 # VMS is setting FAKE and READONLY flags. What VMS uses for storing
514 # ENV hashes is also not always null terminated.
517 $ENV{PATH}=@ARGV, # scalar(@ARGV) is a handy known tainted value
518 'SV = PVMG\\($ADDR\\) at $ADDR
520 FLAGS = \\(GMG,SMG,RMG,pIOK,pPOK\\)
527 MG_VIRTUAL = &PL_vtbl_envelem
528 MG_TYPE = PERL_MAGIC_envelem\\(e\\)
532 MG_PTR = $ADDR (?:"(?i:PATH)"|=> HEf_SVKEY
533 SV = PV(?:IV)?\\($ADDR\\) at $ADDR
535 FLAGS = \\(TEMP,POK,(?:FAKE,READONLY,)?pPOK\\)
537 )? PV = $ADDR "(?i:PATH)"(?:\\\0)?
541 MG_VIRTUAL = &PL_vtbl_taint
542 MG_TYPE = PERL_MAGIC_taint\\(t\\)');
546 bless(\\undef, 'Foobar'),
547 'SV = $RV\\($ADDR\\) at $ADDR
551 SV = PVMG\\($ADDR\\) at $ADDR
553 FLAGS = \\(OBJECT,ROK\\)
557 SV = NULL\\(0x0\\) at $ADDR
559 FLAGS = \\(READONLY\\)
563 STASH = $ADDR\s+"Foobar"');
565 # Constant subroutines
573 'SV = $RV\\($ADDR\\) at $ADDR
577 SV = PVCV\\($ADDR\\) at $ADDR
579 FLAGS = \\(POK,pPOK,CONST\\)
585 XSUBANY = $ADDR \\(CONST SV\\)
586 SV = PV\\($ADDR\\) at $ADDR
588 FLAGS = \\(.*POK,READONLY,pPOK\\)
589 PV = $ADDR "Perl rules"\\\0
592 GVGV::GV = $ADDR\\t"main" :: "const"
593 FILE = ".*\\b(?i:peek\\.t)"
597 FLAGS = 0x200 # $] < 5.009
598 FLAGS = 0xc00 # $] >= 5.009
601 OUTSIDE = 0x0 \\(null\\)');
603 # isUV should show on PVMG
605 do { my $v = $1; $v = ~0; $v },
606 'SV = PVMG\\($ADDR\\) at $ADDR
608 FLAGS = \\(IOK,pIOK,IsUV\\)
615 'SV = $RV\\($ADDR\\) at $ADDR
619 SV = PVIO\\($ADDR\\) at $ADDR
624 STASH = $ADDR\s+"IO::Handle"