DYLD_LIBRARY_PATH=/opt/local/lib
って環境変数を設定してたのが原因でした。なんか作業中に設定してしまった模様。
同じ名前で中身が違うshared libraryがDYLD_LIBRARY_PATHで先に読まれてしまったのが原因。今回の場合はDYLD_FALLBACK_LIBRARY_PATHで足らなかったら読むようにすれば解決。
だけだと面白くないですね。追ってみます。
syscallをおっかけられるktraceで見てみると
...
いやさ10.5ならktraceじゃなくてdtrace!
sudo dtrace -n syscall::open"*":entry'/execname == "Vim"/{printf("%s", copyinstr(arg0))}'
こんなんでopen syscallの第一引数を逐次表示。よくわからんスクリプトだなぁと思ってましたが、awkと思えばスッキリ。
DYLD_LIBRARY_PATH=/opt/local/lib を指定してると
CPU ID FUNCTION:NAME
1 17600 open:entry /opt/local/lib/libncurses.5.dylib
1 17600 open:entry /opt/local/lib/libiconv.2.dylib
1 17600 open:entry /opt/local/lib/libintl.8.dylib
1 17600 open:entry /opt/local/lib/libmigemo.1.dylib
1 17600 open:entry /System/Library/Frameworks/Python.framework/Versions/2.3/Python
1 17600 open:entry /opt/local/lib/libruby.dylib
1 17600 open:entry /opt/local/lib/libz.1.dylib
1 17600 open:entry /opt/local/lib/libxslt.1.dylib
1 17600 open:entry /opt/local/lib/libPng.dylib
DYLD_FALLBACK_LIBRARY_PATH=/opt/local/lib を指定していると
0 17600 open:entry /opt/local/lib/libncurses.5.dylib
0 17600 open:entry /opt/local/lib/libiconv.2.dylib
0 17600 open:entry /opt/local/lib/libintl.8.dylib
0 17600 open:entry /opt/local/lib/libmigemo.1.dylib
0 17600 open:entry /System/Library/Frameworks/Python.framework/Versions/2.3/Python
0 17600 open:entry /opt/local/lib/libruby.dylib
ほらこの通り。って、なんか全然足らないですね。carbonげなdylibとかまったく読まれてない。DYLD_PRINT_LIBRARIES= も付けて実行すると読み込まれたすべてのdylibが表示されるので、dtraceでもここまで表示されて欲しい。
syscall::"*":entryで見てみるとstatで/usr/lib/libobjc.A.dylibとか触ってる。システム系のshared libraryはsystem callで読まれないのかなぁ、とか一瞬思ってしまいましたが、こりゃcacheですね。man dyldで発見。
DYLD_SHARED_REGION=avoid DYLD_FALLBACK_LIBRARY_PATH=/opt/local/lib なら
0 17600 open:entry /opt/local/lib/libncurses.5.dylib
0 17600 open:entry /opt/local/lib/libiconv.2.dylib
0 17600 open:entry /opt/local/lib/libintl.8.dylib
0 17600 open:entry /opt/local/lib/libmigemo.1.dylib
0 17600 open:entry /System/Library/Frameworks/Python.framework/Versions/2.3/Python
0 17600 open:entry /opt/local/lib/libruby.dylib
0 17600 open:entry /usr/lib/libobjc.A.dylib
0 17600 open:entry /usr/lib/libSystem.B.dylib
0 17600 open:entry /System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/CarbonSound.framework/Versions/A/CarbonSound
0 17600 open:entry /System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/CommonPanels.framework/Versions/A/CommonPanels
...
解決! でも/opt/local/lib/libncurses.5.dylibとか使ってる状態で、さらにこれやってもopenで読まれるのはなんでだろう。何かcacheされる条件があるんかな。
ということでdtraceは面白いという話でした。awkみたいなスクリプト以外にrubyとかで書けたら便利かも。あとhookして挙動いじれたり。openしたつもりが別のファイルをopenしてたりとか。system callの中身をrubyで書いたりとか。jailな感じ。