2009-05-08

scim-helper-managerのcoreダンプをなんとかしたい

いつのころからか、ホームディレクトリにscim-helper-manager.coreができるようになっており、XfceにあるSCIMのアイコンを右クリックしても「SCIMを設定」のメニュー項目が出なくなってしまっていた。

これに関する最初の記述は、たぶん、[FreeBSD-users-jp 91512] 7.0-RELEASE で scim-helper-manager.core から始まるスレッドで、途中でsetupモジュールをロードするところがおかしいというところまで追求しているものの、いつのまにか ltdl.cpp 内で try_dlopen() が成功したら(エラー数が0なら)エラーを返すとかいう意味のわからない解決に終わってしまっている。

それ以外では、かけまわる子犬。: scim-helper-manager.core の core うざい・・。 で、.xsession 内で(kde起動前に) skim を起動することで、coreダンプしなくなるという記述があるが、何らかの依存関係が解消したなどの根本的な解決ではなさそうである。

また、めもがき:2009年1月中旬 によれば、NetBSDでも同様な問題があって、libpthreadがらみではないかという結論に至っている。

さらに最近、2chの FreeBSDを語れ Part23 にも関連の話題があり、NISユーザだと発生するだの、-gやgcc34を使えばいいだの、スレッドがらみでデバッグが困難だの、いろいろ情報が書かれている。

自分でも何とか解決できればと、SCIM 1.4.9を探し出して自家portを作ってみたり、コンパイラを変えてみたりしてみた。NISユーザの場合は、getpwuid() 内の getpwent_r() から呼ばれた yp_match() 内のさらに奥の _pthread_main_np() 内で落ちているということまではわかったが、libc を -g で作ってまで調べるには気合いと時間が足りない。それでも何とか、あちこちにデバッグプリントを入れてみたみたところ、どうやら dlopen/dlclose が関連している可能性が高く、ltdl.cpp 内の sys_dl_close() にある dlclose() を呼ぶ部分で、これを呼ばずにいきなり return してしまえば、とりあえずは落ちなくなることがわかった。

パッチはこんな感じ。

--- ./src/ltdl.cpp.orig 2008-11-02 15:42:40.000000000 +0900
+++ ./src/ltdl.cpp 2009-05-07 18:11:26.000000000 +0900
@@ -1073,6 +1073,7 @@
sys_dl_close (lt_user_data loader_data, lt_module module)
{
int errors = 0;
+ return errors; // Avoiding FreeBSD core-dump; don't know why this works

if (dlclose (module) != 0)
{

この続きは気力次第。


追記(5/11)

早速にも めもがき:2009年5月9日分 にて、詳しい解説つきのフォローをいただきました。ありがとうございます。

ビルド時のログをとって調べてみると、確かにライブラリのリンク時には -pthread がついていて、親のバイナリにはついていなかったりする。

というわけで、Makefileをいじって、configureに渡すLDCONFIGに -pthread を追加してみたところ、ぴたりと問題はおさまった。パッチを作って、メンテナに連絡してみたりする。

ところで、uim への乗り換えも検討して試してみたりしたことはあるのだが、どうもキーバインディングなどの微妙な問題なのか、uim-skk の使い勝手が悪い。xterm/kterm 上で Enter がわりに(Ctrl-M より楽だから)Ctrl-J を押す癖があることも一因かもしれないけど、firefox 上でもなんかバタバタして状態の把握がうまくできない。なので uim はお預け。最近 anthy 版portの出た ibus に注目中。

2009-04-21

FreeBSDのportsでmake installするときは-dlなど禁止

makeの -dl は、makeが実行するコマンドをすべて強制表示させるオプションで、Makefileなんかで非表示にしたコマンドも表示されるので、デバッグに便利な機能である。

portsのmake時にいったい何が起きているのかを表示させようと、portupgrade -f -m -dl hoge とかやってみたところ、たしかに期待どおりに表示されるのだが、もう一度portupgradeしようとすると、

Stale dependency: hoge --> ] -- manually run 'pkgdb -F'...
とか言われるようになり、pkgdb -F をするはめになる。そうすると何やらわけのわからない依存関係が多量に削除される。

で、hoge/+CONTENTS を見てみたら、多量のゴミが。

しばらく bsd.port.mk と格闘したところ、fake-pkg のターゲットで Registering installation for hoge と表示した後の処理で使う PKG_ARGS の展開結果がおかしい。その定義はというと、make actual-package-depends を実行した結果を加工している。つまり、このmakeの実行時に -dl が有効になってしまって、ゴミが出力され、それも含めて加工した結果をpkg_createに渡しているせいで、+CONTENTSが壊れるということらしい。

makeが子makeを呼ぶときに .MAKEFLAGS を渡すが、この中から -d* を探して削除するというコードが必要になる。とってもめんどくさそうなので、make install時に限っては -d* をつけないことにする。

あとでpkgdb -Fすればいいんだから簡単じゃないかとも思えるが、-dg2 とかしたらpkgdb -Fの後でもpkg_deleteがcoreを吐くとかいう事態になる。


追記(5/7)

デバッグオプションを取り除いて子makeを呼ぶコードを書いてみた。
--- bsd.port.mk.orig 2009-04-10 07:40:20.000000000 +0900
+++ bsd.port.mk 2009-05-06 13:36:11.000000000 +0900
@@ -2384,7 +2384,18 @@
.endif

.if !defined(PKG_ARGS)
-PKG_ARGS= -v -c -${COMMENT:Q} -d ${DESCR} -f ${TMPPLIST} -p ${PREFIX} -P "`cd ${.CURDIR} && ${MAKE} actual-package-depends | ${GREP} -v -E ${PKG_IGNORE_DEPENDS} | ${SORT} -u -t : -k 2`" ${EXTRA_PKG_ARGS} $${_LATE_PKG_ARGS}
+_MINUSD= -d
+. for _MAKEFLAG in ${.MAKEFLAGS}
+. if ${_MINUSD} == ${_MAKEFLAG}
+_AFTERMINUSD= yes
+. else
+. if !defined(_AFTERMINUSD)
+_NODEBUGMAKEFLAGS+= ${_MAKEFLAG}
+. endif
+.undef _AFTERMINUSD
+. endif
+. endfor
+PKG_ARGS= -v -c -${COMMENT:Q} -d ${DESCR} -f ${TMPPLIST} -p ${PREFIX} -P "`cd ${.CURDIR} && MAKEFLAGS=${_NODEBUGMAKEFLAGS} ${MAKE} actual-package-depends | ${GREP} -v -E ${PKG_IGNORE_DEPENDS} | ${SORT} -u -t : -k 2`" ${EXTRA_PKG_ARGS} $${_LATE_PKG_ARGS}
.if !defined(NO_MTREE)
PKG_ARGS+= -m ${MTREE_FILE}
.endif

一応動いてそうなので、いつかのためにメモ。


追記(5/20)

やっぱりダメ。依存関係によってインストールされたパッケージに正常に@pkgdepがつかない。 -DINSTALLS_DEPENDS がうまくわかってない感じ。