如何在Perl调试器中移动指令点?

时间:2009-10-16 21:32:05

标签: perl debugging

我希望能够(合理地)在Perl调试器中任意设置我的执行点。例如,在if的主体之前移动if并设置变量。

围绕perldebug(以及perldebguts和perl调试器POD)页面进行翻查表明,此类功能不受支持或未记录。

4 个答案:

答案 0 :(得分:1)

繁琐的解决方法是在整个代码中添加标签和条件goto语句。但是根据你想要模仿这个功能的严重程度,它可能是值得的。

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;
 }

示例调试会话:

$ 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>

我想知道是否可以构建一个使用这个想法的调试器。

答案 1 :(得分:1)

我仍然不确定这会实现什么,但我打赌一个自定义的runloop跳过你不关心的操作,直到你再次开始关心可能会解决你的问题。

对货物崇拜的良好运行是Runops::Switch。删除switch语句并编写一个跳过ops的函数,直到你想要运行它为止;然后调用正常的runloop来实际运行该操作。

相关代码:http://cpansearch.perl.org/src/RGARCIA/Runops-Switch-0.04/Switch.xs

这都是手工操作,我以前从未写过一个runloop。另一篇文章中的goto想法也很好,但这涉及编写更少的代码。

答案 2 :(得分:0)

断点只能在语句的第一行设置。

答案 3 :(得分:-1)

使用现有的调试器无法做到这一点。