Bug #943
Segmentation fault (cygwin)
| Status: | Closed | Start date: | 12/29/2008 | |
|---|---|---|---|---|
| Priority: | Normal | Due date: | ||
| Assignee: | - | % Done: | 100% |
|
| Category: | - | |||
| Target version: | 1.9.1 Release Candidate | |||
| ruby -v: |
Description
次のスクリプトが Segmentation fault (core dumped) で終わります。
ruby -e 'puts "A=["; 0.upto(1000000) { puts " [22, 55]," }; puts "]"' | ruby
[ruby-dev:37611] で報告した問題を簡単化しました。問題は左側の ruby のではなく、
右側の ruby で起こります。
よろしくお願いします。 Martin.
Associated revisions
* vm.c (vm_set_eval_stack, vm_set_main_stack, vm_set_top_stack):
check stack overflow. [ruby-dev:37646]
History
Updated by Yuki Sonoda about 3 years ago
- Target version set to 1.9.1 Release Candidate
Updated by Koichi Sasada about 3 years ago
ささだです.
Martin Du"rst wrote::
> 次のスクリプトが Segmentation fault (core dumped) で終わります。
>
> ruby -e 'puts "A=["; 0.upto(1000000) { puts " [22, 55]," }; puts "]"' | ruby
>
> [ruby-dev:37611] で報告した問題を簡単化しました。問題は左側の ruby のではなく、
> 右側の ruby で起こります。
スタックオーバーフローチェックが足りていませんでした.多分,これで直り
ます.手元では直りました.[ruby-dev:37611] のほうは試していないのです
が,見てもらえませんか.
Index: vm.c
===================================================================
--- vm.c (リビジョン 21150)
+++ vm.c (作業コピー)
@@ -77,6 +77,8 @@ vm_set_top_stack(rb_thread_t * th, VALUE
vm_push_frame(th, iseq, VM_FRAME_MAGIC_TOP,
th->top_self, 0, iseq->iseq_encoded,
th->cfp->sp, 0, iseq->local_size);
+
+ CHECK_STACK_OVERFLOW(th->cfp, iseq->stack_max);
}
static void
@@ -95,6 +97,8 @@ vm_set_eval_stack(rb_thread_t * th, VALU
if (cref) {
th->cfp->dfp[-1] = (VALUE)cref;
}
+
+ CHECK_STACK_OVERFLOW(th->cfp, iseq->stack_max);
}
static void
@@ -116,6 +120,8 @@ vm_set_main_stack(rb_thread_t *th, VALUE
if (bind && iseq->local_size > 0) {
bind->env = vm_make_env_object(th, th->cfp);
}
+
+ CHECK_STACK_OVERFLOW(th->cfp, iseq->stack_max);
}
rb_control_frame_t *
--
// SASADA Koichi at atdot dot net
Updated by Koichi Sasada about 3 years ago
- Status changed from Open to Closed
- % Done changed from 0 to 100
Applied in changeset r21163.
Updated by Martin Dürst about 3 years ago
笹田さん、こんにちは。
At 16:18 08/12/29, SASADA Koichi wrote:
> ささだです.
>
>Martin Du"rst wrote::
>> 次のスクリプトが Segmentation fault (core dumped) で終わります。
>>
>> ruby -e 'puts "A=["; 0.upto(1000000) { puts " [22, 55]," }; puts "]"' | ruby
>>
>> [ruby-dev:37611] で報告した問題を簡単化しました。問題は左側の ruby のではなく、
>> 右側の ruby で起こります。
>
> スタックオーバーフローチェックが足りていませんでした.多分,これで直り
>ます.手元では直りました.[ruby-dev:37611] のほうは試していないのです
>が,見てもらえませんか.
以下の修正で上記の問題も [ruby-dev:37611] も直っています。
というのは、Segmentation fault から SystemStackError に
変わっただけです。その方がいいですので、是非下記のパッチを
コミットしてください。
しかし、真っ平らなデータを読み込むだけでスタックがこんなに伸びる
のはなぜでしょうか。上記のスクリプトを
ruby -e 'puts "A=[]"; 0.upto(1000000) { puts "A<<[22, 55]" }' | ruby
に直すと、時間がかかるものの、問題なく完成されます。
よろしくお願いします。 Martin.
>Index: vm.c
>===================================================================
>--- vm.c (リビジョン 21150)
>+++ vm.c (作業コピー)
>@@ -77,6 +77,8 @@ vm_set_top_stack(rb_thread_t * th, VALUE
> vm_push_frame(th, iseq, VM_FRAME_MAGIC_TOP,
> th->top_self, 0, iseq->iseq_encoded,
> th->cfp->sp, 0, iseq->local_size);
>+
>+ CHECK_STACK_OVERFLOW(th->cfp, iseq->stack_max);
> }
>
> static void
>@@ -95,6 +97,8 @@ vm_set_eval_stack(rb_thread_t * th, VALU
> if (cref) {
> th->cfp->dfp[-1] = (VALUE)cref;
> }
>+
>+ CHECK_STACK_OVERFLOW(th->cfp, iseq->stack_max);
> }
>
> static void
>@@ -116,6 +120,8 @@ vm_set_main_stack(rb_thread_t *th, VALUE
> if (bind && iseq->local_size > 0) {
> bind->env = vm_make_env_object(th, th->cfp);
> }
>+
>+ CHECK_STACK_OVERFLOW(th->cfp, iseq->stack_max);
> }
>
> rb_control_frame_t *
>
>
>--
>// SASADA Koichi at atdot dot net
#-#-# Martin J. Du"rst, Assoc. Professor, Aoyama Gakuin University
#-#-# http://www.sw.it.aoyama.ac.jp mailto:duerst@it.aoyama.ac.jp
Updated by Koichi Sasada about 3 years ago
ささだです. Martin Duerst wrote:: > 以下の修正で上記の問題も [ruby-dev:37611] も直っています。 > というのは、Segmentation fault から SystemStackError に > 変わっただけです。その方がいいですので、是非下記のパッチを > コミットしてください。 > > しかし、真っ平らなデータを読み込むだけでスタックがこんなに伸びる > のはなぜでしょうか。上記のスクリプトを > > ruby -e 'puts "A=[]"; 0.upto(1000000) { puts "A<<[22, 55]" }' | ruby > > に直すと、時間がかかるものの、問題なく完成されます。 [e1, e2, ..., eN] というリテラルは,一度 e1, e2, ..., eN を全部スタッ クに積んで,スタック上の値を利用して配列を作ります.そのため,スタック オーバーフローになります. 上記例のように,空の配列を作って,それに push するように変更することも 可能ですが,それを出来るようにしたほうがいいですかねぇ.するにしても, 1.9.2 で命令追加ってことになると思いますが.そう変更したら,ちょっと速度 が遅くなるってくらいかなぁ. -- // SASADA Koichi at atdot dot net
Updated by Martin Dürst about 3 years ago
At 17:19 08/12/29, SASADA Koichi wrote:
> ささだです.
>
>Martin Duerst wrote::
>> しかし、真っ平らなデータを読み込むだけでスタックがこんなに伸びる
>> のはなぜでしょうか。上記のスクリプトを
>>
>> ruby -e 'puts "A=[]"; 0.upto(1000000) { puts "A<<[22, 55]" }' | ruby
>>
>> に直すと、時間がかかるものの、問題なく完成されます。
>
> [e1, e2, ..., eN] というリテラルは,一度 e1, e2, ..., eN を全部スタッ
>クに積んで,スタック上の値を利用して配列を作ります.そのため,スタック
>オーバーフローになります.
そのぐらいは想像が付きました。
> 上記例のように,空の配列を作って,それに push するように変更することも
>可能ですが,それを出来るようにしたほうがいいですかねぇ.するにしても,
>1.9.2 で命令追加ってことになると思いますが.そう変更したら,ちょっと速度
>が遅くなるってくらいかなぁ.
こんなにでかい「定数」の配列はどのぐらい必要になるのかは分かりませんが、
「定数から追加に記述を変更してください。」と言う必要がでてくるのは
何となく逆のような気がする。まあ、1.9.2 とかの段階でじっくり考えた
方がいいと思います。
よろしくお願いします。 Martin.
#-#-# Martin J. Du"rst, Assoc. Professor, Aoyama Gakuin University
#-#-# http://www.sw.it.aoyama.ac.jp mailto:duerst@it.aoyama.ac.jp