MacPortsのrubyがsslのエラーで落ちる
rabbitユーザとかは注意。お知らせしてくれた@masarakkiさん、@nahiさん、ありがとうざいます。
たとえばこんな感じ。
% rabbit --help Xlib: extension "RANDR" missing on display "/tmp/launch-AQLo1z/org.x:0". /opt/local/lib/ruby/1.8/openssl/ssl-internal.rb:30: [BUG] Segmentation fault ruby 1.8.7 (2010-08-16 patchlevel 302) [i686-darwin10] zsh: abort rabbit --help %
いろいろ詰めていくと、最小の再現パターンはこんな感じ。
% ruby -rglib2 -ropenssl -e ''
glib2とopensslの順番を入れ替えるとだいじょぶだったりする。原因はrubyの拡張ライブラリopenssl.bundleがリンクしているport:opensslのlibcrypto.1.0.0.dylibとglib2がCarbon経由で参照しているMac組み込みの/usr/lib/libcrypto.0.9.8.dylibの両方をロードしてしまうため。
回避方法は次のいずれか
- rubyのext/opensslがリンクするlibsslを0.9.8にするようにする
- glib2からCarbonをリンクしないようにする
- twolevel_namespaceで別々のlibsslをロードしても大丈夫にする
希望としてはglib2での対処なんだけど、他の人を説得できる自信はあんまない。twolevel_namespaceのは考えただけで本当に解決するかはわからない。
最初のは、すでにMacPortsで0.9.8がインストールされている場合はこんなふうにすればよい。
% sudo port -f deactivate openssl % sudo port activate openssl @0.9.8o_0 % sudo port -n upgrade --force ruby
これを英語にしてmacports-devに投げる予定。はあ、、
(2010/08/27 追記)また、opensslがすでに1.0.0系しかない場合は、MacPortsのopensslにリンクしないrubyを使うようにすることで回避できます。
% sudo port -f deactivate openssl # opensslを一時的に無効に % sudo port edit ruby # rubyの依存関係からopensslを外す Index: ruby/Portfile =================================================================== --- ruby/Portfile (revision 70788) +++ ruby/Portfile (working copy) @@ -31,7 +31,6 @@ depends_lib port:libiconv \ port:readline \ - port:openssl \ port:zlib \ port:ncurses % sudo port -n upgrade --force ruby # rubyを再コンパイル % sudo port activate openssl @1.0.0a_0+universal # opensslを戻す % otool -L /opt/local/lib/ruby/1.8/i686-darwin10/openssl.bundle /opt/local/lib/ruby/1.8/i686-darwin10/openssl.bundle: /opt/local/lib/libruby.dylib (compatibility version 1.8.0, current version 1.8.7) /usr/lib/libssl.0.9.8.dylib (compatibility version 0.9.8, current version 0.9.8) /usr/lib/libcrypto.0.9.8.dylib (compatibility version 0.9.8, current version 0.9.8) /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.2.0) /usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 227.0.0)
おぼえがき、今回の調べかた
ext/openssl単体をrequireしたとき("ruby -ropenssl -e ''")では問題が起きないことから、ほかのライブラリとの組み合わせっぽいとこまでは早めに推測できた。で、拡張ライブラリをいろいろ使ってるrabbitで試してみて、ruby-gnome2のモジュールを試してみたら、glib2がアウトらしいことを見つけた。
次はglib2からリンクしているどのライブラリ・フレームワークが影響しているかを調べる。
実行時のライブラリ読み込みは、環境変数 DYLD_PRINT_LIBRARIES_POST_LAUNCH (see man dyld(1))を有効にして様子を見る。
% DYLD_PRINT_LIBRARIES_POST_LAUNCH=1 ruby -rglib2 -ropenssl -e '' dyld: loaded: /opt/local/lib/ruby/1.8/i686-darwin10/thread.bundle dyld: loaded: /opt/local/lib/ruby/vendor_ruby/1.8/i686-darwin10/glib2.bundle dyld: loaded: /opt/local/lib/libgobject-2.0.0.dylib dyld: loaded: /opt/local/lib/libgthread-2.0.0.dylib dyld: loaded: /opt/local/lib/libglib-2.0.0.dylib dyld: loaded: /opt/local/lib/libintl.8.dylib dyld: loaded: /opt/local/lib/libiconv.2.dylib dyld: loaded: /System/Library/Frameworks/Carbon.framework/Versions/A/Carbon dyld: loaded: /usr/lib/libresolv.9.dylib : dyld: loaded: /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libLAPACK.dylib dyld: loaded: /usr/lib/libcrypto.0.9.8.dylib dyld: loaded: /System/Library/PrivateFrameworks/TrustEvaluationAgent.framework/Versions/A/TrustEvaluationAgent : dyld: loaded: /opt/local/lib/ruby/1.8/i686-darwin10/openssl.bundle dyld: loaded: /opt/local/lib/libssl.1.0.0.dylib dyld: loaded: /opt/local/lib/libcrypto.1.0.0.dylib
ここはもうてきとーにotool -Lで試し打ちして確認。/opt/local/lib/*.dylibには該当がないことは確認。で、/System/Library/Frameworksとかになるとリンク関係が深いので手作業だとキツイ。[otool recursive]で検索してでてきたpythonスクリプトを利用して、Carbon.frameworkが原因であることを見つけた。