http://www.perlmonks.org?node_id=750710

incognito129 has asked for the wisdom of the Perl Monks concerning the following question:

I'm trying to debug a script I wrote but I'd like to skip over a line. By skip i dont mean issuing the "c 1234" command but instead say if I'm on line 61, I want to not execute whatever is on line 61 and goto line 62. Is there any way of doing this?

Replies are listed 'Best First'.
Re: Using the perl debugger
by codeacrobat (Chaplain) on Mar 15, 2009 at 11:13 UTC
    To my knowledge there is no jump over next line. Hi maybe you could inject a LABEL on the next line and then goto that label?
    $ perl -de 'print "hello world\n"; die; LABEL: print "fnord\n"; exit 0;' Loading DB routines from perl5db.pl version 1.3 Editor support available. Enter h or `h h' for help, or `man perldebug' for more help. main::(-e:1): print "hello world\n"; DB<1> n hello world main::(-e:2): die; DB<1> n Died at -e line 2. at -e line 2 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<1> q $ perl -de 'print "hello world\n"; die; LABEL: print "fnord\n"; exit 0;' Loading DB routines from perl5db.pl version 1.3 Editor support available. Enter h or `h h' for help, or `man perldebug' for more help. main::(-e:1): print "hello world\n"; DB<1> n hello world main::(-e:2): die; DB<1> goto LABEL fnord 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.
    Unfortunately the goto breaks something in the debugger, the remaining code runs without user interaction (as if you had pressed "r").

    print+qq(\L@{[ref\&@]}@{['@'x7^'!#2/"!4']});
Re: Using the perl debugger
by planetscape (Chancellor) on Mar 15, 2009 at 17:23 UTC
      Devel::ptkdb has a "step over" command that should do the trick.

      Are you sure this isn't just a frontend to what happens when you press 'n' in the command line debugger? I.e. the usual "step over sub" ('n') vs. "step into sub / single step" ('s'). A quick check of the sources seems to confirm my suspicion...

        Actually, no, I am not 100% certain. I've not used either graphical debugger, just the CLI. I was basing my statement on an evident misreading of the content of the Devel::ptkdb tutorial, which states:

        Step in: continuing execution step by stepping inside the currently selected line of code. If the current line of code contains a function, stepping in will go inside that function.
        Step over: continuing execution over the currently selected line of code. Execution occurs unconditionally, regardless of the line's contents, and control returns to the debugger upon completion.

        As opposed to the CLI's help menu that n

        Next, steps over subs

        , not lines.

        My mistake. almut is correct.

        HTH,

        planetscape
Re: Using the perl debugger
by ww (Archbishop) on Mar 15, 2009 at 11:24 UTC

    Clumsy, but use {{ at the debugger prompt before the line(s) you want to "skip over."

    Line 25 below, set the "pre-debugger" command to an octothorpe, effectively turning the line in the next debugger step into a comment. You can see the effect at 29.

    Line 35 is one way of showing yourself what "pre-debugger" commands are in effect; Line 43 clears all "pre-debugger" commands.

    #!/usr/bin/perl use strict; use warnings; my @i = (2..5); for my $i (@i) { $i ++; print "foo"; print " $i\n"; } =head running under debug: >perl -d pl_test\test{{.pl Loading DB routines from perl5db.pl version 1.28 Editor support available. Enter h or `h h' for help, or `perldoc perldebug' for more help. main::(pl_test\test{{.pl:5): 5: my @i = (2..5); DB<1> {{ # DB<2> s main::(pl_test\test{{.pl:7): 7: for my $i (@i) { auto(-1) DB<2> # DB<2> s ... DB<2> {{ pre-debugger commands: {{ -- # DB<3> s foomain::(pl_test\test{{.pl:10): 10: print " $i\n"; auto(-1) DB<3> # DB<3> { * All { actions cleared. DB<4> ... continue normally =cut

    Update: bolded the first {{ in the narrative.

      use {{ ... effectively turning the line in the next debugger step into a comment.

      I don't think this has the desired effect of commenting out the lines. Rather, it runs the debugger command "#" (which does nothing of interest) before running the line itself. Even if you'd use pre-Perl actions (i.e. <), they would still be executed separately, rather than being textually merged with the line(s) in question (as would be required to comment out).

      Try skipping over the $i++, for example... the subsequent print " $i\n" will still print the incremented value (e.g. 3, not 2, on the first iteration).

      An example application of pre-debugger commands would be setting "{ l" to get a listing of the next few lines on every prompt.

      Unfortunately it doesn't work in perl5db.pl v1.30 :-( After "{{ #" statements are still getting executed.
      $ perl -v This is perl, v5.10.0 built for cygwin-thread-multi-64int (with 6 registered patches, see perl -V for more detail) $ perl -d bla.pl Loading DB routines from perl5db.pl version 1.3 Editor support available. Enter h or `h h' for help, or `man perldebug' for more help. main::(bla.pl:5): my @i = (2..5); DB<1> {{ # DB<2> s main::(bla.pl:7): for my $i (@i) { auto(-1) DB<2> # DB<2> s main::(bla.pl:8): $i ++; auto(-1) DB<2> # DB<2> s main::(bla.pl:9): print "foo"; auto(-1) DB<2> # DB<2> s main::(bla.pl:10): print " $i\n"; auto(-1) DB<2> # foo

      print+qq(\L@{[ref\&@]}@{['@'x7^'!#2/"!4']});

      Ooops! The behavior appears to vary depending on how lines are executed, leading me to believe almut may be correct and that codeacrobat's observation may apply to 5.8.8 (and probably others). A caveat (or "confusion") follows. Compare using r instead of stepping:

      >perl -d \pl_test\test{{.pl Loading DB routines from perl5db.pl version 1.28 Editor support available. Enter h or `h h' for help, or `perldoc perldebug' for more help. main::(\pl_test\test{{.pl:5): 5: my @i = (2..5); DB<1> {{ # DB<2> r foo 3 foo 4 foo 5 foo 6 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. auto(-1) DB<2> # DB<2> ...

      BUT, stepping (entirely) through the script:

      BUT: >perl -d pl_test\test{{.pl Loading DB routines from perl5db.pl version 1.28 Editor support available. Enter h or `h h' for help, or `perldoc perldebug' for more help. main::(pl_test\test{{.pl:5): 5: my @i = (2..5); DB<1> {{ # DB<2> s main::(pl_test\test{{.pl:7): 7: for my $i (@i) { auto(-1) DB<2> # DB<2> main::(pl_test\test{{.pl:8): 8: $i ++; auto(-1) DB<2> # DB<2> main::(pl_test\test{{.pl:9): 9: print "foo"; auto(-1) DB<2> # DB<2> foomain::(pl_test\test{{.pl:10): 10: print " $i\n"; auto(-1) DB<2> # DB<2> 3 main::(pl_test\test{{.pl:8): 8: $i ++; auto(-1) DB<2> # DB<2> main::(pl_test\test{{.pl:9): 9: print "foo"; auto(-1) DB<2> # DB<2> foomain::(pl_test\test{{.pl:10): 10: print " $i\n"; auto(-1) DB<2> # DB<2> 4 main::(pl_test\test{{.pl:8): 8: $i ++; auto(-1) DB<2> # DB<2> main::(pl_test\test{{.pl:9): 9: print "foo"; auto(-1) DB<2> # DB<2> foomain::(pl_test\test{{.pl:10): 10: print " $i\n"; auto(-1) DB<2> # DB<2> 5 main::(pl_test\test{{.pl:8): 8: $i ++; auto(-1) DB<2> # DB<2> main::(pl_test\test{{.pl:9): 9: print "foo"; auto(-1) DB<2> # DB<2> foomain::(pl_test\test{{.pl:10): 10: print " $i\n"; auto(-1) DB<2> # DB<2> 6 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. auto(-1) DB<2> # DB<2> Use `q' to quit or `R' to restart. `h q' for details. DB<2> s Use `q' to quit or `R' to restart. `h q' for details. ...

      WTF?

        BUT, stepping (entirely) through the script...

        ?? — I don't really see a difference in output. For example, the line print " $i\n" is still printing 3..6.  And the "foo" is there as well: foomain::(...

      I tried it out but it didn't work.
Re: Using the perl debugger
by educated_foo (Vicar) on Mar 15, 2009 at 22:45 UTC
    It's not going to happen. By the time the debugger gets your script, it's already compiled. If you're in a function, there's no way for it to change that function and continue in the changed version. The only thing I can think of that might work is to write a source filter to add labels before every line, then run the debugger on that version of the script, e.g. turn this:
    my $x = 23; die "blaagh!";
    into this:
    LINE1: my $x = 23; LINE2: die "blaagh!"
    then execute a goto in the debugger. Perl's goto is insanely powerful. Unfortunately, you would more or less have to parse the script to do this without introducing syntax errors (think multiline statements), so you're probably hosed.
      Is there then any way to skip over a line while debugging without previous modification of the script?
      Is there then any way to skip over a line while debugging without previous modification of the script? (that was me asking by the way -- now hopefully logged in)
      (and now finally logged in)
        If you've managed to insert the labels, then goto should be able to skip to the next line. That said, this whole source filtering thing is a terrible idea. The only decent way to do this would be through XS hacking, and that would take a lot of work.
Re: Using the perl debugger
by graff (Chancellor) on Mar 15, 2009 at 21:06 UTC
    if I'm on line 61, I want to not execute whatever is on line 61 and goto line 62.

    I think your only option is to edit the script first to comment out line 61, then run with the debugger with a breakpoint at line 62. If, upon reaching line 62, you decide you want to apply whatever was on line 61, just paste that line of code as a debugger command, and now things would be just as if line 61 had not been commented out.

    Another approach would be to create a new variable and wrap line 61 inside a conditional block on that variable like:

    my $dbg61 = 0; # <- add this line if($dbg61){ original code of line 61 }
    Then when you step to the original line 61 (which now begins with if($dbg61), and which might now be line 62 because you had to add a line above it), you can just reset the value of $dbg61 according to whether you really want that line to execute.

    This poses the dilemma that in order to debug the app, you have to change the code in ways that you wouldn't want to retain in production. But once you figure out whatever is wrong with your original line 61, you should be able to put things back as they are supposed to be.