2005/11/01
昨日の続き。
- 途中経過のdumpからGC_written_bitsが上書きされている、と思ったのは誤認であった。 テストルーチンは問題が出る前にforkしており、先にdumpが出る子プロセスの方では GC_written_bitsが正しく設定されており、後にdumpが出てた親プロセスの方で GC_written_bitsが'0'のままであった。
- Solarisでは、dirty bitsを読むのにprocfsを使ってる。GC初期化時に自分のプロセスIDの ファイルをオープンして、ioctl(PIOCOPENPD)でpage data fileのディスクリプタを 得て保存。その後、GCがキックされる度に(GC_initiate_gc)そこからdirty bitsの 情報をread(2)する。read(2)の度にdirty bits情報はクリアされる。
- 仮説。page data file descriptorが親子で共有されるということは、 もしかして片方でread(2)するとそれがもう片方に影響を与えたりしない?
- もひとつ。page data file descriptorは /proc/<親のprocess-id> をopenした プロセスファイルから得たものなんだが、そのまま子がそれを参照してて 子自身のpage dirty bitsが取れるんだろうか。
- sunのサイトにもforkが絡んだ場合のpage data fileの説明が見当たらないし、 とりあえずこのへんの疑問点をgc-listに投げてみた。
Gauche的には、今回の問題だけに関してはforkの前に強制的にgcを呼ぶようにすれば 回避できるな…
Tag: Gauche
2005/11/01
う〜。0.8.6リリース寸前にもたついている。
どうもメモリ絡みのやばいバグが潜んでる模様。 び?さんのレポートするMacOS X最新版での不具合もひょっとすると同根かも。 これまでの経過。
- こっちでテストできるプラットフォームのほとんどでテストは通ってるのだけれど、 SolarisでのテストがAssertion failedで落ちることが発覚。
- dlopenされるモジュール中のScmIdentifierであるべきオブジェクトが 全然違うオブジェクトに化けているので、gc絡みだろう
- root setの登録ミスをまず疑うが、値をダンプしたりScm_GCSentinelを 使ったりして調べてみると、 「root setとして登録されているアドレス範囲から参照されているにも かかわらず、GCされている」ことが発覚。gcのバグを疑い、gc/ 以下に突入。
- mark_rts.c, mark.c, os_dep.c と読んで、「root setに登録されているが、 ページに一度もdirty bitが立ったことがないことになっているのでmarkされていない」 ことが発覚。dirty bitはOSから得ているのに、おかしいぞ? OSのバグの可能性は低い…
- 「一度でもdirty bitが立ったことがある」ページはGC_written_pagesで 管理されている。このビットマップは、一度 '1' になったら決して '0' になることは ない。ところが、問題のページに該当するビットを追っていると、最初はちゃんと '1' になっているのに途中から '0' になっていることが判明。あれれ。
- 念のためビットマップのバックアップをstaticに確保しといて 比較するプローブを組み込んだら、今度はテストが通る。→ちうことは、 GaucheのどっかのコードがGCのデータ領域に間違って書き込んでるっちゅうことじゃん!
さすがにこの爆弾を抱えたまま出すわけにいかないので、引続き調査中。
Tag: Gauche
2005/10/05
Rubyだと色々やり方があるみたい。Gaucheでは
(use srfi-14) (char-set->string #[\w])
Tags: Programming, Gauche
2005/10/04
毎年恒例(?)、Franz社の2日間にわたるLispセミナーが今年も開催されるそうです。
「2日間みっちり! Lispチュートリアル&Lispセミナー&Lisp事例紹介」
去年はAllegro Common Lisp 7.0の正規表現ライブラリについて 発表させてもらったんですが、今年は残念ながら行けません。 1日目のJansによる「Lispゲームプログラミング」が気になるなあ。
Tag: Lisp
