3

エラーが発生しています

セグメンテーション違反

次の Perl コードを使用します。

use LWP::UserAgent;
use HTTP::Request;
use HTTP::Response;
use Image::ValidJpeg;

my $url = ...
my $ua = LWP::UserAgent->new(agent => '');
my $request = HTTP::Request->new(GET => $url);
my $response = $ua->request($request);

if (($response->is_success) &&
    ($response->code == 200) && 
    ($response->header('Content-Type') eq 'image/jpeg'))
{
  my $content = $response->decoded_content;
  open(my $img, '<', \$content);
  my $check = Image::ValidJpeg::check_all($img);
  print "$check\n";
}

なぜそのようなエラーですか?私のコードは間違っていますか?


デバッグ情報:

(gdb) run /home/test.pl 
Starting program: /home/test.pl
[Thread debugging using libthread_db enabled]
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff683a7e0 in feof () from /lib64/libc.so.6

(gdb) bt
#0  0x00007ffff683a7e0 in feof () from /lib64/libc.so.6
#1  0x00007ffff5d4af82 in valid_jpeg (fh=0x0, seek_over_entropy=0 '\000') at valid_jpeg.c:50
#2  0x00007ffff5d4a94b in XS_Image__ValidJpeg_check_all (my_perl=<value optimized out>, cv=<value optimized out>) at ValidJpeg.c:138
#3  0x00007ffff7b18805 in Perl_pp_entersub () from /usr/lib64/perl5/CORE/libperl.so
#4  0x00007ffff7b16af6 in Perl_runops_standard () from /usr/lib64/perl5/CORE/libperl.so
#5  0x00007ffff7abf0d8 in perl_run () from /usr/lib64/perl5/CORE/libperl.so
#6  0x0000000000400cac in main ()
4

2 に答える 2

4

Image::ValidJpegの実装、特にの実装を見るとvalid_jpeg.c、モジュールは のみを使用するため、「通常の」ファイル ハンドルのみを処理できるようですFILE*。メモリ内のファイル ハンドルは にマップできないFILE*ため、これは機能しません。

インメモリ ファイル ハンドルと XSに関するStackOverflowの関連記事があります。

おそらく最良の解決策は、ここで純粋な perl モジュールを使用するか、誤用ImagerするかImage::Magick、検証のためだけに使用するか、Image::ValidJpeg. バグレポートもお忘れなく。

于 2013-09-16T20:40:47.977 に答える
1

amon が言うように、これが発生した場合は、(単なる) スクリプトではなく、基盤となる実装にバグがあることを示しています。モジュールを誤って使用したとしても、そのモジュールの XS コードによって、その間違いがメモリ アクセス違反に変わる可能性があります。これは、XS を書いた人による間違いです。普通のperlではできません。

gdb (gnu デバッガー) に精通している場合は、これにより原因を特定しやすくなります。

gdb perl 

perl をデバッガーにロードします。プロンプトで:

run ./myscript.pl

明らかに、「./myscript.pl」は、実行するスクリプトへの実際のパスである必要があります。スクリプトは、通常よりもはるかに遅く開始されますが、あらゆる対話を行うことができます。セグメント障害が発生すると、gdb は一時停止し、これを示します。その時点でbt、出力を入力して保存します。

このバックトレースをバグ レポートに含めることができます。どのモジュールに問題があるかわからない場合は、バックトレースを投稿してください。誰かが教えてくれるはずです。

于 2013-09-16T20:23:30.190 に答える