Gauche:NetBSD
特定条件下でmake checkでthreadのテストに失敗する(0.8.9_pre1)
び(2007/01/13 15:30:00 PST): Parallels Desktop 上でnetbsd-4枝先端(NetBSD-4.0_BETA2/i386)という環境下、ext/threadsでgmake(GNU make)を使ってgmake checkすると
% gmake -s check Testing threads ... failed. discrepancies found. Errors are: test thread-join!: expects 1346269 => got #<error "couldn't start a new thread: #<thread 7 new 0x8264a80>"> test uncaught-exception: expects #t => got #<error "couldn't start a new thread: #<thread #f new 0x818b540>"> test uncaught-exception: expects #t => got #<error "couldn't start a new thread: #<thread #f new 0x818b380>"> test uncaught-exception: expects #t => got #<error "couldn't start a new thread: #<thread #f new 0x818b1c0>"> test lock and unlock - blocking (simple spin-lock): expects ((put a) (get a) (put b) (get b) (put c) (get c)) => got #<error "couldn't start a new thread: #<thread producer new 0x818b000>"> test condition-variable-signal!: expects ((put a) (get a) (put b) (get b) (put c) (get c)) => got #<error "couldn't start a new thread: #<thread producer new 0x820be00>"> test write to file, buffered: expects #t => got #<error "couldn't start a new thread: #<thread #f new 0x820bc40>"> test write to file, line-buffered: expects #t => got #<error "couldn't start a new thread: #<thread #f new 0x82ece00>"> test write to string: expects #t => got #<error "couldn't start a new thread: #<thread #f new 0x82ec000>"> test check if port is unlocked on error: expects "aaaaaAAAAAAbbbbbbbb" => got #<error "couldn't start a new thread: #<thread th1 new 0x84301c0>"> test check if port is unlocked on error: expects "aaaaaAAAAAAbbbbbbbb" => got #<error "couldn't start a new thread: #<thread th1 new 0x818b540>"> test check if port is unlocked on error (use file): expects "aaaaaAAAAAAbbbbbbbb" => got #<error "couldn't start a new thread: #<thread th1 new 0x818b1c0>"> test check if port is unlocked on error (use file): expects "aaaaaAAAAAAbbbbbbbb" => got #<error "couldn't start a new thread: #<thread th1 new 0x82ece00>"> test check locality of parameters: expects (3 4 5) => got #<error "couldn't start a new thread: #<thread #f new 0x82eca80>">
ところが、BSD標準のmake(BSD make)だと問題は起きない。
% make -s check Testing threads ... passed.
なお、netbsd-3枝先端(NetBSD-3.1_STABLE/i386)では、gmake、makeともに問題ない。なんでやねん。
- enami (2007/01/14 02:01:32 PST): 以下のような理屈みたいです。
- gmake は起動時に最大まで stack limit を拡げる。
- pthread は thread の stack を stack limit 分確保する。
- stack limit の hard limit は netbsd-3 では 32768k だけど netbsd-current (多分 -4 も) では 65536k
- 後者だと途中で mmap が fail する。
び (2006/03/03 18:37:26 PST) NetBSD pthread対応(gc6.7版)
3/3付けでリリースされたBoehm-gcの6.7で、拙作のNetBSD pthread対応パッチがマージされました。他にも、Intel版Mac OS X用のパッチなどもマージされていて、けっこう嬉しいリリースになっています。
Gauche CVS HEADに含まれるgcを6.7に上げつつgc以外の部分をNetBSD pthreadに対応させるパッチを作りました。問題がないようなら、gc6.7に上げるタイミングでマージしていただけると嬉しいです。
- Shiro(2006/03/04 01:22:28 PST): マージしました。ありがとうございます。
び (2005/09/05 21:22:23 PDT) NetBSD pthread対応
NetBSD-2.0以降サポートされたpthreadに、GaucheのCVS HEADを対応させてみました(パッチ)。 試したのはNetBSD-3.0BETA/2.0.2のみですし、make checkが通ったというだけなので、ご注意ください。
Boehm-gcをNetBSDのpthread対応するに当たっては、とりあえずpthreadの枠組みの中で行いました。たぶん、Scheduler Activationやその上に実装されたLWPを活用した方が効率的かつ安全だとは思うのですが、それは追って挑戦してみます。
genstubに手を加えた理由は、現状だとext/net/netlib.stubから生成されるnetlib.cのScm_Init_netlib()において、Scm_InitBuiltinGeneric()より先にScm_InitBuiltinMethod()が呼ばれてしまい、その結果ScmGenericのlockをSCM_INTERNAL_MUTEX_INIT()する前にSCM_INTERNAL_MUTEX_LOCK()/SCM_INTERNAL_MUTEX_UNLOCK()されてしまうからです。
- Shiro: Boehm GCは既に7.0alphaがいくつか出ていて、
NetBSDのpthread対応もMLでちらと話題になっていたと思います。
できれば本家の方にフィードバックして下さい。GaucheはBoehm GCの
新版が出た際に gc/ の下をごっそり入れ換えるだけなので、Gauche独自の
変更はrevertされてしまう可能性大です。
- はい、そのつもりです。ただ、NetBSD的にはたぶんシグナルによるGC_start_world()/GC_stop_world()よりも、_lwp_suspend()/_lwp_continue()を使うべきかと思い、実現可能性を探っています。うまくいきそうならそちらを実現してから、わたしの手に余るようなら現状のパッチを本家に投げようと考えています。
- 結局lwpによる再実装は諦め、上記のパッチを先日リリースされたgc6.6に対応させたものをBoehm-gcのメーリングリストに投げました。うまいこと取り込まれるといいんですが...
- それと、以前のパッチではi386以外のアーキテクチャではいくつかマクロが定義されない不具合があったので、上記のリンク先はその不具合を修正したものに差し替えました。
- はい、そのつもりです。ただ、NetBSD的にはたぶんシグナルによるGC_start_world()/GC_stop_world()よりも、_lwp_suspend()/_lwp_continue()を使うべきかと思い、実現可能性を探っています。うまくいきそうならそちらを実現してから、わたしの手に余るようなら現状のパッチを本家に投げようと考えています。
- genstubの変更は正しいfixだと思います。現在のinstance-pool->listは ちゃんとインスタンスの作成順になってるんでreverseの必要はないはずで、 たぶん昔のコードが残っちゃっていたのでしょう。
skimu のお勧めインストール手順
LD_LIBRARY_PATH=/usr/lib:/usr/pkg/lib:/usr/local/lib export LD_LIBRARY_PATH ./configure --with-local=/usr/pkg --with-rpath=/usr/lib:/usr/pkg/lib:/usr/local/lib --with-iconv=/usr/pkg unset LD_LIBRARY_PATH make make test make install
LD_LIBRARY_PATH を設定しているのは ext/charconv でのコンパイラコマンドライン のチェック時にgccのつくるプログラムが libiconv を見つけられずに失敗してしまうのを 一時的に LD_LIBRARY_PATH を設定することにより回避するためです。本来は configure が 適切な -rpath を指定するべき。 --with-local を指定しているのは私の NetBSD box では gdbm が /usr/pkg にいるためです。 gdbm が /usr/local に いる機械では必要ありません。
NetBSD について
- NetBSD Project が配布しているサードパーティーソフトウェア(pkgsrc) は /usr/pkg に入る。
- /usr/lib 以外にある .so をリンクするプログラムは -L だけでなく -Wl,-rpath もつけなくてはならない。
- つけなくても /etc/ld.so.conf にパスを付け加えるか LD_LIBRARY_PATH を指定すれば よいが、/etc/ld.so.conf を編集するには root 権限がいるし、あまり お勧めでない。 LD_LIBRARY_PATH を日常環境に入れておくのもお勧めでない。 /usr/lib /usr/pkg/lib /usr/local/lib の 3 つは事実上の標準ディレクトリで あるから /etc/ld.so.conf に入れているひともいる。このようなシステムでは -rpath を入れなくても問題はない。(が、-rpath があっても問題はない)
- /usr/ 以下は4.4BSD由来の share, lib, libexec と分ける流儀。 /usr/pkg/ も多くはそれに従っているようです。/usr/local もそうするのが 好まれると思う。
- 共有ライブラリの検索順序について
上記の2番目の項目の背後にある規則の様です。 オンラインマニュアル参照。
- LD_LIBRARY_PATH と /etc/ld.so.conf
- リンク時に-rpathで埋め込まれたパス
- /usr/lib
この順序で参照される。 このため、-rpath で指定されたものと別のライブラリを参照してしまう場合がありうる。 ちなみにFreeBSD や Solaris でも同じように動作するらしいです。
NetBSD 各プラットフォームでの動作確認
主に i386 以外の NetBSD での動作報告です. このような書き方で良いのかはわからないのですが(^^;), 問題があれば適宜修正等していきたいと思います.ytaki
- 共通: 2.0 から pthreads が導入されているが,pkgsrc では --enable-threads=none で configure されている(Boehm GC が未対応?). ytaki(2005/03/23 00:47:54 PST)
- macppc: 2.0.2 + Gauche 0.8.4 で,compile.c がメモリが足りなくなって
コンパイルできない現象を確認.メモリが少ないマシンでは辛いかも.さしあたり,
compile.c のみ最適化なし(-O2 なし)にすると通る.make check は全て passed.
詳細はこちら.ytaki(2005/06/25 11:15:03 PDT)
- 2.0.2 + Gauche 0.8.5 では特に修正の必要もなくコンパイル可(make check も全て passed).compile.scm の改良により compile.c のサイズが小さくなったのがうまく いった直接の理由と考えられるので,今後のバージョンでもうまくいくかは不明. ytaki(2005/07/04 23:29:40 PDT)
- alpha: current 2.99.15 + Gauche 0.8.3 で全テスト OK.ytaki(2005/03/23 00:47:54 PST)
NetBSD2.0以降でGauche-0.8.5をpthread対応でコンパイルする方法
この情報は近い将来不要になるはずです。
- 背景
2005/08現在、Gauche-0.8.5についているBoehm-GCのバージョンはNetBSDに対しては pthreads対応していません。 一方NetBSD自体にはpthreadsが対応しており、pkgsrc以下のさまざまなプログラムや ライブラリも可能なものはpthreads対応でコンパイルされています。 (もちろんGauche自身はpthread対応しておりLinuxなどでは動作している) この状況でGauche-glなどを使いたい場合にはGaucheでpthreadライブラリをリンクする 必要があります。
--- Makefile.org 2005-08-05 16:44:23.000000000 +0900 +++ Makefile 2005-08-09 14:08:39.000000000 +0900 @@ -40,7 +40,7 @@ DESTDIR = CC = gcc AR = ar -LIBS = -lcrypt -lutil -lm +LIBS = -lcrypt -lutil -lm -pthread -lpthread CFLAGS = -g -O2 -fPIC -DPIC CPPFLAGS = -I/usr/pkg/include LDFLAGS = -L/usr/pkg/lib
./configure後のmake前にsrc/MakefileのLIBSに上記の変更を追加してください。 あとはそのままmake; make check; make installへ。
Gauche-gl のインストール
gauche-gl のインストールには LD_LIBRARY_PATH の設定と若干の Makefile の変更が必要になる。あくまで pkgsrc から GL/GLUT なんかがインストール されていればだけど。(Gauche-gl-0.3.1 時点)
- setenv LD_LIBRARY_PATH /usr/local/lib:/usr/pkg/lib:/usr/X11R6/lib:/usr/lib
- ./configure
- cd src
- vi Makefile
- cd ..
- make
- make check
- make install
- src/Makefile の変更ポイントは
CFLAGSに -I/usr/pkg/include を追加 LIBS の -lGLU等の前に -L/usr/pkg/lib を追加
なお、2005/08時点NetBSDはpthread対応Gaucheに含まれるBoehm-GCのNetBSD対応部分の pthread非対応への対応は、上にある、 NetBSD2.0以降でgaucheをpthread対応でコンパイルする方法 によりGaucheにmake時にpthreadをリンクすることで回避できます。
NetBSDにおけるGauche-0.8.5でのpthread問題に関する記録
- メーリングリストの件(I'have an error at make check in Gauche-gl-0.4)ですが、こちらで失礼します。 NetBSD (2.0 以上?)で pthread ライブラリをリンクしている拡張モジュールをロードしようとすると coredump するようです。 (2005/08/07 20:29:48 PDT)
- Shiro: なるほど。Gauche自体はenable-threads=pthreadsでコンパイルされて ますか?
- やっぱりMLに投げてみるものですね。
確かにNetBSDって2.0からpthread対応されてますけどBoehm-GCが
まだなんじゃなかったでしたっけ?
と思って一応念のために件のマシンで--enable-threads=pthreadsを追加するとconfigure: error: pthread is not supported on i386-unknown-netbsdelf2.0.2
ってなりますねぇ。cut-sea:2005/08/07 22:23:11 PDT - ちょっと調べてみたのですが、libpthread をリンクしていないプログラムが dlopen で libpthread をリンクしているプログラムを呼ぶと起こるようです。
参照: http://mail-index.netbsd.org/tech-kern/2004/11/23/0008.html
ここに従って、gosh に libpthread を手動でリンクするようにしたら make check が通るようになりました。これが本当に正しい解決方法なのか分からないので、誰か確認してくれると助かります。(2005/08/08 21:04:40 PDT) - dlopen を使ってるプログラムは libpthread をリンクせよとのことなので、make check も通ったならそれで良いんじゃないでしょうか?
- Shiro: んーなるほど。libpthreadをリンクしててもプログラム中でスレッドを 作成しなければBoehm GC的には安全なはず。
- 情報ポインタありがとうございます。 この上にpthreadsをリンクしてmakeする方法を記載しました。 この方法でglが無事useできてgear.scmも動作確認できました。 んー、やっぱO2はずしてるからかちと遅い。cut-sea:2005/08/08 22:24:34 PDT
Gauche-gtk のインストール
gauche-gtk のインストールも gauche-gl と同じでいける。(Gauche-gtk-0.4.1時点)
- setenv LD_LIBRARY_PATH /usr/local/lib:/usr/pkg/lib:/usr/X11R6/lib:/usr/lib
- ./configure
- make
- make check
- make install
make できないのよ事例
こちらでも gdbm は /usr/pkg 以下にあるようなのですが、なぜか捜し出せない?
cut-sea@jini> uname -a NetBSD jini 1.6 NetBSD 1.6 (JINI) #0: Fri Nov 8 20:44:24 JST 2002 root@jini:/usr/src/sys/arch/i386/compile/JINI i386 cut-sea@jini> locate gdbm |grep -v pkgsrc : : /usr/pkg/include/gdbm.h /usr/pkg/info/gdbm.info /usr/pkg/lib/elk/runtime/scm/gdbmtest.scm /usr/pkg/lib/libgdbm.a /usr/pkg/lib/libgdbm.la /usr/pkg/lib/libgdbm.so /usr/pkg/lib/libgdbm.so.2 /usr/pkg/lib/libgdbm.so.2.0 : :
ところが今のところ
cut-sea@jini> gauche-config --reconfigure ./configure '--with-slib=/usr/local/lib' '--with-local=/usr/local' '--enable-ipv6'
でしかコンパイル確認できておらず、これまではこれで遊んでいて特に困らなかった。
apache を pkgsrc からインストールして、 簡単な gauche の cgi スクリプトが動作するのを確認できたので、 最近 WiLiKi を使いたいなと思ってインストールしてみた。 ところが web ブラウザからアクセスしてみるとエラーがでるではないか。 httpd/error_log を確認すると
*** ERROR: cannot find file "dbm/gdbm.scm" in *load-path* ("/usr/local/share/gauche/site/lib" "/usr/local/share/gauche/0.7.1/lib") Stack Trace: _______________________________________ 0 (initialize obj initargs) At line 59 of "/usr/local/share/gauche/0.7.1/lib/gauche/object.scm" 1 (make <wiliki> :db-path "/home/cut-sea/data/wikidata.dbm" :top-pag ... At line 50 of "/usr/pkg/libexec/cgi-bin/wiliki.cgi" [Sat Sep 13 21:38:43 2003] [error] [client 127.0.0.1] Premature end of script headers: /usr/pkg/libexec/cgi-bin/wiliki.cgi
となっていて、はじめて gdbm が使えないことに気付いた。 gdbm.scm が lib にインストールされてないんだけど、 要は make する際に見つけられてない。(のか?) とくに --with-local=/usr/local としてたところを --with-local=/usr/pkg としただけでも configure にて下のようなエラーが出る。 そもそも私のマシンでは基本的にソフトのインストールは pkgsrc を使用していて、 自力でインストールしているソフトなんか皆無なのだ。 (scm と slib だけ最新のが欲しかったのでインストールした) なぜライブラリなどが豊富なはずの /usr/pkg を指定して失敗するのか(とほほ)。
./configure 時にかなり多くの
config.status: creating doc/Makefile sed: sed: 46: ./confstat08263a/subs-1.sed: 3: ./confstat08263a/subs-2.sed: unescaped newline inside substitute patterninvalid command code - config.status: creating ext/Makefile sed: 46: ./confstat08263a/subs-1.sed: sed: unescaped newline inside substitute pattern3: ./confstat08263a/subs-2.sed: invalid command code - config.status: creating ext/Makefile.ext sed: sed: 46: ./confstat08263a/subs-1.sed: 3: ./confstat08263a/subs-2.sed: unescaped newline inside substitute patterninvalid command code - : : :
なんてエラーっぽいのがでるのも顕著。 そうなると make しても
cut-sea@jini> make make: no target to make. make: stopped in /home/cut-sea/devel/Gauche-0.7.1
って感じで make できない。 今のところ --with-local=/usr/local 以外を指定すると状況は同じだ。。。cut-sea:2003/09/13 07:31:40 PDT
- すこし yahoo で調べたら、 同じ様なところではまったのか?と思えるサイト発見。 あ、コレは??? sakaeさんのページか?ビンゴ! とりあえず、 gdbm が /usr/pkg や /usr/local に入ると面倒ってのは分かった。 /usr/lib 下に入ってれば OK ってのも分かったけど、 私はあまり、 /usr/lib に入れたくないな。。。 さてどうしてくれようぞ。cut-sea
私の 1.6.1 では問題なくコンパイルとおります。 一度 config.cache などを消して, やり直してみてはいかがでしょう。だだし、今日(9/13/03)の CVS 版 Gauche では dbm.scm が 無いと言って make test が通りません。skimu
- アドバイスありがとうございます。 完全にソースディレクトリ消して tarball の展開からやり直しました。 configure が何事もなく終了したので期待したけど、 make は途中からエラーストップしちゃいました。 ん〜、ちょっと煮詰まったな。。。今夜のところはあきらめてフテ寝します。cut-sea:2003/09/13 10:39:39 PDT
- 0.7.1 リリース版だと libcharconv.so をつくるところでエラーになりました。 ``-o'' で終わらなきゃ行けない LDFLAGS に `+=' でライブラリのサーチパスを追加してるのが原因。 本日9/14/03の CVS 版だと正常にビルドできます。skimu
- CVS 版を 取り出してみました。 ところが、いそいそと喜び勇んで HACKING をみたら、 autoconf 2.54 以上ねって。 ちなみに私の方の環境では pkgsrc から入ったやつで 2.12 (TワT)古すぎて涙 環境から整えていかないとダメですね〜。 (どんどん深みにはまってるな)cut-sea:2003/09/15 04:18:07 PDT