From: KIMURA Koichi Date: 2008-05-26T13:51:15+09:00 Subject: [ruby-dev:34850] Re: Windows2000上でtrunkがビルドできない 木村です。 多分、原因にたどり着きました。 まず簡単なまとめ。 ・非Windows環境では発生しません。 ただし同一原因(後述)によるバグが別の箇所で発生するかもしれません。 (これに関してはソースを精査していないので杞憂かもしれません) ・たぶんビルド時の環境に影響される。 具体的にこれ、という条件までは絞れていません。 ・(Windowsであれば)OSの種別には依存しない。 (う)さんのところで発生しなかったのは一つ前の条件で何かを満たして いなかったからだと思われます。 次にバグの詳細について。 前回までで、file.c の file_expand_path の中に怪しい部分があるという ところまで絞れていましたが、この関数の末尾付近の #ifdef __CYGWIN__ if (lnk_added && len > 4 && STRCASECMP(wfd.cFileName + len - 4, ".lnk") == 0) { len -= 4; } #endif if (!p) p = buf; buflen = ++p - buf + len; rb_str_resize(result, buflen); ← これ memcpy(p, wfd.cFileName, len + 1); } } #endif if (tainted) OBJ_TAINT(result); rb_str_set_len(result, buflen); rb_enc_check(fname, result); return result; } rb_str_resize()が引き金を引いているのがわかりました。 この関数をどのようなパラメータで呼び出しているかを記録してみると、ビルド プロセスが落ちる直前に ./../file.c(file_expand_path 2881): buflen=43, len=11, filename='mdoc2man.rb' ./../file.c(file_expand_path 2881): buflen=6, len=3, filename='tmp' ./../file.c(file_expand_path 2890): buflen=6, len=3, original buflen=1026, filename='tmp'(0012A830) p=0120DA73, buf=0120DA70 buflen を6に設定しているのがわかりました。 ここを通過するすべての呼び出しについてこの長さを確認してみるとこの6と いうのは一回だけ(落ちる直前)にしか呼び出されていません。 1 6 19 31 1 32 1 33 (略) 2 142 1 144 1 146 1 147 試しに buflen が十分小さな値のときは rb_str_resize() を呼び出さないよう に細工すると、ビルドは成功します。 ここではたと思い出したのですが、メモリ使用効率を向上させるための一環と して、ある程度の長さ以下の文字列は RString構造体に押し込めるようになって ますよね? ということは、 ./../file.c(file_expand_path 2890): buflen=6, len=3, original buflen=1026, filename='tmp'(0012A830) p=0120DA73, buf=0120DA70 のように、文字列実体が EMBEDED されてない状態からされている状態へ 変更するような場合には特別な手当てがいるのではないでしょうか? ここまでくると修正はわたしの手に余る(よく理解していないので)ので、 申し訳ありませんがパッチはありません。 #単に rb_str_resize()しないでいいというのであれば別ですけど。 以上よろしくお願いします。 -- 木村浩一