Bug #4909

trapハンドラは再入されてはいけないのではないか?

Added by Motohiro KOSAKI almost 4 years ago. Updated over 2 years ago.

[ruby-dev:43852]
Status:Closed
Priority:Normal
Assignee:Motohiro KOSAKI
ruby -v:- Backport:

Description

以下のプログラムは

if intrap == 1
raise "trap nested"
end

が真になってしまって例外終了してしまうのですが、これは起きてはいけないのではないでしょうか。
以下の二点が問題だと考えます。

1)このプログラムのようにシグナルを連続して配送されるとスタックオーバーフローを引き起こせる
2)Rubyレベルでsigprocmask()に相当するシグナルブロッキング操作が提供されていないため、
正しいトラップハンドラを書くのが、ほぼ不可能になっている

C言語ですら、シグナルハンドラ実行中はシグナルが自動的にマスクされるんですから、Rubyでも
同レベルの配慮はMRIがおこなうべきだと思います。


n = 0
intrap = 0

parent = $$

trap(:USR1) {
if intrap == 1
raise "trap nested"
end
intrap = 1
10000.times {
n += 1
}
intrap = 0
}

fork do
Process.kill(:USR1, parent) while true
end

sleep 100


Related issues

Duplicates Ruby trunk - Bug #6009: Rapid signal delivery via kill(2) causes SystemStackError Closed 02/13/2012

History

#1 Updated by Masaya Tarui almost 4 years ago

  • ruby -v changed from ruby 1.9.3dev (2011-06-17 trunk 32146) [x86_64-darwin10.7.4] to -

#2 Updated by Masaya Tarui almost 4 years ago

同意します。
というか、いままでmaskされてないと知らなかった。

2011年6月20日18:46 Motohiro KOSAKI kosaki.motohiro@gmail.com:

Issue #4909 has been reported by Motohiro KOSAKI.


Bug #4909: trapハンドラは再入されてはいけないのではないか?
http://redmine.ruby-lang.org/issues/4909

Author: Motohiro KOSAKI
Status: Open
Priority: Normal
Assignee:
Category: core
Target version: 1.9.x
ruby -v: ruby 1.9.3dev (2011-06-17 trunk 32146) [x86_64-darwin10.7.4]

以下のプログラムは

if intrap == 1
raise "trap nested"
end

が真になってしまって例外終了してしまうのですが、これは起きてはいけないのではないでしょうか。
以下の二点が問題だと考えます。

1)このプログラムのようにシグナルを連続して配送されるとスタックオーバーフローを引き起こせる
2)Rubyレベルでsigprocmask()に相当するシグナルブロッキング操作が提供されていないため、
正しいトラップハンドラを書くのが、ほぼ不可能になっている

C言語ですら、シグナルハンドラ実行中はシグナルが自動的にマスクされるんですから、Rubyでも
同レベルの配慮はMRIがおこなうべきだと思います。


n = 0
intrap = 0

parent = $$

trap(:USR1) {
if intrap == 1
raise "trap nested"
end
intrap = 1
10000.times {
n += 1
}
intrap = 0
}

fork do
Process.kill(:USR1, parent) while true
end

sleep 100

http://redmine.ruby-lang.org

--
樽家昌也(Masaya TARUI)
No Tool,No Life.

#3 Updated by Koichi Sasada almost 4 years ago

 ささだです.

(2011/06/21 1:25), Masaya TARUI wrote:

同意します。
というか、いままでmaskされてないと知らなかった。

 mask するための新しい仕様が必要になると思いますが,さてこれを 1.9.3 に
入れますか? それとも,trap 中はどんな trap を再入禁止?

--
// SASADA Koichi at atdot dot net

#4 Updated by Yui NARUSE almost 4 years ago

  • Status changed from Open to Assigned
  • Assignee set to Koichi Sasada

#5 Updated by Koichi Sasada almost 3 years ago

こういう話もあったんですね.

POSIX signal を考えると,同じシグナルは mask しておく(遅延する)という感じでしょうか.
あ,POSIX signal の場合は遅延じゃなくて,単に捨てるんだっけ(realtime signal 以外).

それとも,trap 自体を禁止する感じでしょうか.

この仕組みは " Re: 非同期割り込みに対する対処案(日本語版)" と独立に作るべきか,混ぜちゃうべきか....

#6 Updated by Motohiro KOSAKI almost 3 years ago

こういう話もあったんですね.

POSIX signal を考えると,同じシグナルは mask しておく(遅延する)という感じでしょうか.
あ,POSIX signal の場合は遅延じゃなくて,単に捨てるんだっけ(realtime signal 以外).

C言語は遅延ですね。捨てられるのは2つ以上遅延した場合ですから

それとも,trap 自体を禁止する感じでしょうか.

この仕組みは " Re: 非同期割り込みに対する対処案(日本語版)" と独立に作るべきか,混ぜちゃうべきか....

これは構文拡張なしで問答無用でマスクしてしまえばすむと思ってます。
あんまり混ぜるメリットが分かってないんですけど、なにか思い当たるところあります?

この話は実際にスタックオーバーフローしたというバグレポートが来ているのでできれば2.0で直したい

#7 Updated by Koichi Sasada almost 3 years ago

(2012/06/26 6:24), KOSAKI Motohiro wrote:

こういう話もあったんですね.

POSIX signal を考えると,同じシグナルは mask しておく(遅延する)という感じでしょうか.
あ,POSIX signal の場合は遅延じゃなくて,単に捨てるんだっけ(realtime signal 以外).
C言語は遅延ですね。捨てられるのは2つ以上遅延した場合ですから

 なるほど.Ruby では何個もっときますかねえ.

それとも,trap 自体を禁止する感じでしょうか.

 こちら,どう思います? つまり,来たシグナルの trap だけを禁止,もしく
は trap 全部を禁止.

 そういえば,unmask をどうするか,だけど Ruby には要らない,でいいかなぁ.

この仕組みは " Re: 非同期割り込みに対する対処案(日本語版)" と独立に作るべきか,混ぜちゃうべきか....
これは構文拡張なしで問答無用でマスクしてしまえばすむと思ってます。
あんまり混ぜるメリットが分かってないんですけど、なにか思い当たるところあります?

Pros.
- mask/unmask の操作が,同じインターフェースでできる

Cons.
- なんか混ぜると複雑になってわけわからんくなりそう

 分けた方がわかりやすくて良さそう.

この話は実際にスタックオーバーフローしたというバグレポートが来ているのでできれば2.0で直したい

 そう思います.

--
// SASADA Koichi at atdot dot net

#8 Updated by Motohiro KOSAKI almost 3 years ago

2012/6/25 SASADA Koichi ko1@atdot.net:

(2012/06/26 6:24), KOSAKI Motohiro wrote:

こういう話もあったんですね.

POSIX signal を考えると,同じシグナルは mask しておく(遅延する)という感じでしょうか.
あ,POSIX signal の場合は遅延じゃなくて,単に捨てるんだっけ(realtime signal 以外).
C言語は遅延ですね。捨てられるのは2つ以上遅延した場合ですから

 なるほど.Ruby では何個もっときますかねえ.

それとも,trap 自体を禁止する感じでしょうか.

 こちら,どう思います? つまり,来たシグナルの trap だけを禁止,もしく
は trap 全部を禁止.

全部禁止がいいと思います。一番分かりやすい

 そういえば,unmask をどうするか,だけど Ruby には要らない,でいいかなぁ.

いらないんじゃないかなあ。それが必要になるぐらい重い処理をtrapでやるのはそもそも
間違ってると主張してみる

この仕組みは " Re: 非同期割り込みに対する対処案(日本語版)" と独立に作るべきか,混ぜちゃうべきか....
これは構文拡張なしで問答無用でマスクしてしまえばすむと思ってます。
あんまり混ぜるメリットが分かってないんですけど、なにか思い当たるところあります?

Pros.
- mask/unmask の操作が,同じインターフェースでできる

Cons.
- なんか混ぜると複雑になってわけわからんくなりそう

 分けた方がわかりやすくて良さそう.

そう思います

#9 Updated by Koichi Sasada over 2 years ago

  • Assignee changed from Koichi Sasada to Motohiro KOSAKI

小崎先生にお任せ.

#10 Updated by Motohiro KOSAKI over 2 years ago

  • Status changed from Assigned to Closed

#6009と重複しているので、こちらのチケットは閉じますね。英語のほうを残します。

Also available in: Atom PDF