tags:

views:

174

answers:

4

I would like to be able to (reasonably) arbitrarily set my execution point in the Perl debugger. E.g., moving immediately prior to an if from the body of the if and setting a variable.

Rummaging around the perldebug(and perldebguts and the perl debugger POD) page suggests that this kind of functionality is either not supported or not documented.

A: 

This can't be done with the existing debugger.

nick
Wait a second, so far every answer is "no" and I get voted down? Really?
nick
Your answer wasn't "no." Your answer only told us what it is that you don't believe. That doesn't sound very confident. So you don't actually know the answer, and you have no alternative to suggest. Your answer wasn't useful, and was therefore worthy of a negative vote. (I thought -1 was enough, so I did not vote on it myself.) Besides, the other answers weren't "no," either. It wasn't a yes/no question. It was a "how" question. If you don't know how, and you don't know that it's impossible, then what contribution will your answer really make?
Rob Kennedy
A: 

Breakpoints can only be set on the first line of a statement.

David Harris
I'm not looking to set a breakpoint. I want to move my execution point - the instruction pointer of the Perl VM.
Paul Nathan
What Paul is asking for is not what breakpoints do. While the program is paused, Paul wants to point at a specific line and say, "Resume running right here, now. Don't run anything more beforehand." A breakpoint doesn't let you skip over code or re-run code you've just passed. Moving the IP does.
Rob Kennedy
Rob has it correct.
Paul Nathan
+1  A: 

A cumbersome workaround would be to add labels and conditional goto statements throughout your code. But depending on how badly you want to emulate this feature, it might be worth it.

POINT1: $GOTO="";      # $GOTO is our fake variable that we only set from the debugger
($a,$b,$c)=(1,2,3);
POINT2: $GOTO="";
if ($a < $b) {
    goto $GOTO if $GOTO;
    if ($a > $c) {
        goto $GOTO if $GOTO;
        print "foo\n";
    } else {
        goto $GOTO if $GOTO;
        print "bar\n";
    }
    goto $GOTO if $GOTO;
 } else {
    goto $GOTO if $GOTO;
    print "nothing\n";
    goto $GOTO if $GOTO;
 }

Sample debugging session:

$ perl -d debuggoto.pl

Loading DB routines from perl5db.pl version 1.28
Editor support available.

Enter h or `h h' for help, or `man perldebug' for more help.

main::(debuggoto.pl:1): POINT1: $GOTO="";      # $GOTO is our fake variable that we only set from the debugger
  DB<1> n
main::(debuggoto.pl:2): ($a,$b,$c)=(1,2,3);
  DB<1>
main::(debuggoto.pl:3): POINT2: $GOTO="";
  DB<1>
main::(debuggoto.pl:4): if ($a < $b) {
  DB<1>
main::(debuggoto.pl:5):    goto $GOTO if $GOTO;
  DB<1>
main::(debuggoto.pl:6):    if ($a > $c) {
  DB<1>
main::(debuggoto.pl:10):               goto $GOTO if $GOTO;
  DB<1>
main::(debuggoto.pl:11):               print "bar\n";
  DB<1>
bar
main::(debuggoto.pl:13):           goto $GOTO if $GOTO;
  DB<1> $GOTO="POINT2"

  DB<2> n
main::(debuggoto.pl:3): POINT2: $GOTO="";
  DB<2> $c=0

  DB<3> n
main::(debuggoto.pl:4): if ($a < $b) {
  DB<3>
main::(debuggoto.pl:5):    goto $GOTO if $GOTO;
  DB<3>
main::(debuggoto.pl:6):    if ($a > $c) {
  DB<3>
main::(debuggoto.pl:7):        goto $GOTO if $GOTO;
  DB<3>
main::(debuggoto.pl:8):        print "foo\n";
  DB<3>
foo
main::(debuggoto.pl:13):           goto $GOTO if $GOTO;
  DB<3>
Debugged program terminated.  Use q to quit or R to restart,
  use o inhibit_exit to avoid stopping after program termination,
  h q, h R or h o to get additional info.
  DB<3>
Use `q' to quit or `R' to restart.  `h q' for details.
  DB<3>

I wonder if it would be possible to build a debugger that uses this idea.

mobrule
Paul Nathan
+1  A: 

I am still not sure what exactly this would achieve, but I bet a custom runloop that skips ops you don't care about until you start caring again might solve your problem.

A good runloop to cargo-cult is Runops::Switch. Remove the switch statement and write a function that skips ops until you are on the one you want to run; then just call into the normal runloop to actually run that op.

Relevant code: http://cpansearch.perl.org/src/RGARCIA/Runops-Switch-0.04/Switch.xs

This is all handwaving, I have never written a runloop before. The goto idea in another post is also good, but this involves writing less code.

jrockway