Perl / perl5

🐪 The Perl programming language
https://dev.perl.org/perl5/
Other
1.85k stars 523 forks source link

debugger: line not optional for a #1274

Closed p5pRT closed 20 years ago

p5pRT commented 24 years ago

Migrated from rt.perl.org#2270 (status was 'resolved')

Searchable as RT2270$

p5pRT commented 24 years ago

From @tamias

Created by rjk@linguist.dartmouth.edu

The documentation in perldebug for the a debugger command suggests that the line argument is optional​:

  a [line] command

However\, the code in perl5db.pl requires the line argument.

Is the proper solution to update the documentation\, or to make the line argument optional?

I can do a patch either way.

Perl Info ``` Site configuration information for perl 5.00503: Configured by sting at Mon Jul 26 10:22:37 EDT 1999. Summary of my perl5 (5.0 patchlevel 5 subversion 3) configuration: Platform: osname=irix, osvers=6.5, archname=IP32-irix uname='irix linguist 6.5 01221644 ip32 ' hint=recommended, useposix=true, d_sigaction=define usethreads=undef useperlio=undef d_sfio=undef Compiler: cc='cc -n32', optimize='-O3', gccversion= cppflags='-D_BSD_TYPES -D_BSD_TIME -OPT:Olimit=0:space=ON -I/usr/local/include -DLANGUAGE_C' ccflags ='-D_BSD_TYPES -D_BSD_TIME -woff 1009,1110,1184 -OPT:Olimit=0:space=ON -I/usr/local/include -DLANGUAGE_C' stdchar='unsigned char', d_stdstdio=define, usevfork=false intsize=4, longsize=4, ptrsize=4, doublesize=8 d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16 alignbytes=8, usemymalloc=y, prototype=define Linker and Libraries: ld='cc -n32', ldflags ='-L/usr/local/lib -L/usr/linguist/lib -L/usr/local/lib32' libpth=/usr/local/lib /usr/lib32 /lib32 /lib /usr/lib /usr/linguist/lib libs=-lm libc=/usr/lib32/libc.so, so=so, useshrplib=false, libperl=libperl.a Dynamic Linking: dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags=' ' cccdlflags=' ', lddlflags='-n32 -shared -L/usr/local/lib -L/usr/linguist/lib -L/usr/local/lib32' Locally applied patches: @INC for perl 5.00503: /usr/linguist/lib/perl5/5.00503/IP32-irix /usr/linguist/lib/perl5/5.00503 /usr/linguist/lib/perl5/site_perl/5.005/IP32-irix /usr/linguist/lib/perl5/site_perl/5.005 . Environment for perl 5.00503: HOME=/usr/people/rjk LANG=C LANGUAGE (unset) LD_LIBRARY_PATH (unset) LOGDIR (unset) PATH=/usr/bin:/usr/linguist/bin:/usr/sbin:/usr/bsd:/sbin:/usr/bin/X11:/usr/local/bin:/usr/afsws/bin:/usr/etc:/usr/people/rjk/scripts:/usr/people/rjk/bin:. PERL_BADLANG (unset) SHELL=/bin/tcsh ```
p5pRT commented 24 years ago

From @gsar

On Mon\, 06 Mar 2000 17​:45​:24 EST\, "Ronald J. Kimball" wrote​:

The documentation in perldebug for the a debugger command suggests that the line argument is optional​:

  a \[line\] command

However\, the code in perl5db.pl requires the line argument.

Is the proper solution to update the documentation\, or to make the line argument optional?

The latter makes more sense to me.

Thanks.

Sarathy gsar@​ActiveState.com

p5pRT commented 24 years ago

From @tamias

On Mon\, Mar 06\, 2000 at 05​:39​:38PM -0800\, Gurusamy Sarathy wrote​:

On Mon\, 06 Mar 2000 17​:45​:24 EST\, "Ronald J. Kimball" wrote​:

The documentation in perldebug for the a debugger command suggests that the line argument is optional​:

  a \[line\] command

However\, the code in perl5db.pl requires the line argument.

Is the proper solution to update the documentation\, or to make the line argument optional?

The latter makes more sense to me.

I assume the correct behavior is to set an action for the line about to be executed\, as b without a line number sets a breakpoint on the line about to be executed.

Also\, the perldebug POD makes no distinction between a literal argument and a placeholder argument. For example​:

=item b load filename

load is a literal argument\, filename is a placeholder for an actual name of a file. Is there an appropriate POD sequence to highlight one or the other?

Ronald

p5pRT commented 24 years ago

From @tamias

On Mon\, Mar 06\, 2000 at 05​:39​:38PM -0800\, Gurusamy Sarathy wrote​:

On Mon\, 06 Mar 2000 17​:45​:24 EST\, "Ronald J. Kimball" wrote​:

The documentation in perldebug for the a debugger command suggests that the line argument is optional​:

  a \[line\] command

However\, the code in perl5db.pl requires the line argument.

Is the proper solution to update the documentation\, or to make the line argument optional?

The latter makes more sense to me.

Thanks.

Well\, this patch is going to take longer than I expected.

In the process of fixing this bug\, I discovered another bug in the debugger. There is a hash\, %had_breakpoints\, where keys are names of files that have had breakpoints (the values appear to be unused). The hash is also used for indicating actions\, but inconsistently​:

L\, to list all breakpoints/actions\, only checks files in %had_breakpoints.

a\, to set an action\, does not update %had_breakpoints. So\, L only lists actions in files that had breakpoints.

Similarly for A\, which only deletes actions from files that had breakpoints. Also\, D\, to delete all breakpoints\, undefs %had_breakpoints\, while A doesn't.

The simple solution is to have the a command set $had_breakpoints{$file} and neither the D nor A commands undef %had_breakpoints. However\, this means %had_breakpoints will not be reset when the user deletes all breakpoints and actions.

A slightly more complicated solution is to assign signifiance to the values in %had_breakpoints indicating breakpoints and actions\, i.e.​: 1 - breakpoints; 2 - actions; 3 - breakpoints and actions D will delete all breakpoints\, then iterate over %had_breakpoints\, zeroing the breakpoints bit and deleting any keys whose values are 0. A will do the same for actions.

I prefer the second solution. Thoughts?

And\, one final issue​: there does not appear to be any way to delete a single action. With breakpoints\, d [line] deletes a single breakpoint and D deletes all breakpoints\, but for actions there is only A to delete all actions. Is this a problem?

Ronald

p5pRT commented 24 years ago

From @gsar

On Wed\, 08 Mar 2000 00​:08​:04 EST\, Ronald J Kimball wrote​:

The simple solution is to have the a command set $had_breakpoints{$file} and neither the D nor A commands undef %had_breakpoints. However\, this means %had_breakpoints will not be reset when the user deletes all breakpoints and actions.

A slightly more complicated solution is to assign signifiance to the values in %had_breakpoints indicating breakpoints and actions\, i.e.​: 1 - breakpoints; 2 - actions; 3 - breakpoints and actions D will delete all breakpoints\, then iterate over %had_breakpoints\, zeroing the breakpoints bit and deleting any keys whose values are 0. A will do the same for actions.

I prefer the second solution. Thoughts?

Sounds fine.

Breakpoints and actions should be totally orthogonal. Perhaps you might want to consider using two separate hashes to keep the state...

And\, one final issue​: there does not appear to be any way to delete a single action. With breakpoints\, d [line] deletes a single breakpoint and D deletes all breakpoints\, but for actions there is only A to delete all actions. Is this a problem?

Why not support "A [line]" where [line] stands for a single line\, a range of lines\, or a file?

Sarathy gsar@​ActiveState.com

p5pRT commented 24 years ago

From [Unknown Contact. See original ticket]

Ronald J Kimball \rjk@​linguist\.dartmouth\.edu wrote

I prefer the second solution. Thoughts?

I'd recommend whatever leads to the cleanest code. perl5db.pl is quite tangled enough already.

And\, one final issue​: there does not appear to be any way to delete a single action. With breakpoints\, d [line] deletes a single breakpoint and D deletes all breakpoints\, but for actions there is only A to delete all actions. Is this a problem?

Sure you can. Just go "a 123" or whatever. Note that you can only have one action at each point (and only one breakpoint)\, and it can be null.

perldoc.pod is not as explicit as it might be\, but you can read between the lines. :-)

Mike Guy

p5pRT commented 24 years ago

From @tamias

On Wed\, Mar 08\, 2000 at 03​:23​:12AM -0800\, Gurusamy Sarathy wrote​:

On Wed\, 08 Mar 2000 00​:08​:04 EST\, Ronald J Kimball wrote​:

The simple solution is to have the a command set $had_breakpoints{$file} and neither the D nor A commands undef %had_breakpoints. However\, this means %had_breakpoints will not be reset when the user deletes all breakpoints and actions.

A slightly more complicated solution is to assign signifiance to the values in %had_breakpoints indicating breakpoints and actions\, i.e.​: 1 - breakpoints; 2 - actions; 3 - breakpoints and actions D will delete all breakpoints\, then iterate over %had_breakpoints\, zeroing the breakpoints bit and deleting any keys whose values are 0. A will do the same for actions.

I prefer the second solution. Thoughts?

Sounds fine.

Breakpoints and actions should be totally orthogonal. Perhaps you might want to consider using two separate hashes to keep the state...

That is another option. Then the L command would iterate over a union of the two hashes\, but the A and D commands could just iterate over and undef their own hashes.

However\, I'm not sure breakpoints and actions need to be totally orthogonal. The breakpoints and actions themselves are kept in the same hash (%dbline)\, and the L and R commands operate on breakpoints and actions together.

And\, one final issue​: there does not appear to be any way to delete a single action. With breakpoints\, d [line] deletes a single breakpoint and D deletes all breakpoints\, but for actions there is only A to delete all actions. Is this a problem?

Why not support "A [line]" where [line] stands for a single line\, a range of lines\, or a file?

That's a good idea; I'll include that in the patch.

Ronald

p5pRT commented 24 years ago

From @tamias

On Wed\, Mar 08\, 2000 at 01​:31​:39PM +0000\, M.J.T. Guy wrote​:

Ronald J Kimball \rjk@​linguist\.dartmouth\.edu wrote

And\, one final issue​: there does not appear to be any way to delete a single action. With breakpoints\, d [line] deletes a single breakpoint and D deletes all breakpoints\, but for actions there is only A to delete all actions. Is this a problem?

Sure you can. Just go "a 123" or whatever. Note that you can only have one action at each point (and only one breakpoint)\, and it can be null.

You're right\, the code in perl5db.pl does support setting a null action\, which is equivalent to deleting an existing action. I'll patch perldebug.pod to clarify that.

Ronald

p5pRT commented 24 years ago

From @tamias

This patch makes the following changes to perl5db.pl and perldebug.pod​:

Increments the version of perl5db.pl to 1.06.

Makes the line argument optional for the a command.

Makes the a command delete the entry from %dbline if the line has neither a breakpoint nor an action\, like the d command.

Updates various commands to use %had_breakpoints for indicating actions as well as breakpoints. (1 - breakpoints; 2 - actions; 3 - both)

Makes the A command output "Deleting all actions..."\, like the D command.

Simplifies a few logical expressions.

Fixes column alignments in the online help.

Updates the documentation for the a command to specify the default for line and specify the behavior of deleting an action.

Ronald

Inline Patch ```diff --- lib/perl5db.pl.orig Fri Feb 4 05:26:23 2000 +++ lib/perl5db.pl Wed Mar 8 23:06:57 2000 @@ -2,7 +2,7 @@ # Debugger for Perl 5.00x; perl5db.pl patch level: -$VERSION = 1.05; +$VERSION = 1.06; $header = "perl5db.pl version $VERSION"; # Enhanced by ilya@math.ohio-state.edu (Ilya Zakharevich) @@ -530,7 +530,7 @@ } next CMD; }; $cmd =~ /^t$/ && do { - ($trace & 1) ? ($trace &= ~1) : ($trace |= 1); + $trace ^= 1; print $OUT "Trace = " . (($trace & 1) ? "on" : "off" ) . "\n"; next CMD; }; @@ -700,11 +700,14 @@ } } } + + if (not $had_breakpoints{$file} &= ~1) { + delete $had_breakpoints{$file}; + } } undef %postponed; undef %postponed_file; undef %break_on_load; - undef %had_breakpoints; next CMD; }; $cmd =~ /^L$/ && do { my $file; @@ -779,7 +782,7 @@ $break_on_load{$::INC{$file}} = 1 if $::INC{$file}; $file .= '.pm', redo unless $file =~ /\./; } - $had_breakpoints{$file} = 1; + $had_breakpoints{$file} |= 1; print $OUT "Will stop on load of `@{[join '\', `', sort keys %break_on_load]}'.\n"; next CMD; }; $cmd =~ /^b\b\s*(postpone|compile)\b\s*([':A-Za-z_][':\w]*)\s*(.*)/ && do { @@ -805,7 +808,7 @@ if ($i) { local $filename = $file; local *dbline = $main::{'_<' . $filename}; - $had_breakpoints{$filename} = 1; + $had_breakpoints{$filename} |= 1; $max = $#dbline; ++$i while $dbline[$i] == 0 && $i < $max; $dbline{$i} =~ s/^[^\0]*/$cond/; @@ -814,21 +817,22 @@ } next CMD; }; $cmd =~ /^b\b\s*(\d*)\s*(.*)/ && do { - $i = ($1?$1:$line); + $i = $1 || $line; $cond = $2 || '1'; if ($dbline[$i] == 0) { print $OUT "Line $i not breakable.\n"; } else { - $had_breakpoints{$filename} = 1; + $had_breakpoints{$filename} |= 1; $dbline{$i} =~ s/^[^\0]*/$cond/; } next CMD; }; - $cmd =~ /^d\b\s*(\d+)?/ && do { - $i = ($1?$1:$line); + $cmd =~ /^d\b\s*(\d*)/ && do { + $i = $1 || $line; $dbline{$i} =~ s/^[^\0]*//; delete $dbline{$i} if $dbline{$i} eq ''; next CMD; }; $cmd =~ /^A$/ && do { + print $OUT "Deleting all actions...\n"; my $file; for $file (keys %had_breakpoints) { local *dbline = $main::{'_<' . $file}; @@ -841,6 +845,10 @@ delete $dbline{$i} if $dbline{$i} eq ''; } } + + if (not $had_breakpoints{$file} &= ~2) { + delete $had_breakpoints{$file}; + } } next CMD; }; $cmd =~ /^O\s*$/ && do { @@ -872,13 +880,19 @@ $pretype = [], next CMD unless $1; $pretype = [$1]; next CMD; }; - $cmd =~ /^a\b\s*(\d+)(\s+(.*))?/ && do { - $i = $1; $j = $3; - if ($dbline[$i] == 0) { - print $OUT "Line $i may not have an action.\n"; + $cmd =~ /^a\b\s*(\d*)\s*(.*)/ && do { + $i = $1 || $line; $j = $2; + if (length $j) { + if ($dbline[$i] == 0) { + print $OUT "Line $i may not have an action.\n"; + } else { + $had_breakpoints{$filename} |= 2; + $dbline{$i} =~ s/\0[^\0]*//; + $dbline{$i} .= "\0" . action($j); + } } else { $dbline{$i} =~ s/\0[^\0]*//; - $dbline{$i} .= "\0" . action($j); + delete $dbline{$i} if $dbline{$i} eq ''; } next CMD; }; $cmd =~ /^n$/ && do { @@ -906,7 +920,7 @@ if ($i) { $filename = $file; *dbline = $main::{'_<' . $filename}; - $had_breakpoints{$filename}++; + $had_breakpoints{$filename} |= 1; $max = $#dbline; ++$i while $dbline[$i] == 0 && $i < $max; } else { @@ -1086,7 +1100,7 @@ next CMD; }; $cmd =~ /^$rc+\s*(-)?(\d+)?$/ && do { pop(@hist) if length($cmd) > 1; - $i = $1 ? ($#hist-($2?$2:1)) : ($2?$2:$#hist); + $i = $1 ? ($#hist-($2||1)) : ($2||$#hist); $cmd = $hist[$i]; print $OUT $cmd, "\n"; redo CMD; }; @@ -1301,7 +1315,7 @@ $i += $offset; local *dbline = $main::{'_<' . $file}; local $^W = 0; # != 0 is magical below - $had_breakpoints{$file}++; + $had_breakpoints{$file} |= 1; my $max = $#dbline; ++$i until $dbline[$i] != 0 or $i >= $max; $dbline{$i} = delete $postponed{$subname}; @@ -1329,7 +1343,7 @@ if $break_on_load{$filename}; print $LINEINFO ' ' x $stack_depth, "Package $filename.\n" if $frame; return unless $postponed_file{$filename}; - $had_breakpoints{$filename}++; + $had_breakpoints{$filename} |= 1; #%dbline = %{$postponed_file{$filename}}; # Cannot be done: unsufficient magic my $key; for $key (keys %{$postponed_file{$filename}}) { @@ -1821,7 +1835,7 @@ B IB<->I List lines I through I. B I List single I. B I List first window of lines from subroutine. -B I<$var> List first window of lines from subroutine referenced by I<$var>. +B I<\$var> List first window of lines from subroutine referenced by I<\$var>. B List next window of lines. B<-> List previous window of lines. B [I] List window around I. @@ -1844,7 +1858,7 @@ I breaks if it evaluates to true, defaults to '1'. B I [I] Set breakpoint at first line of subroutine. -B I<$var> Set breakpoint at first line of subroutine referenced by I<$var>. +B I<\$var> Set breakpoint at first line of subroutine referenced by I<\$var>. B B I Set breakpoint on `require'ing the given file. B B I [I] Set breakpoint at first line of subroutine after @@ -1854,10 +1868,12 @@ B [I] Delete the breakpoint for I. B Delete all breakpoints. B [I] I - Set an action to be done before the I is executed. + Set an action to be done before the I is executed; + I defaults to the current execution line. Sequence is: check for breakpoint/watchpoint, print line if necessary, do action, prompt user if necessary, - execute expression. + execute line. +B [I] Delete the action for I. B Delete all actions. B I Add a global watch-expression. B Delete all watch-expressions. @@ -1877,7 +1893,7 @@ I I I: level of verbosity; I Allows stepping off the end of the script. I Debugger should stop as early as possible. - I: Remote hostname:port for remote debugging + I: Remote hostname:port for remote debugging The following options affect what happens with B, B, and B commands: I, I: print only first N elements ('' for all); I, I: change style of array and hash dump; @@ -1884,7 +1900,7 @@ I: whether to print contents of globs; I: dump arrays holding debugged files; I: dump symbol tables of packages; - I: dump contents of \"reused\" addresses; + I: dump contents of \"reused\" addresses; I, I, I: change style of string dump; I: Do not print the overload-stringified value; Option I affects printing of return value after B command, @@ -1899,7 +1915,7 @@ B<<> I Define Perl command to run before each prompt. B<<<> I Add to the list of Perl commands to run before each prompt. B<>> I Define Perl command to run after each prompt. -B<>>B<>> I Add to the list of Perl commands to run after each prompt. +B<>>B<>> I Add to the list of Perl commands to run after each prompt. B<{> I Define debugger command to run before each prompt. B<{{> I Add to the list of debugger commands to run before each prompt. B<$prc> I Redo a previous command (default previous command). --- pod/perldebug.pod.orig Mon Feb 7 08:28:02 2000 +++ pod/perldebug.pod Wed Mar 8 23:19:11 2000 @@ -281,7 +281,8 @@ =item a [line] command -Set an action to be done before the line is executed. +Set an action to be done before the line is executed. If line is +omitted, sets an action on the line that is about to be executed. The sequence of steps taken by the debugger is 1. check for a breakpoint at this line @@ -294,6 +295,11 @@ 53 is passed: a 53 print "DB FOUND $foo\n" + +=item a [line] + +Delete an action at the specified line. If line is omitted, deletes +the action on the line that is about to be executed. =item A ```