Perl 或 Perl 调试器优化“空”`if``s?

问题描述 投票:0回答:1

在开发一些代码时,我运行了一些不完整的代码,其中

ìf
/
else
部分仍然需要完成。然而,条件调用例程具有“副作用”,因此我希望能够跟踪基本逻辑流程。

然而,最初的

n
处的一个
if
命令似乎跳过了整个
if
...
elsif
...
else
语句。

考虑一下在看到效果后捕获的这个示例(它不会运行,但你明白了):

  DB<5> l 3136-3164
3136    sub manage_key($$$)
3137    {
3138:       my ($ks, $ID, $params) = @_;
3139:       my $me = 'manage_key';
3140:       my $result = 1;
3141:       my ($key_type, $instance) = split_ID($ID);
3142
3143:       $ks->clear_errors();
3144:b      if (defined(my $PIN = $params->{(PK_PIN)})) {
3145:           if (my $container = $ks->get_container($key_type, $instance, $PIN)) {
3146                #...
3147            } else {
3148:               my $err = ks_error_message($ks, ': ');
3149
3150:               verbose(-1, "failed to get key $ID$err");
3151:               show_ks_errors($ks);
3152:               $result = 0;
3153            }
3154:       } elsif (my $container = $ks->_get_container($key_type, $instance)) {
3155            #...
3156        } else {
3157:           my $err = ks_error_message($ks, ': ');
3158
3159:           verbose(-1, "failed to get key $ID$err");
3160:           show_ks_errors($ks);
3161:           $result = 0;
3162        }
3163==>     return $result;
3164    }

调试器会话(未设置

$params->{(PK_PIN)}
)是:

main::manage_key(./keytool.pl:3144):        if (defined(my $PIN = $params->{(PK_PIN)})) {
  DB<3> n
main::manage_key(./keytool.pl:3163):        return $result;
  DB<3> x $result
0  1
#...
  DB<6> x $params->{(PK_PIN)}
0  undef

所以我的期望是

n
命令将再次在第 3154 行停止,其中
elsif
测试应该发生。但相反,该部分(实际执行的部分)已被跳过,直到复合语句结束。

我想知道:Perl 调试器会这样做,还是 Perl 编译器会优化“空”

if
,即使条件有副作用?

我应该提到:x86-64 (SLES12 SP5) 上的 Perl 5.18.2

perl debugging optimization
1个回答
0
投票

使用

s
,而不是
n
step 进入调试器中的子例程调用。

use warnings;
use strict;
use feature qw{ say };

sub check {
    say "SUB";
    return time
}

my %H = (ZERO => 0);

if (defined(my $pin = $H{MISSING})) {
    say "IF";
} elsif (my $pop = $H{ZERO} * check()) {
    say "ELSIF";
} else {
    say "ELSE";
}
say "Done.";

您可以看到子程序仍在运行(由于副作用),但它没有显示在调试器中。

使用

n

perl -d 2.pl

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

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

main::(2.pl:11):    my %H = (ZERO => 0);
  DB<1> n
main::(2.pl:13):    if (defined(my $pin = $H{MISSING})) {
  DB<1> n
SUB
main::(2.pl:18):        say "ELSE";
  DB<1> n
ELSE
main::(2.pl:20):    say "Done.";

使用

s

main::(2.pl:11):    my %H = (ZERO => 0);
  DB<1> s
main::(2.pl:13):    if (defined(my $pin = $H{MISSING})) {
  DB<1> s
main::check(2.pl:7):        say "SUB";
main::check(2.pl:8):        return time
  DB<1> s
SUB
main::check(2.pl:9):    }
  DB<1> s
main::(2.pl:18):        say "ELSE";
  DB<1> s
ELSE
main::(2.pl:20):    say "Done.";
  DB<1> s
Done.
© www.soinside.com 2019 - 2024. All rights reserved.