Project

General

Profile

Bug #943

Segmentation fault (cygwin)

Added by duerst (Martin Dürst) almost 11 years ago. Updated over 8 years ago.

Status:
Closed
Priority:
Normal
Assignee:
-
ruby -v:
Backport:
[ruby-dev:37646]

Description

=begin
次のスクリプトが Segmentation fault (core dumped) で終わります。

ruby -e 'puts "A=["; 0.upto(1000000) { puts " [22, 55]," }; puts "]"' | ruby

[ruby-dev:37611] で報告した問題を簡単化しました。問題は左側の ruby のではなく、
右側の ruby で起こります。

よろしくお願いします。 Martin.
=end

History

#1

Updated by yugui (Yuki Sonoda) almost 11 years ago

  • Target version set to 1.9.1 Release Candidate

=begin

=end

#2

Updated by ko1 (Koichi Sasada) almost 11 years ago

=begin
 ささだです.

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

=end

#3

Updated by ko1 (Koichi Sasada) almost 11 years ago

  • Status changed from Open to Closed
  • % Done changed from 0 to 100

=begin
Applied in changeset r21163.
=end

#4

Updated by duerst (Martin Dürst) almost 11 years ago

=begin
笹田さん、こんにちは。

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

=end

#5

Updated by ko1 (Koichi Sasada) almost 11 years ago

=begin
 ささだです.

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

=end

#6

Updated by duerst (Martin Dürst) almost 11 years ago

=begin
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

=end

Also available in: Atom PDF