# Debugger for Perl 5.00x; perl5db.pl patch level:
-$VERSION = 1.13;
+$VERSION = 1.15;
$header = "perl5db.pl version $VERSION";
#
# This file is automatically included if you do perl -d.
# It's probably not useful to include this yourself.
#
+# Before venturing further into these twisty passages, it is
+# wise to read the perldebguts man page or risk the ire of dragons.
+#
# Perl supplies the values for %sub. It effectively inserts
# a &DB'DB(); in front of every place that can have a
# breakpoint. Instead of a subroutine call it calls &DB::sub with
# if caller() is called from the package DB, it provides some
# additional data.
#
-# The array @{$main::{'_<'.$filename}} is the line-by-line contents of
-# $filename.
+# The array @{$main::{'_<'.$filename}} (herein called @dbline) is the
+# line-by-line contents of $filename.
#
-# The hash %{'_<'.$filename} contains breakpoints and action (it is
-# keyed by line number), and individual entries are settable (as
-# opposed to the whole hash). Only true/false is important to the
-# interpreter, though the values used by perl5db.pl have the form
-# "$break_condition\0$action". Values are magical in numeric context.
+# The hash %{'_<'.$filename} (herein called %dbline) contains
+# breakpoints and action (it is keyed by line number), and individual
+# entries are settable (as opposed to the whole hash). Only true/false
+# is important to the interpreter, though the values used by
+# perl5db.pl have the form "$break_condition\0$action". Values are
+# magical in numeric context.
#
# The scalar ${'_<'.$filename} contains $filename.
#
# I<CreateTTY> bits control attempts to create a new TTY on events:
# 1: on fork() 2: debugger is started inside debugger
# 4: on startup
-# c) Code to auto-create a new TTY window on OS/2 (currently one one
+# c) Code to auto-create a new TTY window on OS/2 (currently one
# extra window per session - need named pipes to have more...);
# d) Simplified interface for custom createTTY functions (with a backward
# compatibility hack); now returns the TTY name to use; return of ''
# + Fixed warnings generated by "p 42" (Print expression)
# Changes: 1.13: Jun 19, 2001 Scott.L.Miller@compaq.com
# + Added windowSize option
+# Changes: 1.14: Oct 9, 2001 multiple
+# + Clean up after itself on VMS (Charles Lane in 12385)
+# + Adding "@ file" syntax (Peter Scott in 12014)
+# + Debug reloading selfloaded stuff (Ilya Zakharevich in 11457)
+# + $^S and other debugger fixes (Ilya Zakharevich in 11120)
+# + Forgot a my() declaration (Ilya Zakharevich in 11085)
+# Changes: 1.15: Nov 6, 2001 Michael G Schwern <schwern@pobox.com>
+# + Updated 1.14 change log
+# + Added *dbline explainatory comments
+# + Mentioning perldebguts man page
####################################################################
# Needed for the statement after exec():
# These guys may be defined in $ENV{PERL5DB} :
$rl = 1 unless defined $rl;
-$warnLevel = 0 unless defined $warnLevel;
-$dieLevel = 0 unless defined $dieLevel;
+$warnLevel = 1 unless defined $warnLevel;
+$dieLevel = 1 unless defined $dieLevel;
$signalLevel = 1 unless defined $signalLevel;
$pre = [] unless defined $pre;
$post = [] unless defined $post;
);
if (!$OUT) { die "Unable to connect to remote host: $remoteport\n"; }
$IN = $OUT;
- } elsif ($CreateTTY & 4) {
- create_IN_OUT(4);
} else {
+ create_IN_OUT(4) if $CreateTTY & 4;
if (defined $console) {
my ($i, $o) = split /,/, $console;
$o = $i unless defined $o;
next CMD;
}
}
- $cmd =~ /^q$/ && ($fall_off_end = 1) && exit $?;
+ $cmd =~ /^q$/ && ($fall_off_end = 1) && clean_ENV() && exit $?;
$cmd =~ /^h$/ && do {
print_help($help);
next CMD; };
$i = $end;
} else {
for (; $i <= $end; $i++) {
+ my ($stop,$action);
($stop,$action) = split(/\0/, $dbline{$i}) if
$dbline{$i};
$arrow = ($i==$line
*dbline = $main::{'_<' . $file};
next unless %dbline or $postponed_file{$file};
(push @hard, $file), next
- if $file =~ /^\(eval \d+\)$/;
+ if $file =~ /^\(\w*eval/;
my @add;
@add = %{$postponed_file{$file}}
if $postponed_file{$file};
}
}
next CMD; };
+ $cmd =~ /^\@\s*(.*\S)/ && do {
+ if (open my $fh, $1) {
+ push @cmdfhs, $fh;
+ }
+ else {
+ &warn("Can't execute `$1': $!\n");
+ }
+ next CMD; };
$cmd =~ /^\|\|?\s*[^|]/ && do {
if ($pager =~ /^\|/) {
open(SAVEOUT,">&STDOUT") || &warn("Can't save STDOUT");
}
local $frame = 0;
local $doret = -2;
+ while (@cmdfhs) {
+ my $line = CORE::readline($cmdfhs[-1]);
+ defined $line ? (print $OUT ">> $line" and return $line)
+ : close pop @cmdfhs;
+ }
if (ref $OUT and UNIVERSAL::isa($OUT, 'IO::Socket::INET')) {
$OUT->write(join('', @_));
my $stuff;
}
&warn("Too late to set TTY, enabled on next `R'!\n") if $term and @_;
# Useful if done through PERLDB_OPTS:
- $tty = shift if @_;
+ $console = $tty = shift if @_;
$tty or $console;
}
. ( $rc eq $sh ? "" : "
B<$psh> [I<cmd>] Run I<cmd> in subshell (forces \"\$SHELL -c 'cmd'\")." ) . "
See 'B<O> I<shellBang>' too.
+B<@>I<file> Execute I<file> containing debugger commands (may nest).
B<H> I<-number> Display last number commands (default all).
B<p> I<expr> Same as \"I<print {DB::OUT} expr>\" in current package.
B<|>I<dbcmd> Run debugger command, piping DB::OUT to current pager.
if ($dieLevel < 2) {
die @_ if $^S; # in eval propagate
}
- eval { require Carp } if defined $^S; # If error/warning during compilation,
+ # No need to check $^S, eval is much more robust nowadays
+ eval { require Carp }; #if defined $^S;# If error/warning during compilation,
# require may be broken.
die(@_, "\nCannot print stack trace, load with -MCarp option to see stack")
# inside DB::DB, but not in Carp).
my ($mysingle,$mytrace) = ($single,$trace);
$single = 0; $trace = 0;
- my $mess = Carp::longmess(@_);
+ my $mess = "@_";
+ {
+ package Carp; # Do not include us in the list
+ eval {
+ $mess = Carp::longmess(@_);
+ };
+ }
($single,$trace) = ($mysingle,$mytrace);
die $mess;
}
print $OUT "Use `q' to quit or `R' to restart. `h q' for details.\n"
}
+sub clean_ENV {
+ if (defined($ini_pids)) {
+ $ENV{PERLDB_PIDS} = $ini_pids;
+ } else {
+ delete($ENV{PERLDB_PIDS});
+ }
+}
+
END {
$finished = 1 if $inhibit_exit; # So that some keys may be disabled.
$fall_off_end = 1 unless $inhibit_exit;