在Perl中调试分段错误有哪些好的方法或步骤?

时间:2009-07-23 15:14:47

标签: perl debugging segmentation-fault

有两种情况我的代码不会导致segmentation fault

  1. 当我在至少一个地方使用Smart::Comments
  2. 运行调试器。
  3. 我已经跟踪了这个电话:

    $action->{breakdown} 
        = join( ' '
              ,  each_pair { 
                    my ( $name, $length ) = @_;
                    return "x$length" if $name eq 'FILLER';
                    push @$field_list_ref, $name;
                    return "A$length";
    
                } @$field_def_ref
        );
    

    其中each_pair在另一个模块中定义为:

    sub each_pair (&@) { 
        my $block   = shift;
        return unless @_;
        my $caller  = caller();
        my $aref    = qualify( 'a', $caller );
        my $bref    = qualify( 'b', $caller );
        my @results;
        my $pairs   = 0;
    
        for ( my $index = 0; $index < $#_; $index += 2 ) { 
            $pairs++;
            my @pair                 = @_[$index..($index+1)];
            no strict 'refs';
            local ( $$aref, $$bref ) = @pair;
            push @results, $block->( @pair );
        }
        return wantarray || $pairs != 1 ? @results : shift @results;
    }
    
    • 现在我知道我可以用List::MoreUtils::natatime替换each_pair(虽然我听说有一些错误),但他们最近才允许这个模块进入我们的环境,我仍然对这个调用的原因感兴趣导致分段错误 - 或者由于调试分段错误导致的其他Perl程序员。

    我已经失去了一点时间。

    <小时/>

    修改

    我有其他模块使用此功能,有些人希望能够使用$a$b,也可以在同一模块的其他地方使用另一个列表。我可以更改它的这个调用,我可以为这个文件更改它,但是为每个成功使用它的地方更改它可能比我在这个晚些时候允许做的更多变化。

5 个答案:

答案 0 :(得分:4)

对于一般调试步骤,您始终可以在gdb下运行Perl解释器。看到任何有教育意义的机会并不一定那么热,但我已经做了几次,甚至可能有一次帮助。

答案 1 :(得分:4)

Perl中的分段错误极为罕见。我记不起上次遇到的时候了。

调试器具有足够的侵入性,代码在那里表现不同并不特别令人惊讶,尽管它确实令人沮丧。 Smart::Comments使用源过滤器(我们都知道) evil 。进入Smart :: Comments的源代码,我发现它使用了List :: Util,它通常使用XS实现。 List::Util可能会“修复”您的问题。请尝试直接使用List::Util,而不是Smart::Comments。这不会解决任何问题,但可能会将源滤波器的不确定性排除在等式之外。

不幸的是,你的问题似乎不是代码本身,而是不同事物之间的意外交互。您无法直接在Perl中触发分段错误。 root必须是perl本身或XS代码。如果您可以将其减少到一个小而完整的样本,其他人可能能够重现并隔离问题。

答案 2 :(得分:3)

我将使用each_pair函数回显chaos' concern。如果您使用以下实现会发生什么?

#!/usr/bin/perl

use strict;
use warnings;

use Data::Dumper;

sub each_pair(&@);

my $field_def_ref  = [ qw( FILLER 5 NOTFILLER 6 ) ];
my $field_list_ref;

print join(' ' => each_pair {
    my ($name, $length) = @_;
    return "x$length" if $name eq 'FILLER';
    push @$field_list_ref, $name;
    return "A$length";
} @$field_def_ref ), "\n";

print Dumper $field_list_ref;

sub each_pair( &@ ) {
    my $code = shift;
    my @results;

    for my $i ( 0 .. $#_/2 ) {
        push @results, $code->( shift, shift );
    }

    return @results;
}
__END__

答案 3 :(得分:3)

Segfaults可能来自与XS绑定的C语言外部模块中的内存错误。

我建议您在valgrind中运行脚本以发现错误:

valgrind perl ./yourfaultyscript.pl

答案 4 :(得分:2)

好吧,我无法弄清楚你each_pair()这样做的原因:

my $caller  = caller();
my $aref    = qualify( 'a', $caller );
my $bref    = qualify( 'b', $caller );

或者这个:

    no strict 'refs';
    local ( $$aref, $$bref ) = @pair;

并且引用需要您关闭strict refs的操作似乎在分段情况下立即被怀疑。

如果禁用所有这些,会发生什么?