14 if (! -c "/dev/null") {
15 print "1..0 # Skip: no /dev/null\n";
19 my $dev_tty = '/dev/tty';
20 $dev_tty = 'TT:' if ($^O eq 'VMS');
22 print "1..0 # Skip: no $dev_tty\n";
26 print "1..0 # Skip: \$ENV{PERL5DB} is already set to '$ENV{PERL5DB}'\n";
29 $ENV{PERL_RL} = 'Perl'; # Suppress system Term::ReadLine::Gnu
34 my $rc_filename = '.perldb';
37 open my $rc_fh, '>', $rc_filename
42 # overly permissive perms gives "Must not source insecure rcfile"
43 # and hangs at the DB(1> prompt
44 chmod 0644, $rc_filename;
51 open my $in, '<', $filename
52 or die "Cannot open '$filename' for slurping - $!";
62 my $out_fn = 'db.out';
66 return _slurp($out_fn);
70 # Test for Proxy constants
75 &parse_options("NonStop=0 ReadLine=0 TTY=db.out");
87 my $output = runperl(switches => [ '-d' ], stderr => 1, progfile => '../lib/perl5db/t/proxy-constants');
88 is($output, "", "proxy constant subroutines");
91 # [perl #66110] Call a subroutine inside a regex
93 local $ENV{PERLDB_OPTS} = "ReadLine=0 NonStop=1";
94 my $output = runperl(switches => [ '-d' ], stderr => 1, progfile => '../lib/perl5db/t/rt-66110');
95 like($output, qr/\bAll tests successful\.$/, "[perl #66110]");
97 # [ perl #116769] Frame=2
99 local $ENV{PERLDB_OPTS} = "frame=2 nonstop";
100 my $output = runperl( switches => [ '-d' ], prog => 'print q{success}' );
101 is( $?, 0, '[perl #116769] frame=2 does not crash debugger, exit == 0' );
102 is( $output, 'success' , '[perl #116769] code is run' );
104 # [ perl #116771] autotrace
106 local $ENV{PERLDB_OPTS} = "autotrace nonstop";
107 my $output = runperl( switches => [ '-d' ], prog => 'print q{success}' );
108 is( $?, 0, '[perl #116771] autotrace does not crash debugger, exit == 0' );
109 is( $output, 'success' , '[perl #116771] code is run' );
111 # [ perl #41461] Frame=2 noTTY
113 local $ENV{PERLDB_OPTS} = "frame=2 noTTY nonstop";
115 my $output = runperl( switches => [ '-d' ], prog => 'print q{success}' );
116 is( $?, 0, '[perl #41461] frame=2 noTTY does not crash debugger, exit == 0' );
117 is( $output, 'success' , '[perl #41461] code is run' );
125 my $self = bless {}, $class;
136 $self->{_cmds} = shift;
139 return $self->{_cmds};
146 $self->{_prog} = shift;
149 return $self->{_prog};
156 $self->{_output} = shift;
159 return $self->{_output};
168 $self->{_include_t} = shift;
171 return $self->{_include_t};
180 $self->{_stderr_val} = shift;
183 return $self->{_stderr_val};
192 $self->{field} = shift;
195 return $self->{field};
204 $self->{_switches} = shift;
207 return $self->{_switches};
216 $self->{_contents} = shift;
219 return $self->{_contents};
224 my ($self, $args) = @_;
226 my $cmds = $args->{cmds};
228 if (ref($cmds) ne 'ARRAY') {
229 die "cmds must be an array of commands.";
234 my $prog = $args->{prog};
236 if (ref($prog) ne '' or !defined($prog)) {
237 die "prog should be a path to a program file.";
242 $self->_include_t($args->{include_t} ? 1 : 0);
244 $self->_stderr_val(exists($args->{stderr}) ? $args->{stderr} : 1);
246 if (exists($args->{switches}))
248 $self->_switches($args->{switches});
258 my ($self, $str) = @_;
260 $str =~ s/(["\@\$\\])/\\$1/g;
270 my $rc = qq{&parse_options("NonStop=0 TTY=db.out");\n};
275 q#push (@DB::typeahead,#,
276 (map { $self->_quote($_) . "," } @{$self->_cmds()}),
282 # I guess two objects like that cannot be used at the same time.
290 ($self->_switches ? (@{$self->_switches()}) : ('-d')),
291 ($self->_include_t ? ('-I', '../lib/perl5db/t') : ())
293 (defined($self->_stderr_val())
294 ? (stderr => $self->_stderr_val())
297 progfile => $self->_prog()
300 $self->_output($output);
302 $self->_contents(::_out_contents());
309 return shift->_output();
313 my ($self, $re, $msg) = @_;
315 local $::Level = $::Level + 1;
316 ::like($self->_output(), $re, $msg);
320 my ($self, $re, $msg) = @_;
322 local $::Level = $::Level + 1;
323 ::unlike($self->_output(), $re, $msg);
327 my ($self, $re, $msg) = @_;
329 local $::Level = $::Level + 1;
330 ::like($self->_contents(), $re, $msg);
333 sub contents_unlike {
334 my ($self, $re, $msg) = @_;
336 local $::Level = $::Level + 1;
337 ::unlike($self->_contents(), $re, $msg);
343 local $ENV{PERLDB_OPTS} = "ReadLine=0";
344 my $target = '../lib/perl5db/t/eval-line-bug';
345 my $wrapper = DebugWrap->new(
355 "p \@{'main::_<$target'}",
361 $wrapper->contents_like(
363 'The ${main::_<filename} variable in the debugger was not destroyed',
367 sub _calc_generic_wrapper
371 my $extra_opts = delete($args->{extra_opts});
373 local $ENV{PERLDB_OPTS} = "ReadLine=0" . $extra_opts;
374 return DebugWrap->new(
376 cmds => delete($args->{cmds}),
377 prog => delete($args->{prog}),
383 sub _calc_new_var_wrapper
386 return _calc_generic_wrapper(
393 'x "new_var = <$new_var>\\n"',
401 sub _calc_threads_wrapper
405 return _calc_new_var_wrapper(
407 switches => [ '-dt', ],
415 _calc_new_var_wrapper({ prog => '../lib/perl5db/t/eval-line-bug'})
418 "no strict 'vars' in evaluated lines.",
423 _calc_new_var_wrapper(
425 prog => '../lib/perl5db/t/lvalue-bug',
430 'lvalue subs work in the debugger',
435 _calc_new_var_wrapper(
437 prog => '../lib/perl5db/t/symbol-table-bug',
438 extra_opts => "NonStop=1",
442 qr/Undefined symbols 0/,
443 'there are no undefined values in the symbol table',
449 if ( $Config{usethreads} ) {
450 skip('This perl has threads, skipping non-threaded debugger tests');
453 my $error = 'This Perl not built to support threads';
454 _calc_threads_wrapper(
456 prog => '../lib/perl5db/t/eval-line-bug',
460 'Perl debugger correctly complains that it was not built with threads',
467 if ( $Config{usethreads} ) {
468 _calc_threads_wrapper(
470 prog => '../lib/perl5db/t/symbol-table-bug',
473 qr/Undefined symbols 0/,
474 'there are no undefined values in the symbol table when running with thread support',
478 skip("This perl is not threaded, skipping threaded debugger tests");
484 local $ENV{PERLDB_OPTS};
485 my $wrapper = DebugWrap->new(
492 prog => '../lib/perl5db/t/rt-61222',
496 $wrapper->contents_unlike(qr/INCORRECT/, "[perl #61222]");
499 sub _calc_trace_wrapper
503 return _calc_generic_wrapper(
516 # [perl 104168] level option for tracing
518 my $wrapper = _calc_trace_wrapper({ prog => '../lib/perl5db/t/rt-104168' });
519 $wrapper->contents_like(qr/level 2/, "[perl #104168] - level 2 appears");
520 $wrapper->contents_unlike(qr/baz/, "[perl #104168] - no 'baz'");
525 my $wrapper = _calc_trace_wrapper(
527 prog => '../lib/perl5db/t/taint',
528 extra_opts => ' NonStop=1',
529 switches => [ '-d', '-T', ],
533 my $output = $wrapper->get_output();
534 chomp $output if $^O eq 'VMS'; # newline guaranteed at EOF
535 is($output, '[$^X][done]', "taint");
538 # Testing that we can set a line in the middle of the file.
540 my $wrapper = DebugWrap->new(
544 'b ../lib/perl5db/t/MyModule.pm:12',
546 q/do { use IO::Handle; STDOUT->autoflush(1); print "Var=$var\n"; }/,
551 prog => '../lib/perl5db/t/filename-line-breakpoint'
555 $wrapper->output_like(qr/
563 "Can set breakpoint in a line in the middle of the file.");
566 # Testing that we can set a breakpoint
568 my $wrapper = DebugWrap->new(
570 prog => '../lib/perl5db/t/breakpoint-bug',
575 q/do { use IO::Handle; STDOUT->autoflush(1); print "X={$x}\n"; }/,
582 $wrapper->output_like(
584 "Can set breakpoint in a line."
588 # Testing that we can disable a breakpoint at a numeric line.
590 my $wrapper = DebugWrap->new(
592 prog => '../lib/perl5db/t/disable-breakpoints-1',
599 q/print "X={$x}\n";/,
606 $wrapper->output_like(qr/X=\{SecondVal\}/ms,
607 "Can set breakpoint in a line.");
610 # Testing that we can re-enable a breakpoint at a numeric line.
612 my $wrapper = DebugWrap->new(
614 prog => '../lib/perl5db/t/disable-breakpoints-2',
623 q/print "X={$x}\n";/,
630 $wrapper->output_like(
632 X=\{SecondValOneHundred\}
634 "Can set breakpoint in a line."
639 # Disable and enable for breakpoints on outer files.
641 my $wrapper = DebugWrap->new(
646 'b ../lib/perl5db/t/EnableModule.pm:14',
647 'disable ../lib/perl5db/t/EnableModule.pm:14',
649 'enable ../lib/perl5db/t/EnableModule.pm:14',
651 q/print "X={$x}\n";/,
655 prog => '../lib/perl5db/t/disable-breakpoints-3',
660 $wrapper->output_like(qr/
661 X=\{SecondValTwoHundred\}
663 "Can set breakpoint in a line.");
666 # Testing that the prompt with the information appears.
668 my $wrapper = DebugWrap->new(
671 prog => '../lib/perl5db/t/disable-breakpoints-1',
675 $wrapper->contents_like(qr/
676 ^main::\([^\)]*\bdisable-breakpoints-1:2\):\n
677 2:\s+my\ \$x\ =\ "One";\n
679 "Prompt should display the first line of code.");
682 # Testing that R (restart) and "B *" work.
684 my $wrapper = DebugWrap->new(
694 q/print "X={$x};dummy={$dummy}\n";/,
697 prog => '../lib/perl5db/t/disable-breakpoints-1',
701 $wrapper->output_like(qr/
702 X=\{FirstVal\};dummy=\{1\}
704 "Restart and delete all breakpoints work properly.");
708 my $wrapper = DebugWrap->new(
713 q/print "X={$x}\n";/,
717 prog => '../lib/perl5db/t/disable-breakpoints-1',
721 $wrapper->output_like(qr/
724 "'c line_num' is working properly.");
728 my $wrapper = DebugWrap->new(
736 q/print "Exp={$exp}\n";/,
739 prog => '../lib/perl5db/t/break-on-dot',
743 $wrapper->output_like(qr/
746 "'b .' is working correctly.");
749 # Testing that the prompt with the information appears inside a subroutine call.
750 # See https://rt.perl.org/rt3/Ticket/Display.html?id=104820
752 my $wrapper = DebugWrap->new(
759 prog => '../lib/perl5db/t/with-subroutine',
763 $wrapper->contents_like(
765 ^main::back\([^\)\n]*\bwith-subroutine:15\):[\ \t]*\n
766 ^15:\s*print\ "hello\ back\\n";
768 "Prompt should display the line of code inside a subroutine.");
771 # Checking that the p command works.
773 my $wrapper = DebugWrap->new(
777 'p "<<<" . (4*6) . ">>>"',
780 prog => '../lib/perl5db/t/with-subroutine',
784 $wrapper->contents_like(
791 my $wrapper = DebugWrap->new(
798 prog => '../lib/perl5db/t/with-subroutine',
802 $wrapper->contents_like(
803 # qr/^0\s+HASH\([^\)]+\)\n\s+500 => 600\n/,
804 qr/^0\s+HASH\([^\)]+\)\n\s+500 => 600\n/ms,
809 # Tests for x with @_
811 my $wrapper = DebugWrap->new(
820 prog => '../lib/perl5db/t/test-passing-at-underscore-to-x-etc',
824 $wrapper->contents_like(
825 # qr/^0\s+HASH\([^\)]+\)\n\s+500 => 600\n/,
826 qr/Arg1.*?Capsula.*GreekHumor.*Socrates/ms,
827 q/x command test with '@_'./,
831 # Tests for mutating @_
833 my $wrapper = DebugWrap->new(
840 'print "\n\n\n(((" . join(",", @_) . ")))\n\n\n"',
843 prog => '../lib/perl5db/t/test-passing-at-underscore-to-x-etc',
847 $wrapper->output_like(
848 qr/^\(\(\(Capsula,GreekHumor,Socrates\)\)\)$/ms,
853 # Tests for x with AutoTrace=1.
855 my $wrapper = DebugWrap->new(
866 prog => '../lib/perl5db/t/with-subroutine',
870 $wrapper->contents_like(
871 # qr/^0\s+HASH\([^\)]+\)\n\s+500 => 600\n/,
872 qr/^0\s+SCALAR\([^\)]+\)\n\s+-> 'hello world'\n/ms,
873 "x after AutoTrace=1 command is working."
877 # Tests for "T" (stack trace).
879 my $prog_fn = '../lib/perl5db/t/rt-104168';
880 my $wrapper = DebugWrap->new(
891 my $re_text = join('',
894 "%s = %s\\(\\) called from file " .
895 "'" . quotemeta($prog_fn) . "' line %s\\n",
896 (map { quotemeta($_) } @$_)
900 ['.', 'main::baz', 14,],
901 ['.', 'main::bar', 9,],
902 ['.', 'main::foo', 6],
905 $wrapper->contents_like(
906 # qr/^0\s+HASH\([^\)]+\)\n\s+500 => 600\n/,
914 my $wrapper = DebugWrap->new(
921 q/print "X={$x};dummy={$dummy}\n";/,
924 prog => '../lib/perl5db/t/disable-breakpoints-1'
928 $wrapper->output_like(qr/
929 X=\{SecondVal\};dummy=\{1\}
931 'test for s - single step',
936 my $wrapper = DebugWrap->new(
944 q/print "Exp={$exp}\n";/,
947 prog => '../lib/perl5db/t/break-on-dot'
951 $wrapper->output_like(qr/
954 "'b .' is working correctly.");
958 my $prog_fn = '../lib/perl5db/t/rt-104168';
959 my $wrapper = DebugWrap->new(
970 $wrapper->contents_like(
972 ^main::foo\([^\)\n]*\brt-104168:9\):[\ \t]*\n
975 'Test for the s command.',
980 my $wrapper = DebugWrap->new(
984 's uncalled_subroutine()',
989 prog => '../lib/perl5db/t/uncalled-subroutine'}
992 $wrapper->output_like(
994 'uncalled_subroutine was called after s EXPR()',
999 my $wrapper = DebugWrap->new(
1003 'n uncalled_subroutine()',
1007 prog => '../lib/perl5db/t/uncalled-subroutine',
1011 $wrapper->output_like(
1013 'uncalled_subroutine was called after n EXPR()',
1018 my $wrapper = DebugWrap->new(
1030 prog => '../lib/perl5db/t/fact',
1034 $wrapper->output_like(
1036 'b subroutine works fine',
1040 # Test for n with lvalue subs
1044 'n', 'print "<$x>\n"',
1045 'n', 'print "<$x>\n"',
1048 prog => '../lib/perl5db/t/lsub-n',
1051 'n steps over lvalue subs',
1054 # Test for 'M' (module list).
1056 my $wrapper = DebugWrap->new(
1063 prog => '../lib/perl5db/t/load-modules'
1067 $wrapper->contents_like(
1068 qr[Scalar/Util\.pm],
1069 'M (module list) works fine',
1074 my $wrapper = DebugWrap->new(
1082 'print "Var=$var\n";',
1085 prog => '../lib/perl5db/t/test-r-statement',
1089 $wrapper->output_like(
1097 'r statement is working properly.',
1102 my $wrapper = DebugWrap->new(
1109 prog => '../lib/perl5db/t/test-l-statement-1',
1113 $wrapper->contents_like(
1115 ^1==>\s+\$x\ =\ 1;\n
1116 2:\s+print\ "1\\n";\n
1119 5:\s+print\ "2\\n";\n
1121 'l statement is working properly (test No. 1).',
1126 my $wrapper = DebugWrap->new(
1138 prog => '../lib/perl5db/t/test-l-statement-1',
1142 my $first_l_out = qr/
1144 2:\s+print\ "1\\n";\n
1147 5:\s+print\ "2\\n";\n
1150 8:\s+print\ "3\\n";\n
1155 my $second_l_out = qr/
1156 11:\s+print\ "4\\n";\n
1159 14:\s+print\ "5\\n";\n
1162 17:\s+print\ "6\\n";\n
1165 20:\s+print\ "7\\n";\n
1167 $wrapper->contents_like(
1170 [^\n]*?DB<\d+>\ \#\ After\ l\ 1\n
1172 [^\n]*?DB<\d+>\ l\s*\n
1174 [^\n]*?DB<\d+>\ \#\ After\ l\ 2\n
1176 [^\n]*?DB<\d+>\ -\s*\n
1178 [^\n]*?DB<\d+>\ \#\ After\ -\n
1180 'l followed by l and then followed by -',
1185 my $wrapper = DebugWrap->new(
1192 prog => '../lib/perl5db/t/test-l-statement-2',
1196 my $first_l_out = qr/
1198 7:\s+my\ \$n\ =\ shift;\n
1199 8:\s+if\ \(\$n\ >\ 1\)\ \{\n
1200 9:\s+return\ \$n\ \*\ fact\(\$n\ -\ 1\);
1203 $wrapper->contents_like(
1208 'l subroutine_name',
1213 my $wrapper = DebugWrap->new(
1219 # Repeat several times to avoid @typeahead problems.
1226 prog => '../lib/perl5db/t/test-l-statement-2',
1231 ^main::fact\([^\n]*?:7\):\n
1232 ^7:\s+my\ \$n\ =\ shift;\n
1235 $wrapper->contents_like(
1238 auto\(-\d+\)\s+DB<\d+>\s+\.\n
1241 'Test the "." command',
1245 # Testing that the f command works.
1247 my $wrapper = DebugWrap->new(
1251 'f ../lib/perl5db/t/MyModule.pm',
1254 q/do { use IO::Handle; STDOUT->autoflush(1); print "Var=$var\n"; }/,
1259 prog => '../lib/perl5db/t/filename-line-breakpoint'
1263 $wrapper->output_like(qr/
1271 "f command is working.",
1275 # We broke the /pattern/ command because apparently the CORE::eval-s inside
1276 # lib/perl5db.pl cannot handle lexical variable properly. So we now fix this
1281 # 1. Go over the rest of the "eval"s in lib/perl5db.t and see if they cause
1284 my $wrapper = DebugWrap->new(
1291 prog => '../lib/perl5db/t/eval-line-bug',
1295 $wrapper->contents_like(
1296 qr/12: \s* for\ my\ \$q\ \(1\ \.\.\ 10\)\ \{/msx,
1297 "/pat/ command is working and found a match.",
1302 my $wrapper = DebugWrap->new(
1311 prog => '../lib/perl5db/t/eval-line-bug',
1315 $wrapper->contents_like(
1316 qr/12: \s* for\ my\ \$q\ \(1\ \.\.\ 10\)\ \{/msx,
1317 "?pat? command is working and found a match.",
1321 # Test the L command.
1323 my $wrapper = DebugWrap->new(
1332 prog => '../lib/perl5db/t/eval-line-bug',
1336 $wrapper->contents_like(
1338 ^\S*?eval-line-bug:\n
1339 \s*6:\s*my\ \$i\ =\ 5;\n
1340 \s*break\ if\ \(1\)\n
1341 \s*13:\s*\$i\ \+=\ \$q;\n
1342 \s*break\ if\ \(\(\$q\ ==\ 5\)\)\n
1344 "L command is listing breakpoints",
1348 # Test the L command for watch expressions.
1350 my $wrapper = DebugWrap->new(
1358 prog => '../lib/perl5db/t/eval-line-bug',
1362 $wrapper->contents_like(
1364 ^Watch-expressions:\n
1367 "L command is listing watch expressions",
1372 my $wrapper = DebugWrap->new(
1382 prog => '../lib/perl5db/t/eval-line-bug',
1386 $wrapper->contents_like(
1388 ^Watch-expressions:\n
1392 "L command is not listing deleted watch expressions",
1396 # Test the L command.
1398 my $wrapper = DebugWrap->new(
1407 prog => '../lib/perl5db/t/eval-line-bug',
1411 $wrapper->contents_like(
1413 ^\S*?eval-line-bug:\n
1414 \s*6:\s*my\ \$i\ =\ 5;\n
1415 \s*break\ if\ \(1\)\n
1416 \s*13:\s*\$i\ \+=\ \$q;\n
1417 \s*action:\s+print\ \$i\n
1419 "L command is listing actions and breakpoints",
1424 my $wrapper = DebugWrap->new(
1431 prog => '../lib/perl5db/t/rt-104168',
1435 $wrapper->contents_like(
1446 my $wrapper = DebugWrap->new(
1453 prog => '../lib/perl5db/t/rt-104168',
1457 $wrapper->contents_like(
1463 "S command with regex",
1468 my $wrapper = DebugWrap->new(
1475 prog => '../lib/perl5db/t/rt-104168',
1479 $wrapper->contents_unlike(
1483 "S command with negative regex",
1486 $wrapper->contents_like(
1490 "S command with negative regex - what it still matches",
1494 # Test the 'a' command.
1496 my $wrapper = DebugWrap->new(
1500 'a 13 print "\nVar<Q>=$q\n"',
1504 prog => '../lib/perl5db/t/eval-line-bug',
1508 my $nl = $^O eq 'VMS' ? "" : "\\\n";
1509 $wrapper->output_like(qr#
1514 "a command is working",
1518 # Test the 'a' command with no line number.
1520 my $wrapper = DebugWrap->new(
1525 q/a print "Hello " . (3 * 4) . "\n";/,
1529 prog => '../lib/perl5db/t/test-a-statement-1',
1533 $wrapper->output_like(qr#
1534 (?:^Hello\ 12\n.*?){4}
1536 "a command with no line number is working",
1540 # Test the 'A' command
1542 my $wrapper = DebugWrap->new(
1546 'a 13 print "\nVar<Q>=$q\n"',
1551 prog => '../lib/perl5db/t/eval-line-bug',
1555 $wrapper->output_like(
1556 qr#\A\z#msx, # The empty string.
1557 "A command (for removing actions) is working",
1561 # Test the 'A *' command
1563 my $wrapper = DebugWrap->new(
1567 'a 6 print "\nFail!\n"',
1568 'a 13 print "\nVar<Q>=$q\n"',
1573 prog => '../lib/perl5db/t/eval-line-bug',
1577 $wrapper->output_like(
1578 qr#\A\z#msx, # The empty string.
1579 "'A *' command (for removing all actions) is working",
1584 my $wrapper = DebugWrap->new(
1591 'print "\nIDX=<$idx>\n"',
1594 prog => '../lib/perl5db/t/test-w-statement-1',
1599 $wrapper->contents_like(qr#
1601 \s+old\ value:\s+'1'\n
1602 \s+new\ value:\s+'2'\n
1604 'w command - watchpoint changed',
1606 $wrapper->output_like(qr#
1609 "w command - correct output from IDX",
1614 my $wrapper = DebugWrap->new(
1622 'print "\nIDX=<$idx>\n"',
1625 prog => '../lib/perl5db/t/test-w-statement-1',
1629 $wrapper->contents_unlike(qr#
1632 'W command - watchpoint was deleted',
1635 $wrapper->output_like(qr#
1638 "W command - stopped at end.",
1642 # Test the W * command.
1644 my $wrapper = DebugWrap->new(
1653 'print "\nIDX=<$idx>\n"',
1656 prog => '../lib/perl5db/t/test-w-statement-1',
1660 $wrapper->contents_unlike(qr#
1663 '"W *" command - watchpoint was deleted',
1666 $wrapper->output_like(qr#
1669 '"W *" command - stopped at end.',
1673 # Test the 'o' command (without further arguments).
1675 my $wrapper = DebugWrap->new(
1682 prog => '../lib/perl5db/t/test-w-statement-1',
1686 $wrapper->contents_like(qr#
1687 ^\s*warnLevel\ =\ '1'\n
1689 q#"o" command (without arguments) displays warnLevel#,
1692 $wrapper->contents_like(qr#
1693 ^\s*signalLevel\ =\ '1'\n
1695 q#"o" command (without arguments) displays signalLevel#,
1698 $wrapper->contents_like(qr#
1699 ^\s*dieLevel\ =\ '1'\n
1701 q#"o" command (without arguments) displays dieLevel#,
1704 $wrapper->contents_like(qr#
1705 ^\s*hashDepth\ =\ 'N/A'\n
1707 q#"o" command (without arguments) displays hashDepth#,
1711 # Test the 'o' query command.
1713 my $wrapper = DebugWrap->new(
1717 'o hashDepth? signalLevel?',
1720 prog => '../lib/perl5db/t/test-w-statement-1',
1724 $wrapper->contents_unlike(qr#warnLevel#,
1725 q#"o" query command does not display warnLevel#,
1728 $wrapper->contents_like(qr#
1729 ^\s*signalLevel\ =\ '1'\n
1731 q#"o" query command displays signalLevel#,
1734 $wrapper->contents_unlike(qr#dieLevel#,
1735 q#"o" query command does not display dieLevel#,
1738 $wrapper->contents_like(qr#
1739 ^\s*hashDepth\ =\ 'N/A'\n
1741 q#"o" query command displays hashDepth#,
1745 # Test the 'o' set command.
1747 my $wrapper = DebugWrap->new(
1755 prog => '../lib/perl5db/t/test-w-statement-1',
1759 $wrapper->contents_like(qr/
1760 ^\s*(signalLevel\ =\ '0'\n)
1764 q#o set command works#,
1767 $wrapper->contents_like(qr#
1768 ^\s*hashDepth\ =\ 'N/A'\n
1770 q#o set command - hashDepth#,
1774 # Test the '<' and "< ?" commands.
1776 my $wrapper = DebugWrap->new(
1780 q/< print "\nX=<$x>\n"/,
1786 prog => '../lib/perl5db/t/disable-breakpoints-1',
1790 $wrapper->contents_like(qr/
1791 ^pre-perl\ commands:\n
1792 \s*<\ --\ print\ "\\nX=<\$x>\\n"\n
1794 q#Test < and < ? commands - contents.#,
1797 $wrapper->output_like(qr#
1800 q#Test < and < ? commands - output.#,
1804 # Test the '< *' command.
1806 my $wrapper = DebugWrap->new(
1810 q/< print "\nX=<$x>\n"/,
1816 prog => '../lib/perl5db/t/disable-breakpoints-1',
1820 $wrapper->output_unlike(qr/FirstVal/,
1821 q#Test the '< *' command.#,
1825 # Test the '>' and "> ?" commands.
1827 my $wrapper = DebugWrap->new(
1832 q/> print "\nFOO=<$::foo>\n"/,
1838 prog => '../lib/perl5db/t/disable-breakpoints-1',
1842 $wrapper->contents_like(qr/
1843 ^post-perl\ commands:\n
1844 \s*>\ --\ print\ "\\nFOO=<\$::foo>\\n"\n
1846 q#Test > and > ? commands - contents.#,
1849 $wrapper->output_like(qr#
1852 q#Test > and > ? commands - output.#,
1856 # Test the '> *' command.
1858 my $wrapper = DebugWrap->new(
1862 q/> print "\nFOO=<$::foo>\n"/,
1868 prog => '../lib/perl5db/t/disable-breakpoints-1',
1872 $wrapper->output_unlike(qr/FOO=/,
1873 q#Test the '> *' command.#,
1877 # Test the < and > commands together
1879 my $wrapper = DebugWrap->new(
1884 q/< $::lorem += 10;/,
1885 q/> print "\nLOREM=<$::lorem>\n"/,
1892 prog => '../lib/perl5db/t/disable-breakpoints-1',
1896 $wrapper->output_like(qr#
1899 q#Test < and > commands. #,
1903 # Test the { ? and { [command] commands.
1905 my $wrapper = DebugWrap->new(
1916 prog => '../lib/perl5db/t/disable-breakpoints-1',
1920 $wrapper->contents_like(qr#
1921 ^No\ pre-debugger\ actions\.\n
1923 ^pre-debugger\ commands:\n
1926 ^5==>b\s+\$x\ =\ "FirstVal";\n
1930 9:\s+\$x\ =\ "SecondVal";\n
1933 'Test the pre-prompt debugger commands',
1937 # Test the { * command.
1939 my $wrapper = DebugWrap->new(
1947 q/print (("One" x 5), "\n");/,
1950 prog => '../lib/perl5db/t/disable-breakpoints-1',
1954 $wrapper->contents_like(qr#
1955 ^All\ \{\ actions\ cleared\.\n
1957 'Test the { * command',
1960 $wrapper->output_like(qr/OneOneOneOneOne/,
1961 '{ * test - output is OK.',
1965 # Test the ! command.
1967 my $wrapper = DebugWrap->new(
1975 prog => '../lib/perl5db/t/disable-breakpoints-1',
1979 $wrapper->contents_like(qr#
1980 (^3:\s+my\ \$dummy\ =\ 0;\n
1982 5:\s+\$x\ =\ "FirstVal";)\n
1987 'Test the ! command (along with l 3-5)',
1991 # Test the ! -number command.
1993 my $wrapper = DebugWrap->new(
2002 prog => '../lib/perl5db/t/disable-breakpoints-1',
2006 $wrapper->contents_like(qr#
2007 (^3:\s+my\ \$dummy\ =\ 0;\n
2009 5:\s+\$x\ =\ "FirstVal";)\n
2011 ^2==\>\s+my\ \$x\ =\ "One";\n
2016 'Test the ! -n command (along with l)',
2020 # Test the 'source' command.
2022 my $wrapper = DebugWrap->new(
2026 'source ../lib/perl5db/t/source-cmd-test.perldb',
2027 # If we have a 'q' here, then the typeahead will override the
2028 # input, and so it won't be reached - solution:
2029 # put a q inside the .perldb commands.
2030 # ( This may be a bug or a misfeature. )
2032 prog => '../lib/perl5db/t/disable-breakpoints-1',
2036 $wrapper->contents_like(qr#
2037 ^3:\s+my\ \$dummy\ =\ 0;\n
2039 5:\s+\$x\ =\ "FirstVal";\n
2043 9:\s+\$x\ =\ "SecondVal";\n
2046 'Test the source command (along with l)',
2050 # Test the 'source' command being traversed from withing typeahead.
2052 my $wrapper = DebugWrap->new(
2056 'source ../lib/perl5db/t/source-cmd-test-no-q.perldb',
2059 prog => '../lib/perl5db/t/disable-breakpoints-1',
2063 $wrapper->contents_like(qr#
2064 ^3:\s+my\ \$dummy\ =\ 0;\n
2066 5:\s+\$x\ =\ "FirstVal";\n
2070 9:\s+\$x\ =\ "SecondVal";\n
2073 'Test the source command inside a typeahead',
2077 # Test the 'H -number' command.
2079 my $wrapper = DebugWrap->new(
2092 prog => '../lib/perl5db/t/disable-breakpoints-1',
2096 $wrapper->contents_like(qr#
2098 \d+:\s+x\ \(20\+4\)\n
2101 \d+:\s+x\ "Hello\ World"\n
2105 'Test the H -num command',
2109 # Add a test for H (without arguments)
2111 my $wrapper = DebugWrap->new(
2124 prog => '../lib/perl5db/t/disable-breakpoints-1',
2128 $wrapper->contents_like(qr#
2129 ^\d+:\s+x\ \(20\+4\)\n
2132 \d+:\s+x\ "Hello\ World"\n
2136 'Test the H command (without a number.)',
2141 my $wrapper = DebugWrap->new(
2150 prog => '../lib/perl5db/t/test-l-statement-1',
2154 $wrapper->contents_like(
2156 ^1==>\s+\$x\ =\ 1;\n
2157 2:\s+print\ "1\\n";\n
2160 5:\s+print\ "2\\n";\n
2162 'Test the = (command alias) command.',
2166 # Test the m statement.
2168 my $wrapper = DebugWrap->new(
2175 prog => '../lib/perl5db/t/disable-breakpoints-1',
2179 $wrapper->contents_like(qr#
2180 ^via\ UNIVERSAL:\ DOES$
2182 "Test m for main - 1",
2185 $wrapper->contents_like(qr#
2186 ^via\ UNIVERSAL:\ can$
2188 "Test m for main - 2",
2192 # Test the m statement.
2194 my $wrapper = DebugWrap->new(
2203 prog => '../lib/perl5db/t/test-m-statement-1',
2207 $wrapper->contents_like(qr#^greet$#ms,
2208 "Test m for obj - 1",
2211 $wrapper->contents_like(qr#^via UNIVERSAL: can$#ms,
2212 "Test m for obj - 1",
2216 # Test the M command.
2218 my $wrapper = DebugWrap->new(
2225 prog => '../lib/perl5db/t/test-m-statement-1',
2229 $wrapper->contents_like(qr#
2230 ^'strict\.pm'\ =>\ '\d+\.\d+\ from
2237 # Test the recallCommand option.
2239 my $wrapper = DebugWrap->new(
2243 'o recallCommand=%',
2249 prog => '../lib/perl5db/t/disable-breakpoints-1',
2253 $wrapper->contents_like(qr#
2254 (^3:\s+my\ \$dummy\ =\ 0;\n
2256 5:\s+\$x\ =\ "FirstVal";)\n
2258 ^2==\>\s+my\ \$x\ =\ "One";\n
2263 'Test the o recallCommand option',
2267 # Test the dieLevel option
2269 my $wrapper = DebugWrap->new(
2277 prog => '../lib/perl5db/t/test-dieLevel-option-1',
2281 $wrapper->output_like(qr#
2282 ^This\ program\ dies\.\ at\ \S+\ line\ 18\N*\.\n
2284 ^\s+main::baz\(\)\ called\ at\ \S+\ line\ 13\n
2285 \s+main::bar\(\)\ called\ at\ \S+\ line\ 7\n
2286 \s+main::foo\(\)\ called\ at\ \S+\ line\ 21\n
2288 'Test the o dieLevel option',
2292 # Test the warnLevel option
2294 my $wrapper = DebugWrap->new(
2302 prog => '../lib/perl5db/t/test-warnLevel-option-1',
2306 $wrapper->contents_like(qr#
2307 ^This\ is\ not\ a\ warning\.\ at\ \S+\ line\ 18\N*\.\n
2309 ^\s+main::baz\(\)\ called\ at\ \S+\ line\ 13\n
2310 \s+main::bar\(\)\ called\ at\ \S+\ line\ 25\n
2311 \s+main::myfunc\(\)\ called\ at\ \S+\ line\ 28\n
2313 'Test the o warnLevel option',
2317 # Test the t command
2319 my $wrapper = DebugWrap->new(
2327 prog => '../lib/perl5db/t/disable-breakpoints-1',
2331 $wrapper->contents_like(qr/
2332 ^main::\([^:]+:15\):\n
2333 15:\s+\$dummy\+\+;\n
2334 main::\([^:]+:17\):\n
2335 17:\s+\$x\ =\ "FourthVal";\n
2337 'Test the t command (without a number.)',
2341 # Test the o AutoTrace command
2343 my $wrapper = DebugWrap->new(
2351 prog => '../lib/perl5db/t/disable-breakpoints-1',
2355 $wrapper->contents_like(qr/
2356 ^main::\([^:]+:15\):\n
2357 15:\s+\$dummy\+\+;\n
2358 main::\([^:]+:17\):\n
2359 17:\s+\$x\ =\ "FourthVal";\n
2361 'Test the o AutoTrace command',
2365 # Test the t command with function calls
2367 my $wrapper = DebugWrap->new(
2378 prog => '../lib/perl5db/t/test-warnLevel-option-1',
2382 $wrapper->contents_like(qr/
2383 ^main::\([^:]+:28\):\n
2385 auto\(-\d+\)\s+DB<1>\s+t\n
2387 auto\(-\d+\)\s+DB<1>\s+b\ 18\n
2388 auto\(-\d+\)\s+DB<2>\s+c\n
2389 main::myfunc\([^:]+:25\):\n
2392 'Test the t command with function calls.',
2396 # Test the o AutoTrace command with function calls
2398 my $wrapper = DebugWrap->new(
2409 prog => '../lib/perl5db/t/test-warnLevel-option-1',
2413 $wrapper->contents_like(qr/
2414 ^main::\([^:]+:28\):\n
2416 auto\(-\d+\)\s+DB<1>\s+o\ AutoTrace\n
2417 \s+AutoTrace\s+=\s+'1'\n
2418 auto\(-\d+\)\s+DB<2>\s+b\ 18\n
2419 auto\(-\d+\)\s+DB<3>\s+c\n
2420 main::myfunc\([^:]+:25\):\n
2423 'Test the o AutoTrace command with function calls.',
2427 # Test the final message.
2429 my $wrapper = DebugWrap->new(
2436 prog => '../lib/perl5db/t/test-warnLevel-option-1',
2440 $wrapper->contents_like(qr/
2441 ^Debugged\ program\ terminated\.
2443 'Test the final "Debugged program terminated" message.',
2447 # Test the o inhibit_exit=0 command
2449 my $wrapper = DebugWrap->new(
2460 prog => '../lib/perl5db/t/test-warnLevel-option-1',
2464 $wrapper->contents_unlike(qr/
2465 ^Debugged\ program\ terminated\.
2467 'Test the o inhibit_exit=0 command.',
2471 # Test the o PrintRet=1 option
2473 my $wrapper = DebugWrap->new(
2486 prog => '../lib/perl5db/t/test-PrintRet-option-1',
2490 $wrapper->contents_like(
2491 qr/scalar context return from main::return_scalar: 20024/,
2492 "Test o PrintRet=1",
2496 # Test the o PrintRet=0 option
2498 my $wrapper = DebugWrap->new(
2511 prog => '../lib/perl5db/t/test-PrintRet-option-1',
2515 $wrapper->contents_unlike(
2517 "Test o PrintRet=0",
2521 # Test the o PrintRet=1 option in list context
2523 my $wrapper = DebugWrap->new(
2536 prog => '../lib/perl5db/t/test-PrintRet-option-1',
2540 $wrapper->contents_like(
2541 qr/list context return from main::return_list:\n0\s*'Foo'\n1\s*'Bar'\n2\s*'Baz'\n/,
2542 "Test o PrintRet=1 in list context",
2546 # Test the o PrintRet=0 option in list context
2548 my $wrapper = DebugWrap->new(
2561 prog => '../lib/perl5db/t/test-PrintRet-option-1',
2565 $wrapper->contents_unlike(
2567 "Test o PrintRet=0 in list context",
2571 # Test the o PrintRet=1 option in void context
2573 my $wrapper = DebugWrap->new(
2586 prog => '../lib/perl5db/t/test-PrintRet-option-1',
2590 $wrapper->contents_like(
2591 qr/void context return from main::return_void/,
2592 "Test o PrintRet=1 in void context",
2596 # Test the o PrintRet=1 option in void context
2598 my $wrapper = DebugWrap->new(
2611 prog => '../lib/perl5db/t/test-PrintRet-option-1',
2615 $wrapper->contents_unlike(
2617 "Test o PrintRet=0 in void context",
2621 # Test the o frame option.
2623 my $wrapper = DebugWrap->new(
2627 # This is to avoid getting the "Debugger program terminated"
2628 # junk that interferes with the normal output.
2636 prog => '../lib/perl5db/t/test-frame-option-1',
2640 $wrapper->contents_like(
2642 in\s*\.=main::my_other_func\(3,\ 1200\)\ from.*?
2643 out\s*\.=main::my_other_func\(3,\ 1200\)\ from
2645 "Test o PrintRet=0 in void context",
2650 my $wrapper = DebugWrap->new(
2654 # This is to avoid getting the "Debugger program terminated"
2655 # junk that interferes with the normal output.
2660 prog => '../lib/perl5db/t/fact',
2664 $wrapper->contents_like(
2666 (?:^main::fact.*return\ \$n\ \*\ fact\(\$n\ -\ 1\);.*)
2672 # Test the w for lexical variables expression.
2674 my $wrapper = DebugWrap->new(
2678 # This is to avoid getting the "Debugger program terminated"
2679 # junk that interferes with the normal output.
2687 prog => '../lib/perl5db/t/break-on-dot',
2691 $wrapper->contents_like(
2693 \s+old\ value:\s+'1'\n
2694 \s+new\ value:\s+'2'\n
2696 "Test w for lexical values.",
2700 # perl 5 RT #121509 regression bug.
2701 # “perl debugger doesn't save starting dir to restart from”
2702 # Thanks to Linda Walsh for reporting it.
2704 use File::Temp qw/tempdir/;
2706 my $temp_dir = tempdir( CLEANUP => 1 );
2708 local $ENV{__PERLDB_TEMP_DIR} = $temp_dir;
2709 my $wrapper = DebugWrap->new(
2713 # This is to avoid getting the "Debugger program terminated"
2714 # junk that interferes with the normal output.
2734 prog => '../lib/perl5db/t/rt-121509-restart-after-chdir',
2738 $wrapper->output_like(
2746 "Test that the debugger chdirs to the initial directory after a restart.",
2749 # Test the perldoc command
2750 # We don't actually run the program, but we need to provide one to the wrapper.
2754 or skip "man errors aren't especially portable", 1;
2756 or skip "man command seems to be missing", 1;
2757 local $ENV{LANG} = "C";
2758 local $ENV{LC_MESSAGES} = "C";
2759 local $ENV{LC_ALL} = "C";
2760 my $wrapper = DebugWrap->new(
2764 'perldoc perlrules',
2767 prog => '../lib/perl5db/t/fact',
2771 $wrapper->output_like(
2772 qr/No manual entry for perlrules/,
2773 'perldoc command works fine',
2778 1 while unlink ($rc_filename, $out_fn);