2010/02/22(月)SpeedyCGI で ImageMagick が動かない
Webアプリ開発中に ImageMagick(perlmagick)が SpeedyCGI 環境でまともに動かない不具合に当たりました。
問題の詳細
- Image::Magick をロードして何かしら処理を行うルーチンを SpeedyCGI で実行する時、2回目以降のキャッシュされた状態で不具合が起こる*1。
- 問題確認環境
- Perl 5.8.8 + SpeedyCGI 2.22
- ImageMagick 6.3.7 および 6.5.9
この問題は FastCGI や mod_perl2 では起きません。
問題の症状
スクリプト
#!/usr/bin/speedy use Image::Magick(); print "Content-Type: text/plain\n\n"; print "Image::Magick Version $Image::Magick::VERSION \n"; my $image = Image::Magick->new; $image->Read( 'x.png' );
実行結果。
~$ test.pl Image::Magick Version 6.3.7 ~$ test.pl Segmentation fault
~$ test.pl Image::Magick Version 6.5.9 ~$ test.pl Segmentation fault
問題の原因
不明。
問題の解決法
#!/usr/bin/speedy delete $INC{'Image/Magick.pm'}; require Image::Magick; print "Content-Type: text/plain\n\n"; print "Image::Magick Version $Image::Magick::VERSION \n"; my $image = Image::Magick->new; $image->Read( 'x.png' );
requireで毎回確実にロードさせる細工をすることで問題は起こらなくなりました。Image::Magickモジュールがキャッシュされませんが、evalを飛び越えてSpeedyCGIごと落ちるよりはマシということで……。
まとめ
gccの(ライブラリlibgomp )バグのようです。gcc 4.3より前のVersion(4.2以下)で、amd64環境の時起こる模様。
gcc 4.4でも起きたので関係ないようです。4年経っても解決されてないとは思わなかった(汗)
メモ
256色png(8bitカラーパレット)で保存する方法。
$image->Read( 'x.png' ); $image->Resize(width=>133, height=>100); $image->Quantize(colorspace=>'RGB',colors=>256); $image->Set(depth => 8); $image->Write( 'y.png' );