3

I am experiencing an error

Segmentation fault

using the following Perl code:

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";
}

Why such error? Is my code incorrect?


Debug information:

(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 ()
Flow
  • 23,572
  • 15
  • 99
  • 156
Ωmega
  • 42,614
  • 34
  • 134
  • 203
  • 3
    A good library shouldn't segfault even if the user code was incorrect. Find a minimal testcase where this problem occurs, and submit a bug report. Hunch: could this have to do with in-memory files? – amon Sep 16 '13 at 20:07
  • @amon - Yes, I experience this error only when in-memory file handling is used... – Ωmega Sep 16 '13 at 20:10
  • @amon - It seems that some other user reading this post has already reported the issue to author and update has been released... – Ωmega Sep 18 '13 at 12:42

2 Answers2

4

Looking at the implementation of Image::ValidJpeg, especially at valid_jpeg.c, it seems that the module can deal only with "normal" file handles, as it uses only FILE*. An in-memory file handle cannot be mapped to FILE*, so this cannot work.

There's a related StackOverflow article about in-memory file handles and XS.

Probably the best solution is to use a pure-perl module here, or misuse Imager or Image::Magick just for validation, or to use temporary files with Image::ValidJpeg. And don't forget the bug report.

Community
  • 1
  • 1
Slaven Rezic
  • 4,571
  • 14
  • 12
1

As amon says, when this happens it indicates a bug in the underlying implementation, not (just) the script. Even if you have misused a module, the module's XS code has allowed your mistake to turn into a memory access violation -- which is a mistake by whoever wrote the XS. You can't do it in plain perl.

If you are familiar with gdb (gnu debugger), this will make it easier to locate the culprit:

gdb perl 

Loads perl into the debugger. At the prompt:

run ./myscript.pl

Obviously "./myscript.pl" should be the real path to the script you want run. The script will start, albeit much slower than normal, and allow you to do whatever interaction. When the seg fault happens, gdb will pause and indicate this. At that point enter bt and save the output.

You can include this backtrace in your bug report. If you are not sure which module is at fault, post the backtrace and someone should be able to tell you.

CodeClown42
  • 11,194
  • 1
  • 32
  • 67
  • @Ωmega : What about after `bt`? There may be a lot of `?????` in the output, but paste all of it in your OP. – CodeClown42 Sep 16 '13 at 20:31
  • :/ You are saying after that message, at the `(gdb)` prompt, you entered `bt` and gdb said *nothing*? Anyway, looks like Slaven Rezic is ahead of us on this one -- that jibes with the `feof` issue. – CodeClown42 Sep 16 '13 at 20:53