2012/05/05

Debian WheezyでCouchDB 1.2.0をコンパイルした時にはまった事

CouchDB 1.2.0をさくらVPSで稼働しているDebian wheezyに導入したのですが、 エラーがでてcouchjsが実行できない自体になった時のトラブルシュートのログです。

エラーの内容

couchdb自体は問題なく起動したものの、viewを参照するとvar/log/couchdb/couch.logに次のようなエラーが大量に書き込まれていました。

...
[Wed, 02 May 2012 06:30:37 GMT] [error] [<0.4852.0>] OS Process Error <0.5474.0> :: {os_process_error,
                                                     {exit_status,139}}
[Wed, 02 May 2012 06:30:37 GMT] [error] [<0.4852.0>] OS Process Error <0.5477.0> :: {os_process_error,
                                                     {exit_status,139}}
...

原因はSpiderMonkeyのライブラリバージョンにあったのですが、 突き止めるまでに時間が少しかかってしまいました。

Debian wheezyで利用可能なSpiderMonkeyのバージョン

このバージョンのDebianでは2種類のライブラリが使用可能です。

  • libmozjs-dev - Development files for the Mozilla SpiderMonkey JavaScript library
  • libmozjs10d - Mozilla SpiderMonkey JavaScript library
  • libmozjs185-1.0 - Spidermonkey javascript engine
  • libmozjs185-dev - Spidermonkey javascript library - development headers

先頭2つのlibmozjs-devとlibmozjs10dはDebianプロジェクトが開発するfirefox互換ブラウザに組み込まれているJavaScriptエンジンで基本的にはSpiderMonkeyと同一ですが、Mozillaプロジェクトが配布しているSpiderMonkeyのバージョンは1.8.xとなっています。

このライブラリを導入した状態でCouchDBのconfigureを走らせると、バージョンが新し過ぎてサポートされていない旨が表示されます。

そこでlibmozjs185-1.0とlibmozjs185-devを導入して、configureが問題なく動くようにしたのですが、これが問題を引き起した原因となりました。

configureの振舞い

先ほどリストした全てのパッケージが入った状態では、configureは問題なく完了します。

この状態ではcouchjsコマンドだけが、libmozjsとリンクされてしまいます。 正しいのはlibmozj185とリンクされている状態ですが、lddでみるとlibmozjs10dパッケージに含まれるライブラリとリンクされています。

$ ldd src/couchdb/priv/couchjs |grep js
	libmozjs.so.10d => /usr/lib/libmozjs.so.10d (0x00007fab300d0000)

まぁconfigureのバグなんですが、このお陰でviewにアクセスした時だけ結果が正しく帰ってこない事になります。

couchjsコマンドのデバッグ方法

で、原因を突き止めるために、簡単なJavaScriptで書かれたスクリプト(a.js)を準備して実行してみます。

a.jsスクリプトファイル

print("test");
 $ /usr/local/bin/couchjs a.js
Segmentation fault

どこで落ちたのか原因を探るためにstraceを使う事が多いのですが、今回はまったく役に立ちませんでした。

結局のところgdbを使ってlibmozjs.soライブラリの中で落ちている事を確認しました。

 $ gdb /usr/local/bin/couchjs
 (gdb) run a.js
 (gdb) backtrace
(gdb) backtrace 
#0  0x00000000004049e5 in ?? ()
#1  0x00007ffff76d5ab8 in ?? () from /usr/lib/libmozjs.so.10d
#2  0x00007ffff764c937 in JS_ExecuteScript () from /usr/lib/libmozjs.so.10d
#3  0x000000000040227c in main (argc=<optimized out>, argv=<optimized out>)
    at couch_js/sm185.c:389

これで無事に/usr/lib/libmozjs.so.10dの中の処理で落ちていて、本来リンクして欲しくないライブラリを参照していた事が原因だとわかりました。

回避策

この問題を避けるためには、毎回正しいlibmozjs関連のファイルをポイントするようにconfigureオプションを指定する他ありません。

幸い、couchdb 1.2.0もdebian wheezyも比較的新しいパッケージなので、昔のcouchdbのようにinclude fileから指定する必要はなくなっています。

configureを次のように実行して、libmozjs185.soをリンクしている事を確認します。

./configure --with-js-lib-name=mozjs185
checking for JS185... yes
checking for JS185... yes
checking jsapi.h usability... yes
checking jsapi.h presence... yes
checking for jsapi.h... yes
checking for JS_NewObject in -lmozjs185... yes

これでlibmozjs10dパッケージが導入されていても、エラーなくcouchdbが動きます。

さいごに

configureの中でヘッダーファイルのチェックでpkg-configを使っているのに、ライブラリのチェックでは実際にコンパイルできるか普通にチェックしてしまっているので、libmozjs.so.10dをリンクしてしまっていました。

これはバグだとは思うのですが、pkg-configにlibmoz185パッケージが入っているとは限りませんし、どちらもECMAScript Ver.5をサポートするようにできているので、関数のチェックを確実に行なうのは難しそうに思えます。

CouchDBの経験があればcouchjsが動かないだけで、libmozjs周りを見に行くとは思うのですが、今回は現象だけをみても原因がよく分からなかったために時間を数時間ロスしてしまいました。

まだtestingフェーズのdebian wheezyを使っている人が多いとは思いませんし、そんな人達は自力で解決しちゃうと思いますが、どなたかの役に立てば幸いです。

0 件のコメント: