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

Gurus,

It's said that perl debugger support to set a breakpoint by a code reference. but I really never succeed to set such kind of breakpoint.

b $var        Set breakpoint at first line of subroutine referenced by $var.

I'd like to give an example including codes and my debug process.

#!/usr/bin/env perl use 5.016; my $mysubref = sub { say "This is code Ref 0"; say "This is code Ref 1"; say "This is code Ref 2"; }; testMethod(); sub testMethod { say "in testMethod"; &{$mysubref}; } say "end the program";

The debug process is,

H:\store\workspace\myTestCodes>perl -d .\test6.pl Loading DB routines from perl5db.pl version 1.37 Editor support available. Enter h or 'h h' for help, or 'perldoc perldebug' for more help. main::(.\test6.pl:8): }; DB<1> c 10 main::(.\test6.pl:10): testMethod(); DB<2> b $mysubref DB<3> L b .\test6.pl: 10: testMethod(); break if ($mysubref) DB<4> c in testMethod This is code Ref 0 This is code Ref 1 This is code Ref 2 end the program 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<4>

'b $mysubref' seems not to work.

Please tell me what's wrong here. How can I set a breakpoint by a code reference?

Thanks in advance.

Replies are listed 'Best First'.
Re: how to set a breakpoint by a code reference
by ysth (Canon) on Nov 18, 2013 at 06:11 UTC
    I'm not sure where you are getting
    b $mysubref
    from. The doc I see says this, which seems to be the behaviour you are triggering:
    b [line] [condition] Set a breakpoint before the given line. If a condition is specified, it's evaluated each time the statement is reached: a breakpoint is taken only if the condition is true. Breakpoints may only be set on lines that begin an executable statement. Conditions don't use "if":
    That is, you are setting a break point at the current line (because you specify no line) if $mysubref is true.
    --
    A math joke: r = | |csc(θ)|+|sec(θ)| |-| |csc(θ)|-|sec(θ)| |
      Here is the output document,
      C:\Users>perl -d -e 0 Loading DB routines from perl5db.pl version 1.37 Editor support available. Enter h or 'h h' for help, or 'perldoc perldebug' for more help. main::(-e:1): 0 DB<1> h b b Sets breakpoint on current line) b [line] [condition] Set breakpoint; line defaults to the current execution line; condition breaks if it evaluates to true, defaults to '1'. b subname [condition] Set breakpoint at first line of subroutine. b $var Set breakpoint at first line of subroutine referenced by + $var. b load filename Set breakpoint on 'require'ing the given file. b postpone subname [condition] Set breakpoint at first line of subroutine after it is compiled. b compile subname Stop after the subroutine is compiled. DB<2> q C:\Users>perl -v This is perl 5, version 16, subversion 3 (v5.16.3) built for MSWin32-x +86-multi-t hread (with 1 registered patch, see perl -V for more detail) Copyright 1987-2012, Larry Wall Binary build 1603 [296746] provided by ActiveState http://www.ActiveSt +ate.com Built Mar 13 2013 11:29:21 Perl may be copied only under the terms of either the Artistic License + or the GNU General Public License, which may be found in the Perl 5 source ki +t. Complete documentation for Perl, including FAQ lists, should be found +on this system using "man perl" or "perldoc perl". If you have access to + the Internet, point your browser at http://www.perl.org/, the Perl Home Pa +ge.
        Interesting; that doesn't match perldoc perldebug.
        --
        A math joke: r = | |csc(θ)|+|sec(θ)| |-| |csc(θ)|-|sec(θ)| |
Re: how to set a breakpoint by a code reference
by LanX (Saint) on Nov 18, 2013 at 12:50 UTC
    I can confirm the problem.

    from perldebug

    b subname [condition] Set a breakpoint before the first line of the named subroutine. subnam +e may be a variable containing a code reference (in this case conditi +on is not supported).

    And you are not the first one noticing it, see this thread from 2008: b $var

    IMHO the watch expression you get shown from L looks weird...probably a bug!

    I'll try to dig later a little bit into the source code of perl5db.pl trying to better understand what is happening.

    Cheers Rolf

    ( addicted to the Perl Programming Language)

      Hi LanX,

      Thank you for your quick reply.

      Could you let us know if you make any progress?

      This debug feature of Perl can help me a lot.

      BR

        Hi

        I inspected the code and sorry it's not implemented.

        In b $var $var is interpreted as a condition and the breakpoint is set at the current point in code.

        Thats why you see something like this after listing breakpoints

        DB<105> L 10: }; break if ($var)

        you may wanna check cmd_b() on your own.

        There is even no trace that it was even attempted to be implemented.

        cmd_b_sub() explicitely ignores references.

        Though I can find the anonymous sub in %DB::sub as

         "main::__ANON__[/tmp/tst.pl:10]" => "/tmp/tst.pl:6-10"

        But I can't connect it to the subref.

        ... hmm wait ...

        well DB::CvGV_name($mysubref) seems to fix it main::__ANON__[/tmp/tst.pl:10]

        ok I will try to fix it, but this will result in a patch. (update see--> Re: how to set a breakpoint by a code reference (workaround))

        Cheers Rolf

        ( addicted to the Perl Programming Language)

Re: how to set a breakpoint by a code reference
by 2teez (Vicar) on Nov 18, 2013 at 10:02 UTC

    Hi Matq,

    ..How can I set a breakpoint by a code reference?..

    Using $DB::single = 1; at the line where you want to set a breakpoint in your script might be want you want.
    Please see perldebug

    If you tell me, I'll forget.
    If you show me, I'll remember.
    if you involve me, I'll understand.
    --- Author unknown to me
      Hi 2teez, I just want to set/clean breakpoint freely; and don't like to add/delete the directives here and there. :) BR
Re: how to set a breakpoint by a code reference (workaround)
by LanX (Saint) on Nov 19, 2013 at 03:44 UTC
    in continuation of Re^3: how to set a breakpoint by a code reference

    It's not a bug-fix but a temporary hack!

    put the following line into a file in your homedir called '.perldb'

    $DB::alias{b} = q# s/^b\s+(\$\w+)\s*$/'"b ". DB::CvGV_name('.$1.')'/ee +; #

    it creates an alias which intercepts the debuger command b and tries to replace the code-ref with the ANON-name before calling the real command b.

    Works for me!

    HTH! =)

    Could someone with the newest version of the debugger plz check if the bug is still present and if it can be fixed this way?

    update

    Well at least the version on cpan seems still to be buggy.

    Cheers Rolf

    ( addicted to the Perl Programming Language)

    NB: the Variablename parsing is simplistic things like '::' or _ won't match.

      Hi LanX

      I did a quick test using the workaround, but failed:(

      It didn't stop at the breakpoint.

      Please have a look and point out anything wrong with my test.

      Thanks.

      PS H:\store\workspace\myTestCodes> cat ~/.perldb $DB::alias{b} = q# s/^b\s+(\$\w+)\s*$/'"b ". DB::CvGV_name('.$1.')'/ee +; # PS H:\store\workspace\myTestCodes> cat .\test6.pl #!/usr/bin/env perl use 5.016; my $mysubref = sub { say "This is code Ref 0"; say "This is code Ref 1"; say "This is code Ref 2"; }; testMethod(); sub testMethod { say "in testMethod"; &{$mysubref}; } say "end the program"; PS H:\store\workspace\myTestCodes> perl -d .\test6.pl Loading DB routines from perl5db.pl version 1.37 Editor support available. Enter h or 'h h' for help, or 'perldoc perldebug' for more help. main::(.\test6.pl:8): }; DB<1> n main::(.\test6.pl:10): testMethod(); DB<1> b $mysubref DB<2> L b .\test6.pl: 10: testMethod(); break if ($mysubref) DB<3> c in testMethod This is code Ref 0 This is code Ref 1 This is code Ref 2 end the program 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> q PS H:\store\workspace\myTestCodes> perl -v This is perl 5, version 16, subversion 3 (v5.16.3) built for MSWin32-x +86-multi-thread (with 1 registered patch, see perl -V for more detail) Copyright 1987-2012, Larry Wall Binary build 1603 [296746] provided by ActiveState http://www.ActiveSt +ate.com Built Mar 13 2013 11:29:21 Perl may be copied only under the terms of either the Artistic License + or the GNU General Public License, which may be found in the Perl 5 source ki +t. Complete documentation for Perl, including FAQ lists, should be found +on this system using "man perl" or "perldoc perl". If you have access to + the Internet, point your browser at http://www.perl.org/, the Perl Home Pa +ge. PS H:\store\workspace\myTestCodes>

      BR

        I think the config isn't found cause home dir is messed up on your win system.

        Try checking with = if the alias was included.

        Try including prints in .perldb to get a feedback when sourced.

        Prepend the alias with a print to see when it fires, maybe you need to extend the regex.

        IOW localize the problem! : )

        Cheers Rolf

        ( addicted to the Perl Programming Language)