Bug #2821
Dir.[] returns unmatched path
| Status: | Closed | Start date: | ||
|---|---|---|---|---|
| Priority: | Low | Due date: | ||
| Assignee: | - | % Done: | 100% |
|
| Category: | - | |||
| Target version: | - | |||
| ruby -v: |
Description
遠藤です。
mingw で sample/test.rb が失敗します。調べてみると、以下の Dir.[] の
呼び出し結果がおかしいような気がします。
$ cat t.rb
p Dir["C:/Ruby/ruby/{lib,sample,ext,test}/**/*.rb"].sort.first
$ ./ruby t.rb
"C:/Ruby/ruby/"
glob のパターンにマッチしていないと思うのですが、どうでしょうか。
--
Yusuke ENDOH <mame@tsg.ne.jp>
Associated revisions
* dir.c (push_glob): add RB_GC_GUARD to prevent str being free'ed.
a patch from Masaya TARUI in [ruby-dev:40939]. [ruby-dev:40514]
History
Updated by Usaku NAKAMURA almost 2 years ago
こんにちは、なかむら(う)です。 In message "[ruby-dev:40514] [Bug:trunk] Dir.[] returns unmatched path" on Feb.27,2010 12:45:47, <mame@tsg.ne.jp> wrote: > mingw で sample/test.rb が失敗します。調べてみると、以下の Dir.[] の > 呼び出し結果がおかしいような気がします。 > > $ cat t.rb > p Dir["C:/Ruby/ruby/{lib,sample,ext,test}/**/*.rb"].sort.first > > $ ./ruby t.rb > "C:/Ruby/ruby/" > > glob のパターンにマッチしていないと思うのですが、どうでしょうか。 とりあえず、 ruby 1.9.2dev (2010-02-27 trunk 26772) [i386-mswin32] では再現しません(ext/bigdecimal/extconf.rbを正しく拾ってきます)。 Dir.[] にせよ Array#sort にせよ Array#first にせよmswinとmingw で挙動に違いはないはずですが... ところで、ruby -v(というかリビジョン)は? それでは。 -- U.Nakamura <usa@garbagecollect.jp>
Updated by Yusuke Endoh almost 2 years ago
遠藤です。 2010年2月27日13:07 U.Nakamura <usa@garbagecollect.jp>: >> glob のパターンにマッチしていないと思うのですが、どうでしょうか。 > > とりあえず、 > > ruby 1.9.2dev (2010-02-27 trunk 26772) [i386-mswin32] > > では再現しません(ext/bigdecimal/extconf.rbを正しく拾ってきます)。 > > Dir.[] にせよ Array#sort にせよ Array#first にせよmswinとmingw > で挙動に違いはないはずですが... あれれ。 > ところで、ruby -v(というかリビジョン)は? あ、すみません。 $ ./ruby -v t.rb ruby 1.9.2dev (2010-02-26) [i386-mingw32] "C:/Ruby/ruby/" です。 不思議なことに miniruby だとちゃんと動きました。 $ ./miniruby.exe -v t.rb ruby 1.9.2dev (2010-02-26) [i386-mingw32] "C:/Ruby/ruby/ext/bigdecimal/extconf.rb" -- Yusuke ENDOH <mame@tsg.ne.jp>
Updated by Usaku NAKAMURA almost 2 years ago
こんにちは、なかむら(う)です。 In message "[ruby-dev:40518] Re: [Bug:trunk] Dir.[] returns unmatched path" on Feb.27,2010 13:17:21, <mame@tsg.ne.jp> wrote: > > ところで、ruby -v(というかリビジョン)は? > > あ、すみません。 > > $ ./ruby -v t.rb > ruby 1.9.2dev (2010-02-26) [i386-mingw32] > "C:/Ruby/ruby/" > > です。 ふうむ、ちなみにこちらでは2010-02-08でも大丈夫でした。 > 不思議なことに miniruby だとちゃんと動きました。 > > $ ./miniruby.exe -v t.rb > ruby 1.9.2dev (2010-02-26) [i386-mingw32] > "C:/Ruby/ruby/ext/bigdecimal/extconf.rb" なにそれこわい。 minirubyとrubyでglobに違いはないような... ... あ、ありました。encoding絡み。 でもシステムから取ってるからやっぱり同じ結果になるような気も するんだけどなあ。 それでは。 -- U.Nakamura <usa@garbagecollect.jp>
Updated by Masaya Tarui almost 2 years ago
樽家といいます。
dir.cにおいて、ruby_brace_expand関数のstrがwhile(p<rbrace)ループ内の途中で壊れて
不定になるのが直接の原因でした。
GCが起きると壊れるので、潜在的に問題のあった環境では、
100.times{
a= Dir["#{dir}{ext,ext,ext,ext,ext,ext,ext,ext,ext,ext,ext,ext,ext,ext,ext,ext,ext,ext,ext,ext,ext,ext,ext,ext,ext,ext,win32}/**/*.rb"].sort
p [a.select{|i| i=~/win32/}.size,a.size,a[0]]
}
とかするとSEGVを含めおかしな結果を出すと思います。
元をたどればpush_glob関数内でRSTRING_PTR(str)を渡しているのに、
strがGCでmarkされずに回収されるためなので、
以下のpatch(IRCで教えてもらったpatchですが)で直る事を確認しました。
#GC怖い
>svn diff dir.c
Index: dir.c
===================================================================
--- dir.c (リビジョン 27267)
+++ dir.c (作業コピー)
@@ -1622,14 +1622,17 @@
{
struct glob_args args;
rb_encoding *enc = rb_enc_get(str);
+ int ret;
if (enc == rb_usascii_encoding()) enc = rb_filesystem_encoding();
args.func = push_pattern;
args.value = ary;
args.enc = enc;
-
- return ruby_brace_glob0(RSTRING_PTR(str), flags | GLOB_VERBOSE,
- rb_glob_caller, (VALUE)&args, enc);
+
+ ret = ruby_brace_glob0(RSTRING_PTR(str), flags | GLOB_VERBOSE,
+ rb_glob_caller, (VALUE)&args, enc);
+ RB_GC_GUARD(str);
+ return ret;
}
static VALUE
2010年2月27日13:35 U.Nakamura <usa@garbagecollect.jp>:
> こんにちは、なかむら(う)です。
>
> In message "[ruby-dev:40518] Re: [Bug:trunk] Dir.[] returns unmatched path"
> on Feb.27,2010 13:17:21, <mame@tsg.ne.jp> wrote:
>> > ところで、ruby -v(というかリビジョン)は?
>>
>> あ、すみません。
>>
>> $ ./ruby -v t.rb
>> ruby 1.9.2dev (2010-02-26) [i386-mingw32]
>> "C:/Ruby/ruby/"
>>
>> です。
>
> ふうむ、ちなみにこちらでは2010-02-08でも大丈夫でした。
>
>
>> 不思議なことに miniruby だとちゃんと動きました。
>>
>> $ ./miniruby.exe -v t.rb
>> ruby 1.9.2dev (2010-02-26) [i386-mingw32]
>> "C:/Ruby/ruby/ext/bigdecimal/extconf.rb"
>
> なにそれこわい。
>
> minirubyとrubyでglobに違いはないような... ...
> あ、ありました。encoding絡み。
> でもシステムから取ってるからやっぱり同じ結果になるような気も
> するんだけどなあ。
>
>
> それでは。
> --
> U.Nakamura <usa@garbagecollect.jp>
>
>
>
--
Masaya TARUI
mailto: tarui@prx.jp
Updated by Yusuke Endoh almost 2 years ago
遠藤です。 2010年4月9日19:08 Masaya TARUI <tarui@prx.jp>: > 元をたどればpush_glob関数内でRSTRING_PTR(str)を渡しているのに、 > strがGCでmarkされずに回収されるためなので、 > > 以下のpatch(IRCで教えてもらったpatchですが)で直る事を確認しました。 もう手元の mingw 環境は消してしまったので再試はしていないのですが、 明らかにまずいコードであり、樽家さんの環境では直るとのことなので、 取り込みました。 すばらしい調査でした。ありがとうございます。 -- Yusuke ENDOH <mame@tsg.ne.jp>
Updated by Yusuke Endoh almost 2 years ago
- Status changed from Open to Closed
- % Done changed from 0 to 100
This issue was solved with changeset r27268. Yusuke, thank you for reporting this issue. Your contribution to Ruby is greatly appreciated. May Ruby be with you.
Updated by Yukihiro Matsumoto almost 2 years ago
まつもと ゆきひろです In message "Re: [ruby-dev:40939] Re: [Bug:trunk] Dir.[] returns unmatched path" on Fri, 9 Apr 2010 19:08:26 +0900, Masaya TARUI <tarui@prx.jp> writes: |元をたどればpush_glob関数内でRSTRING_PTR(str)を渡しているのに、 |strがGCでmarkされずに回収されるためなので、 | |以下のpatch(IRCで教えてもらったpatchですが)で直る事を確認しました。 ありがとうございます。些細な改善と言えば RB_GC_GUARD を先にお いておけば、ret に戻り値を保存する必要はないように思います。 つまり RB_GC_GUARD(str); return ruby_brace_glob0(RSTRING_PTR(str), flags | GLOB_VERBOSE, rb_glob_caller, (VALUE)&args, enc); ということ。
Updated by Yusuke Endoh almost 2 years ago
遠藤です。 2010年4月9日20:21 Yukihiro Matsumoto <matz@ruby-lang.org>: > ありがとうございます。些細な改善と言えば RB_GC_GUARD を先にお > いておけば、ret に戻り値を保存する必要はないように思います。 > > つまり > > RB_GC_GUARD(str); > return ruby_brace_glob0(RSTRING_PTR(str), flags | GLOB_VERBOSE, > rb_glob_caller, (VALUE)&args, enc); > > ということ。 う、確かに。 そのパッチを書いたのは私なので、直しておきます。 -- Yusuke ENDOH <mame@tsg.ne.jp>