Image :: ValidJpeg和内存中文件的分段错误

时间:2013-09-16 19:55:26

标签: image perl segmentation-fault jpeg file-handling

我遇到了错误

  

细分错误

使用以下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 ()

2 个答案:

答案 0 :(得分:4)

查看Image::ValidJpeg的实现,特别是在valid_jpeg.c,模块似乎只能处理“普通”文件句柄,因为它只使用FILE*。内存中的文件句柄无法映射到FILE*,因此无法正常工作。

有关于内存文件句柄和XS的相关StackOverflow article

最好的解决方案可能是在这里使用纯perl模块,或者仅仅为了验证而误用ImagerImage::Magick,或者使用Image::ValidJpeg的临时文件。不要忘记错误报告。

答案 1 :(得分:1)

正如amon所说,当发生这种情况时,它表示底层实现中的错误,而不是(仅)脚本。即使您滥用了模块,模块的XS代码也会让您的错误变成内存访问冲突 - 这是编写XS的人的错误。你不能用普通的perl来做。

如果您熟悉gdb(gnu调试器),这将更容易找到罪魁祸首:

gdb perl 

将perl加载到调试器中。在提示符处:

run ./myscript.pl

显然“./myscript.pl”应该是您想要运行的脚本的真实路径。该脚本将启动,虽然比正常情况慢得多,并允许您进行任何交互。当seg故障发生时,gdb将暂停并指示这一点。此时输入bt并保存输出。

您可以在错误报告中包含此回溯。如果您不确定哪个模块有问题,请发布回溯,并且有人应该能够告诉您。