From: "H.Yamamoto" Date: 2005-06-11T19:39:13+09:00 Subject: [ruby-dev:26332] Re: ruby_setenv dumps core with mod_ruby/1.4.2 山本です。 >えーと、どのくらい動作が違うのかコードを見てもよく分からない >んですが。ちょっときれいになっているのは認めますが。 >もうちょっと説明してくださいませんか。 違いがわからないというのは、オリジナルと私のパッチの違いが わからない、ということでしょうか?(私の出した2つのパッチに 動作の違いはありません。単に同じコードが2つあって冗長なので まとめただけです) Index: hash.c =================================================================== RCS file: /src/ruby/hash.c,v retrieving revision 1.128.2.11 diff -u -w -b -p -r1.128.2.11 hash.c --- hash.c 28 Feb 2005 02:45:20 -0000 1.128.2.11 +++ hash.c 10 Jun 2005 08:47:16 -0000 @@ -1855,7 +1855,9 @@ ruby_setenv(name, value) environ[i+1] = 0; /* make sure it's null terminated */ } else { - if (environ[i] != origenviron[i]) + char **envp = origenviron; + while (*envp && *envp != environ[i]) envp++; + if (!*envp) free(environ[i]); } environ[i] = ALLOC_N(char, strlen(name) + strlen(value) + 2); origenviron は起動時に environ だった元々の環境変数を退避してるだけなので 長さは変わらず、(少なくとも grep したところでは変更されていないようでした) environ のほうは ruby 側で環境変数を追加するたびに伸びていくので、そのうち origenviron の範囲外の値が int i=envix(name) で返ってきて origenviron[i] が まずいんじゃないかと思いました。上の !value なときの条件判断には こんな問題はないので、こちらが正しかろうと思い流用しました。 本当は environ の要素は全部 strdup されたものなので origenviron を 調べなくてもいきなり free してよさそうに思ったのですが、わざわざ 条件判断で弾いてるからには理由があるのだろうと思って >>たぶん、条件文は万が一にも origenviron な文字列を free しないようにする >>セーフガードだと思うので、(ruby 以外が environ に直接ポインタを設定してしまうとか) という理由をとってつけたのです。 # とはいえ、2.times { 50.times {|i| ENV[i.to_s] = i.to_s } } # なんてしても BeOS ではいっこうに落ちなかったのですが・・・