Bug #943

Segmentation fault (cygwin)

Added by Martin Dürst about 3 years ago. Updated 10 months ago.

[ruby-dev:37646]
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

Revision 21163
Added by Koichi Sasada about 3 years ago

* 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     

Also available in: Atom PDF