2012年6月3日日曜日

ImageMagick セグメンテーション違反です (Segmentation fault)

構築チームから ImageMagick が上手く入らないとの連絡を受ける。我が運用チームはインストール後の引き継ぎになるので関係ないと言えば関係ないのだが、少々時間的余裕があったので個人的学習を兼ねて検証してみることにした。

OSは RedHat Enterprize Linux 5.2(以下RHEL)、原則として rpm によるパッケージ管理なんだが、ユーザから要望があり ImageMagick を入れることになったらしい。どうやら rpm では用意されておらず、ソースからコンパイル→インストールが必要になったらしい。RHEL 5.2 は持っていないので、互換をうたう CentOS 5.2 で試すことにした。

OSのパッチはセキュリティパッチのみ適用、その他は当てていない。記憶に頼ると、apache と OpenSSLのパッチぐらいしか当てていないと思った。構築チームの RHEL 5.4 では問題が出ないってことなので、次のいずれかなってことで仮説を立ててみる。

  1. gcc のリビジョンが古い
  2. ライブラリのリビジョンが古い
  3. カーネルのリビジョンが古い
  4. gcc のコンパイルオプションを変えてみる。(最適化関係だな)

あたりか。yum update ですべて更新して、再コンパイルしてみるのが一番だが、さすがに当たるパッチの数が多すぎる気がする。1. の gcc の update で解決すると楽なんだが。


エラーが出るかの検証

CentOS なので、もしかしたら ImageMagick がインストール済みかもしれないので確認。

# rpm -qa | grep -i imagemagick
ImageMagick-6.2.8.0-4.el5_1.1

予想通り入っていたので、サクッとアンインストールする。

# rpm -e ImageMagick-6.2.8.0-4.el5_1.1

次はエラーが出るか、手順書に従ってコンパイル→インストールを行う。ソースの入手→展開→コンパイル→インストールの順で作業を実施。

まずは ImageMagick から。
#  tar xfz ImageMagick.tar.gz
#  cd ImageMagick-6.7.7-5
# ./configure; make; make install
# convert --version
Version: ImageMagick 6.7.7-5 2012-06-03 Q16 http://www.imagemagick.org
Copyright: Copyright (C) 1999-2012 ImageMagick Studio LLC
Features: OpenMP

問題は特になくインストールできたようだ。次に PerlMagick をコンパイル→インストール and コンパイルの前に Makefile.PL の修正。

# cd PerlMagick
# vi Makefile.PL
修正前:
my $LIBS_magick = '-L../magick/.libs -lMagickCore -lperl -lm';
修正後:
my $LIBS_magick = '-L/usr/lib//perl5/5.8.8/i386-linux-thread-multi/CORE -L../magick/.libs -lMagickCore -lperl -lm';

# perl Makefile.PL;  make; make install

/usr/local/lib 配下が検索できるよう /etc/ld.so.conf の修正と ldconfig の実施
# vi /etc/ld.so.conf
修正前:
include ld.so.conf.d/*.conf
修正後:
/usr/local/lib
include ld.so.conf.d/*.conf

# ldconfig

perl スクリプトを動かして動作のチェック。バージョンが表示されれば ok 何だが... orz
# perl -MImage::Magick -le 'print $Image::Magick::VERSION'
6.77
セグメンテーション違反です


仮説 1. の検証

やぱーり動きませんな。では gcc のリビジョンアップからいってみます。

# yum update gcc

(中略)

(1/9): libgfortran-4.1.2- 100% |=========================| 232 kB    00:02
(2/9): libgomp-4.4.6-3.el 100% |=========================|  72 kB    00:00
(3/9): gcc-4.1.2-52.el5_8 100% |=========================| 5.2 MB    01:33
(4/9): libstdc++-4.1.2-52 100% |=========================| 363 kB    00:13
(5/9): libgcc-4.1.2-52.el 100% |=========================|  97 kB    00:01
(6/9): cpp-4.1.2-52.el5_8 100% |=========================| 1.8 MB    00:29
http://mirror.nus.edu.sg/centos/5.8/updates/i386/RPMS/cpp-4.1.2-52.el5_8.1.i386.rpm: [Errno -1] Package does not match intended download
Trying other mirror.
(6/9): cpp-4.1.2-52.el5_8 100% |=========================| 2.7 MB    00:01
(7/9): libstdc++-devel-4. 100% |=========================| 2.8 MB    00:06
(8/9): gcc-c++-4.1.2-52.e 100% |=========================| 3.4 MB    00:06
(9/9): gcc-gfortran-4.1.2 100% |=========================| 3.1 MB    00:07
warning: rpmts_HdrFromFdno: Header V3 DSA signature: NOKEY, key ID e8562897
Importing GPG key 0xE8562897 "CentOS-5 Key (CentOS 5 Official Signing Key) <centos-5-key@centos.org>" from http://mirror.centos.org/centos/RPM-GPG-KEY-CentOS-5
Is this ok [y/N]: y
Running rpm_check_debug
Running Transaction Test
Finished Transaction Test
Transaction Test Succeeded
Running Transaction
  Updating  : libgcc                       ####################### [ 1/18]
  Updating  : libstdc++                    ####################### [ 2/18]
  Updating  : libgfortran                  ####################### [ 3/18]
  Updating  : libgomp                      ####################### [ 4/18]
  Updating  : libstdc++-devel              ####################### [ 5/18]
  Updating  : cpp                          ####################### [ 6/18]
  Updating  : gcc                          ####################### [ 7/18]
  Updating  : gcc-gfortran                 ####################### [ 8/18]
  Updating  : gcc-c++                      ####################### [ 9/18]
  Cleanup   : gcc-gfortran                 ####################### [10/18]
  Cleanup   : gcc-c++                      ####################### [11/18]
  Cleanup   : libstdc++-devel              ####################### [12/18]
  Cleanup   : cpp                          ####################### [13/18]
  Cleanup   : libgcc                       ####################### [14/18]
  Cleanup   : libstdc++                    ####################### [15/18]
  Cleanup   : gcc                          ####################### [16/18]
  Cleanup   : libgomp                      ####################### [17/18]
  Cleanup   : libgfortran                  ####################### [18/18]

Updated: cpp.i386 0:4.1.2-52.el5_8.1 gcc.i386 0:4.1.2-52.el5_8.1 libgcc.i386 0:4.1.2-52.el5_8.1 libgfortran.i386 0:4.1.2-52.el5_8.1 libgomp.i386 0:4.4.6-3.el5.1 libstdc++.i386 0:4.1.2-52.el5_8.1 libstdc++-devel.i386 0:4.1.2-52.el5_8.1
Dependency Updated: gcc-c++.i386 0:4.1.2-52.el5_8.1 gcc-gfortran.i386 0:4.1.2-52.el5_8.1
Complete!

ではやり直し。ImageMagick から
# make clean; make; make install
# convert –version

さきほども問題が無かったんで、鬼門の PerlMagick のやり直し。
# make clean;  perl Makefile.PL;  make; make install

さて、これで解決してくれるといいのだが。
# perl -MImage::Magick -le 'print $Image::Magick::VERSION'
6.77
セグメンテーション違反です

がーん、解決せずですね。


仮説 2. & 3. の検証

ライブラリはどれが該当するかわからんので、全て最新版にすることにした。
# yum update

凄くたくさん更新がかかる... その数 1,000個以上。update の状況を貼ろうと思ったが、とんでもない行数なのであきらめた... しかも、我が家のWiMAX環境ではずいぶん時間がかかる。ダウンロード→更新が終わるまで 2時間ぐらいかかったんじゃないかな?  しばらく放っておいたら終わっていた。

で、結果ですが ok でした。
とはいえ、もの凄い数の更新がかかるんで、お客さんに提案しても ok が出ないと思うし、動作保証云々を問われると辛いものがある。


仮説 4. の検証

gcc のオプションを考えてみる。convert を動かしたときに表示される "Features: OpenMP" が気になるので、ちょっと調べてみることにする。 グーグル先生によると、「高負荷になる」とか「切った方がいい」って書き込み多いので、disable にして検証を行ってみることにした。

まずは ImageMagick
# make distclean; ./configure --disable-openmp; make; make install
# convert --version
Version: ImageMagick 6.7.7-5 2012-06-03 Q16 http://www.imagemagick.org
Copyright: Copyright (C) 1999-2012 ImageMagick Studio LLC
Features:

disable にしたので OpenMP が消えていますな。

全て最新版にすれば解決するのは分かっているのだが、コンパイルオプションで変わらないか期待を込め PerlMagick のやり直し。作業前に Makefile.PL の編集を忘れずに。
# perl Makefile.PL;  make; make install
# perl -MImage::Magick -le 'print $Image::Magick::VERSION'
6.77

やったー! 正常にバージョン表示がされた。お客さんへはコンパイルオプションの変更で提案だな。自分的には gcc のリビジョンアップで解決すると思ったんだけど、ちょっと読みが甘かったですね。

0 件のコメント:

コメントを投稿