PHP5.3 + ImagickでSegmentation faultが出たときの対処法

CentOS 6.3, PHP5.3な環境で、Imagickを使ったらSegmentation faultが出ました。
何とか解決できたので対処法を紹介します。

対処法

対処法その1
setResourceLimit()を使ってスレッド数を1に制限する。
$img = new Imagick();
$img->setResourceLimit(6, 1);
// 6はTHREAD_LIMITを意味するマジックナンバーだそうです。
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=652960
対処法その2
環境変数MAGICK_THREAD_LIMITを1にする。 例えばコマンドラインから実行するなら、
$ export MAGICK_THREAD_LIMIT=1 ;  php test.php
https://bugs.php.net/bug.php?id=59692

解決に至るまでの経緯

実はめちゃ苦労しました。
誰かの役に立つかもしれないので経緯を晒します。
Segmentation faultが出たらgdbを使う

PHPでのデバッグ方法 (Yahoo! JAPAN Tech Blog)
こちらの記事で、gdbというツールを使えばSegmentation faultの原因箇所を特定できることを知りました。

さっそくgdbを起動!
$ gdb
-bash: gdb: command not found
うむむ、入ってないのか。
しょうがないのでyumでインストールします。
$ sudo yum install  gdb
インストールできました!
さっそくgdbを起動!
$ gdb
起動した!
Yahoo!さんの説明どおりにやってみる。
(gdb) file php
Reading symbols from /usr/bin/php...(no debugging symbols found)...done.
Missing separate debuginfos, use: debuginfo-install php-cli-5.3.3-14.el6_3.x86_64
なにやら警告が出ますが、無視して次へ。
(gdb) run tes.php
Starting program: /usr/bin/php test.php
[Thread debugging using libthread_db enabled]

#!/usr/bin/php
1..7
# test of Imagick
[New Thread 0x7fffe5523700 (LWP 10711)]
# Looks like you planned 7 tests but only ran 0.

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7fffe5523700 (LWP 10711)]
0x00007ffff0234bc2 in ?? () from /usr/lib64/libgomp.so.1
え、情報これだけ?
これじゃ情報が少なすぎるような・・・
ここで冒頭の警告に着目してみました。
use: debuginfo-install php-cli-5.3.3-14.el6_3.x86_64
デバグ用に何かをインストールしろということなのでしょうか。

調べてみたら、"debuginfo-install"というのは"yum-utils"パッケージに含まれていることを知りました。
さっそくインストール。
$ sudo yum install -y yum-utils
無事インストールできました!

次に、debuginfo-installを使って指示通りにデバグ情報をインストール。
# debuginfo-install php-cli-5.3.3-14.el6_3.x86_64
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
 * base: ftp.riken.jp
 * extras: ftp.riken.jp
 * updates: ftp.riken.jp
Checking for new repos for mirrors
Could not find debuginfo for main pkg: php-cli-5.3.3-14.el6_3.x86_64
Could not find debuginfo pkg for dependency package bzip2-libs-1.0.5-7.el6_0.x86_64
Could not find debuginfo pkg for dependency package glibc-2.12-1.80.el6_3.3.x86_64

 [中略]

No debuginfo packages available to install
うむむ・・インストールできません。

色々調べてみると、レポジトリの指定の仕方に問題があったようです。

再度チャレンジ。
# debuginfo-install --nogpgcheck --enablerepo debug php-cli
うまく行きました!

そしてまたgdbでデバグ。
(gdb) run test.t
Starting program: /usr/bin/php test.t
[Thread debugging using libthread_db enabled]

#!/usr/bin/php
1..7
# test of Sen_Mojiire
[New Thread 0x7fffe5523700 (LWP 10805)]
# Looks like you planned 7 tests but only ran 0.

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7fffe5523700 (LWP 10805)]
0x00007ffff0234bc2 in ?? ()
Missing separate debuginfos, use: debuginfo-install ImageMagick-6.5.4.7-6.el6_2.x86_64 cyrus-sasl-lib-2.1.23-13.el6.x86_64 expat-2.0.1-11.el6_2.x86_64 fontconfig-2.8.0-3.el6.x86_64 freetype-2.3.11-6.el6_2.9.x86_64 keyutils-libs-1.4-4.el6.x86_64 lcms-libs-1.19-1.el6.x86_64 libICE-1.0.6-1.el6.x86_64 libSM-1.1.0-7.1.el6.x86_64 libX11-1.3-2.el6.x86_64 libXau-1.0.5-1.el6.x86_64 libXext-1.1-3.el6.x86_64 libXt-1.0.7-1.el6.x86_64 libcurl-7.19.7-26.el6_2.4.x86_64 libedit-2.11-4.20080712cvs.1.el6.x86_64 libgcc-4.4.6-4.el6.x86_64 libgomp-4.4.6-4.el6.x86_64 libidn-1.18-2.el6.x86_64 libjpeg-6b-46.el6.x86_64 libselinux-2.0.94-5.3.el6.x86_64 libssh2-1.2.2-11.el6_3.x86_64 libtiff-3.9.4-6.el6_3.x86_64 libtool-ltdl-2.2.6-15.5.el6.x86_64 libuuid-2.17.2-12.7.el6.x86_64 libxcb-1.5-1.el6.x86_64 ncurses-libs-5.7-3.20090208.el6.x86_64 nspr-4.9.1-2.el6_3.x86_64 nss-3.13.5-1.el6_3.x86_64 nss-softokn-freebl-3.12.9-11.el6.x86_64 nss-util-3.13.5-1.el6_3.x86_64 openldap-2.4.23-26.el6.x86_64 php-pecl-memcache-3.0.5-4.el6.x86_64 postgresql-libs-8.4.12-1.el6_2.x86_64 sqlite-3.6.20-1.el6.x86_64
まだ足りない。

Missingと言われたやつを全部インストール。
# debuginfo-install --nogpgcheck --enablerepo debug  debuginfo-install  ImageMagick-6.5.4.7-6.el6_2.x86_64 cyrus-sasl-lib-2.1.23-13.el6.x86_64 expat-2.0.1-11.el6_2.x86_64 fontconfig-2.8.0-3.el6.x86_64 keyutils-libs-1.4-4.el6.x86_64 lcms-libs-1.19-1.el6.x86_64 libICE-1.0.6-1.el6.x86_64 libSM-1.1.0-7.1.el6.x86_64 libX11-1.3-2.el6.x86_64 libXau-1.0.5-1.el6.x86_64 libXext-1.1-3.el6.x86_64 libXt-1.0.7-1.el6.x86_64 libcurl-7.19.7-26.el6_2.4.x86_64 libedit-2.11-4.20080712cvs.1.el6.x86_64 libidn-1.18-2.el6.x86_64 libjpeg-6b-46.el6.x86_64 libselinux-2.0.94-5.3.el6.x86_64 libssh2-1.2.2-11.el6_3.x86_64 libtool-ltdl-2.2.6-15.5.el6.x86_64 libuuid-2.17.2-12.7.el6.x86_64 libxcb-1.5-1.el6.x86_64 ncurses-libs-5.7-3.20090208.el6.x86_64 nspr-4.9.1-2.el6_3.x86_64 nss-3.13.5-1.el6_3.x86_64 nss-softokn-freebl-3.12.9-11.el6.x86_64 nss-util-3.13.5-1.el6_3.x86_64 openldap-2.4.23-26.el6.x86_64 php-pecl-memcache-3.0.5-4.el6.x86_64 postgresql-libs-8.4.12-1.el6_2.x86_64 sqlite-3.6.20-1.el6.x86_64
再度gdb
(gdb) run test.t
Starting program: /usr/bin/php test.t
warning: the debug information found in "/usr/lib/debug//lib64/libfreebl3.so.debug" does not match "/lib64/libfreebl3.so" (CRC mismatch).

warning: the debug information found in "/usr/lib/debug/lib64/libfreebl3.so.debug" does not match "/lib64/libfreebl3.so" (CRC mismatch).

Missing separate debuginfo for /lib64/libfreebl3.so
Try: yum --disablerepo='*' --enablerepo='*-debug*' install /usr/lib/debug/.build-id/68/195872ecfb188389d29aaf01031a976fd18168.debug
[Thread debugging using libthread_db enabled]

#!/usr/bin/php
1..7
# test of Imagick
[New Thread 0x7fffe5523700 (LWP 10899)]
# Looks like you planned 7 tests but only ran 0.

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7fffe5523700 (LWP 10899)]
do_wait (bar=0x1fcb360, state=20) at ../../../libgomp/config/linux/wait.h:54
54          if (__builtin_expect (*addr != val, 0))
Missing separate debuginfos, use: debuginfo-install fontconfig-2.8.0-3.el6.x86_64 lcms-libs-1.19-1.el6.x86_64 libICE-1.0.6-1.el6.x86_64 libSM-1.1.0-7.1.el6.x86_64 libX11-1.3-2.el6.x86_64 libXau-1.0.5-1.el6.x86_64 libXext-1.1-3.el6.x86_64 libXt-1.0.7-1.el6.x86_64 libedit-2.11-4.20080712cvs.1.el6.x86_64 libidn-1.18-2.el6.x86_64 libjpeg-6b-46.el6.x86_64 libtool-ltdl-2.2.6-15.5.el6.x86_64 libxcb-1.5-1.el6.x86_64 ncurses-libs-5.7-3.20090208.el6.x86_64 sqlite-3.6.20-1.el6.x86_64
おー!!
ついにSegmentation faultの原因箇所を特定できました!!

そして、"libgomp/config/linux/wait.h"でググったら冒頭の対処法にたどり着くことができました。

ヤフーさんありがとうございました。
そして、この記事が誰かのお役に立てば幸いです。
カテゴリ:

人気記事