[Ruby 1.9 - Bug #4909][Open] trapハンドラは再入されてはいけないのではないか?

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

$BF10U$7$^$9!#(B
$B$H$$$&$+!"$$$^$^$G(Bmask$B$5$l$F$J$$$HCN$i$J$+$C$?!#(B

2011$BG/(B6$B7n(B20$BF|(B18:46 Motohiro KOSAKI
[email protected]:

ささだです.

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

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

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

ささだです.

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

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

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

1.9.3には入れるべきではないと思います。基本的に今仕様の議論をしているものは
全部1.9.4送りという認識。(なので、targetを 1.9.x にセットした)

redmineに起票するのを一月遅らせるべきでした。すいません

maskの選択肢は以下の2つだと認識です
1)あるtrapを処理中はあらゆるtrapが発生しない
2)あるtrapを処理中は、同一シグナルはtrapされないが別シグナルは
トラップする(ネストされうる) ※C言語と同じ

要求仕様を整理すると
A)スタックオーバーフローしない
B)trapの再入は通常のスクリプトユーザの手に余るのでなるべく起こしたくない
C)SIGUSR1等のtrapで無限ループしてても、Ctrl-Cで終了して欲しい

という事かと思います。

Aは(1)(2)どちらでもみたされます。(2)でもシグナルの数が
有限なので。
問題は(B)と(C)があまり両立しない関係にあることです。おそらくナイーブな
プログラムはSignal-AのtrapハンドラにSignal-Bのトラップがネストしてきても
誤動作するでしょう。また、このようなタイミング問題はマニュアルに注意を書いた
ところでなくなりません。
しかし Ctrl-C で終了しない可能性を増やすのはたぶん苦情がきます。

よって以下の仕様を提案します。
・trapハンドラ実行中はいかなるtrapも発生しない(trapハンドラ終了まで遅延される)
・ただしtrapハンドラ未登録時のデフォルト動作(Interrupt例外発生)は、trapハンドラ
実行中も禁止されない

穴があるかもしれないので、叩いてください。

よろしくお願いいたします。

Issue #4909 has been updated by Yui NARUSE.

Status changed from Open to Assigned
Assignee set to Koichi Sasada


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

Author: Motohiro KOSAKI
Status: Assigned
Priority: Normal
Assignee: Koichi Sasada
Category: core
Target version: 1.9.x
ruby -v: -

以下のプログラムは

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

Issue #4909 has been updated by ko1 (Koichi Sasada).

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

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

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

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

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

Author: kosaki (Motohiro KOSAKI)
Status: Assigned
Priority: Normal
Assignee: ko1 (Koichi Sasada)
Category: core
Target version: 2.0.0
ruby -v: -

以下のプログラムは

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

$B$3$&$$$&OC$b$"$C$?$s$G$9$M!%(B

POSIX signal $B$r9M$($k$H!$F1$8%7%0%J%k$O(B mask
$B$7$F$*$/!JCY1d$9$k!K$H$$$&46$8$G$7$g$&$+!%(B
$B$"!$(BPOSIX signal $B$N>l9g$OCY1d$8$c$J$/$F!$C1$K<[email protected]$C$1!J(Brealtime
signal $B0J30!K!%(B

[email protected]$OCY1d$G$9$M!#<N$F$i$l$k$N$O#2$D0J>eCY1d$7$?>l9g$G$9$+$i(B

$B$=$l$H$b!$(Btrap $B<+BN$r6X;_$9$k46$8$G$7$g$&$+!%(B

$B$3$N;EAH$$O(B "[ruby-dev:45827] Re:
$BHsF14|3d$j9~$
$KBP$9$kBP=h0F!JF|K\8lHG!K(B"
$B$HFHN)$K:n$k$Y$-$+!$:.$<$A$c$&$Y$-$+(B…$B!%(B

$B$3$l$O9=J83HD%$J$7$GLdEzL5MQ$G%^%9%/$7$F$7$^$($P$9$`$H;W$C$F$^$9!#(B
$B$"$s$^$j:.$<$k%a%j%C%H$,J,$+$C$F$J$$$s$G$9$1$I!"$J$K$+;W$$Ev$?$k$H$3$m$"$j$^$9!)(B

$B$3$NOC$O<B:]$K%9%?%C%/%*!<%P!<%U%m!<$7$?$H$$$&%P%0%l%]!<%H$,Mh$F$$$k$N$G$G$-$l$P#2!%#0$GD>$7$?$$(B

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

$B$3$&$$$&OC$b$"$C$?$s$G$9$M!%(B

POSIX signal $B$r9M$($k$H!$F1$8%7%0%J%k$O(B mask
$B$7$F$*$/!JCY1d$9$k!K$H$$$&46$8$G$7$g$&$+!%(B

$B$"!$(BPOSIX signal $B$N>l9g$OCY1d$8$c$J$/$F!$C1$K<[email protected]$C$1!J(Brealtime
signal $B0J30!K!%(B
[email protected]$OCY1d$G$9$M!#<N$F$i$l$k$N$O#2$D0J>eCY1d$7$?>l9g$G$9$+$i(B

$B!!$J$k$[$I!%(BRuby $B$G$O2?8D$b$C$H$-$^$9$+$M$(!%(B

$B$=$l$H$b!$(Btrap $B<+BN$r6X;_$9$k46$8$G$7$g$&$+!%(B

$B!!$3$A$i!$$I$&;W$$$^$9!)!!$D$^$j!$Mh$?%7%0%J%k$N(B trap
[email protected]$1$r6X;!$$b$7$/(B
$B$O(B trap $BA4It$r6X;
!%(B

$B!!$=$&$$$($P!$(Bunmask $B$r$I$&[email protected]$1$I(B Ruby
$B$K$OMW$i$J$$!$$G$$$$$+$J$!!%(B

$B$3$N;EAH$$O(B "[ruby-dev:45827] Re:
$BHsF14|3d$j9~$
$KBP$9$kBP=h0F!JF|K\8lHG!K(B"
$B$HFHN)$K:n$k$Y$-$+!$:.$<$A$c$&$Y$-$+(B…$B!%(B
$B$3$l$O9=J83HD%$J$7$GLdEzL5MQ$G%^%9%/$7$F$7$^$($P$9$`$H;W$C$F$^$9!#(B

$B$"$s$^$j:.$<$k%a%j%C%H$,J,$+$C$F$J$$$s$G$9$1$I!"$J$K$+;W$$Ev$?$k$H$3$m$"$j$^$9!)(B

Pros.

  • mask/unmask $B$NA`:n$,!$F1$8%$%s%?!<%U%’!<%9$G$G$-$k(B

Cons.

  • $B$J$s$+:.$<$k$HJ#;($K$J$C$F$o$1$o$+$i$s$/$J$j$=$&(B

$B!!J,$1$?J}$,$o$+$j$d$9$/$FNI$5$=$&!%(B

$B$3$NOC$O<B:]$K%9%?%C%/%*!<%P!<%U%m!<$7$?$H$$$&%P%0%l%]!<%H$,Mh$F$$$k$N$G$G$-$l$P#2!%#0$GD>$7$?$$(B

$B!!$=$&;W$$$^$9!%(B

2012/6/25 SASADA Koichi [email protected]:

$B!!$3$A$i!$$I$&;W$$$^$9!)!!$D$^$j!$Mh$?%7%0%J%k$N(B trap [email protected]$1$r6X;!$$b$7$/(B
$B$O(B trap $BA4It$r6X;
!%(B

$BA4It6X;_$,$$$$$H;W$$$^$9!#0lHVJ,$+$j$d$9$$(B

$B!!$=$&$$$($P!$(Bunmask $B$r$I$&[email protected]$1$I(B Ruby
$B$K$OMW$i$J$$!$$G$$$$$+$J$!!%(B

$B$$$i$J$$$s$8$c$J$$$+$J$"!#$=$l$,I,MW$K$J$k$0$i$$=E$$=hM}$r(Btrap$B$G$d$k$N$O$=$b$=$b(B
$B4V0c$C$F$k$H<gD%$7$F$_$k(B

$B!!J,$1$?J}$,$o$+$j$d$9$/$FNI$5$=$&!%(B
$B$=$&;W$$$^$9(B

Issue #4909 has been updated by ko1 (Koichi Sasada).

Assignee changed from ko1 (Koichi Sasada) to kosaki (Motohiro KOSAKI)

小崎先生にお任せ.

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

Author: kosaki (Motohiro KOSAKI)
Status: Assigned
Priority: Normal
Assignee: kosaki (Motohiro KOSAKI)
Category: core
Target version: 2.0.0
ruby -v: -

以下のプログラムは

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

Issue #4909 has been updated by kosaki (Motohiro KOSAKI).

Status changed from Assigned to Closed

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


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

Author: kosaki (Motohiro KOSAKI)
Status: Closed
Priority: Normal
Assignee: kosaki (Motohiro KOSAKI)
Category: core
Target version: 2.0.0
ruby -v: -

以下のプログラムは

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

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs