4

コードがセグメンテーション違反を引き起こさない 2 つのケースがあります。

  1. 少なくとも 1 つの場所でSmart::Commentsを使用する場合
  2. デバッガーを実行します。

私はそれをこの呼び出しまで追跡しました:

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

whereeach_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;
}
  • each_pair をList::MoreUtils::natatimeに置き換えるだけでよいことがわかりました(ただし、これにはいくつかのバグがあると聞きました)。彼らは最近、このモジュールを私たちの環境に許可しました。セグメンテーション違反 -- またはデバッグ セグメンテーション違反による他の Perl プログラマー。

私はこれで少し時間を失いました。


編集

私はこの関数を使用する他のモジュールを持っています.andを使用できると期待する人$a$bいます.また、同じモジュール内の別の場所で別のリストのために機能しています. この呼び出しを変更することも、このファイルに対して変更することもできますが、それを正常に使用するすべての場所で変更することは、おそらく、この遅い時間に許可されているよりも多くの変更です。

4

5 に答える 5

4

一般的なデバッグ手順に関しては、いつでも Perl インタープリターを の下で実行できますgdb。教育的なものを見る可能性は必ずしもそれほど高くはありませんが、私はそれを数回やったことがあります。

于 2009-07-23T16:36:01.643 に答える
4

Perl では、セグメンテーション違反は非常にまれです。最後に会ったのはいつか思い出せない。

デバッガーは十分に侵入的であり、コードがそこで異なる動作をすることは特に驚くべきことではありませんが、確かにイライラします. (私たち全員が知っているように)悪Smart::Commentsであるソースフィルターを使用します。Smart::Comments のソースを調べてみると、通常はXS実装を使用する List::Util が使用されていることがわかります。それが問題を「修正」する可能性があります。を直接使用してみてください。これでは何も解決しませんが、ソース フィルターの不確実性を方程式から除外できる可能性があります。List::UtilList::UtilSmart::Comments

残念ながら、あなたの問題はコード自体ではなく、さまざまなもの間の予期しない相互作用にあるようです。Perl でセグメンテーション違反を直接トリガーすることはできません。ルートは、perl 自体または XS コードのいずれかにある必要があります。小さくても完全なサンプルに減らすことができれば、他の人が問題を再現して特定できる可能性があります。

于 2009-07-23T17:35:57.700 に答える
3

私はカオスの懸念を機能に反響させeach_pairます。次の実装を使用するとどうなりますか?

#!/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__
于 2009-07-23T15:57:07.150 に答える
3

セグメンテーション違反は、XS にバインドされた C で記述された外部モジュールのメモリ バグから発生する可能性があります。

エラーを見つけるために、 valgrindでスクリプトを実行することをお勧めします。

valgrind perl ./yourfaultyscript.pl
于 2009-07-24T16:39:05.287 に答える
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は、セグフォールトの状況ではすぐに疑わしいように見えます。

それをすべて無効にするとどうなりますか?

于 2009-07-23T15:20:54.227 に答える