代码在调试步骤期间工作,但在运行到断点时不工作

时间:2014-05-22 13:09:43

标签: perl debugging

好的,所以我很困惑。我有一些代码基本上读入一个ftp日志文件并将其分成流。我似乎有不一致的输出,但取决于我是否通过代码执行或只是让它执行或从断点到断点。如果我通过它执行它正确执行并且正确创建我拥有的哈希数组。但是,如果我从断点到断点运行它,它似乎错误地创建了哈希和数组。我认为它的调试方式无关紧要,它仍然会出现相同的输出。我使用Eclipse作为IDE,使用EPIC作为调试器。

以下是输入的示例:

Dec  1 23:59:57 ftp1 sshd[5389]: Accepted publickey for test1 from 192.168.0.1 port 18432 ssh2
Dec  1 23:59:57 ftp1 sftp-server[5392]: Starting sftp-server logging for user test1.
Dec  1 23:59:57 ftp1 sftp-server[5392]: bad value 0 for SFTP_UMASK, turning umask control off.
Dec  1 23:59:57 ftp1 sftp-server[5392]: realpath .
Dec  1 23:59:57 ftp1 sftp-server[5392]: realpath /prod/data/006
Dec  1 23:59:57 ftp1 sftp-server[5392]: opendir /prod/data/006
Dec  1 23:59:59 ftp1 sshd[5394]: Accepted publickey for test2 from 192.168.0.1 port 18433 ssh2
Dec  1 23:59:59 ftp1 sftp-server[5397]: Starting sftp-server logging for user test2.
Dec  1 23:59:59 ftp1 sftp-server[5397]: bad value 0 for SFTP_UMASK, turning umask control off.
Dec  1 23:59:59 ftp1 sftp-server[5397]: realpath .
Dec  2 00:00:00 ftp1 sftp-server[5397]: realpath /prod/data/228
Dec  2 00:00:00 ftp1 sftp-server[5397]: opendir /prod/data/228

这是我通过代码执行时得到的输出结果:

$VAR1 = {
          '5397' => {
                      '23:5' => [
                                  'Dec  1 23:59:59 ftp1 sshd[5394]: Accepted publickey for test1 from 192.168.0.1 port 18433 ssh2
',
                                  'Dec  1 23:59:59 ftp1 sftp-server[5397]: Starting sftp-server logging for user test2.
',
                                  'Dec  1 23:59:59 ftp1 sftp-server[5397]: bad value 0 for SFTP_UMASK, turning umask control off.
',
                                  'Dec  1 23:59:59 ftp1 sftp-server[5397]: realpath .
',
                                  'Dec  2 00:00:00 ftp1 sftp-server[5397]: realpath /prod/data/228
',
                                  'Dec  2 00:00:00 ftp1 sftp-server[5397]: opendir /prod/data/228
'
                                ]
                    },

以下是我使用断点或直接运行代码时的情况,因为您会看到它创建了一个额外的哈希' ':

$VAR1 = {
          '5397' => {
                      '' => [
                              'Dec  2 00:00:00 ftp1 sftp-server[5397]: opendir /prod/data/228
'
                            ],
                      '23:5' => [
                                  'Dec  1 23:59:59 ftp1 sshd[5394]: Accepted publickey for test2 from 192.168.0.1 port 18433 ssh2
',
                                  'Dec  1 23:59:59 sslmftp1 sftp-server[5397]: Starting sftp-server logging for user test2.
',
                                  'Dec  1 23:59:59 sslmftp1 sftp-server[5397]: bad value 0 for SFTP_UMASK, turning umask control off.
',
                                  'Dec  1 23:59:59 sslmftp1 sftp-server[5397]: realpath .
',
                                  'Dec  2 00:00:00 sslmftp1 sftp-server[5397]: realpath /prod/data/228
'
                                ]
                    },

以下是相关代码段:

#----------------------
    # Search by IP address
    #----------------------
    sub ip(){
        my $username;
        my $tmpline;
        my %pids;
        my $hhmm;
        my $tmpuser;
        my %finished; 
        my @error;

        my $infile = $searchfile;
        open (INPUT, $infile) or die "Couldn't read $infile.\n";

        if ($STYPE == "ip" && ($SEARCH =~ m/^([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})/)) {
            # pull username and times from matched lines
            while(my $line = <INPUT>) {
                if($line =~ m/(password|publickey)\sfor\s(\w+)\sfrom\s(([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3}))/){
                    my $tmpIP = $3;
                    $username = $2;
                    if ($tmpIP =~ $SEARCH){
                        $tmpline = $line;
                    }
                }
                if ($tmpline){
                    if($line =~ m/(Starting\ssftp-server\slogging\sfor\suser\s(\w+))/){
                        $tmpuser = $2;
                        if ($tmpuser =~ $username){
                            if ($line =~ /sftp-server\[(.*?)\]/){   
                                my $mPID = $1;
                                if($line =~ /(\d{2})\:(\d)/){
                                    my $time = $1 . ":" . $2;
                                    $pids{$mPID} = $time;
                                    $pids{$mPID} = {$pids{$mPID} => []};
                                    $finished{$mPID} = 0;
                                    push @{$pids{$mPID}{$time}}, $tmpline;
                                    push @{$pids{$mPID}{$time}}, $line;
                                }
                            }
                        }
                    } else {
                        if($line =~ /sftp-server\[(.*?)\]/){
                            my $mPID = $1;
                            if(exists $pids{$mPID}){
                                if($line =~ /(\d{2})\:(\d)/){
                                    my $time = $1 . ":" . $2;
                                    if((exists $pids{$mPID}{$time})&&($finished{$mPID} != 1)){
                                        push @{$pids{$mPID}{$time}}, $line;

                                    } else {
                                        if($finished{$mPID} != 1){
                                            if(exists $pids{$mPID}){
                                                my $mtime = each $pids{$mPID};
                                                push @{$pids{$mPID}{$mtime}}, $line;
                                                if($line =~ m/(sftp-server\sfinished)/){
                                                    $finished{$mPID} = 1;
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }else {
                            if($line =~ /$SEARCH/){
                                push @error, $line if not ($line =~ /Accepted/);
                            }
                        }
                    } 

                } 
                #print $line . '\n';        
            }

        } else {
            print "I'm sorry, this is not a valid IP address, please try again.\n";
        }

        close (INPUT);

我很感激你能提供的任何帮助,我现在完全被困住了。

谢谢, 戴夫

1 个答案:

答案 0 :(得分:1)

正如Kaoru所指出的,空哈希密钥是由未初始化的值引起的。这个未初始化的值由第93行生成:

  

我的$ mtime =每个$ pids {$ mPID};

你对每种方法的使用都有些不同寻常。 Perl的each函数通常用于迭代数组或散列。在您的情况下,第一个调用返回您感兴趣的值(第一个键),但第二个调用返回undef,因为没有在哈希中添加或删除键,keys或调用了values个函数。通过在第93行之后添加此代码段,您可以看到这确实是个问题:

if($mtime){ print "mtime defined\n"; }else{ print "mtime undefined\n"; my $test = each $pids{$mPID};<br> print "non-empty again\n" if $test;<br> }

我从未使用过EPIC,但我只能假设它在检查值时会以某种方式重置each的迭代器。这个理论与您在逐行步进和断点之间执行之间观察到的差异是一致的。在更简单的代码片段中重现这种副作用并将其提交给EPIC的开发人员进行审核可能会很有趣。这不是我期望从调试器中产生的那种副作用,很可能是一个错误。