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

Posted by Motohiro KOSAKI (Guest)
on 2011-06-20 11:47
(Received via mailing list)
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
Posted by Masaya TARUI (Guest)
on 2011-06-20 18:36
(Received via mailing list)
$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 
<kosaki.motohiro@gmail.com>:
Posted by SASADA Koichi (Guest)
on 2011-06-20 18:43
(Received via mailing list)
 ささだです.

(2011/06/21 1:25), Masaya TARUI wrote:
> 同意します。
> というか、いままでmaskされてないと知らなかった。

 mask するための新しい仕様が必要になると思いますが,さてこれを 1.9.3 に
入れますか? それとも,trap 中はどんな trap を再入禁止?
Posted by KOSAKI Motohiro (Guest)
on 2011-06-21 03:23
(Received via mailing list)
>  ささだです.
>
> (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ハンドラ
  実行中も禁止されない

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

よろしくお願いいたします。
Posted by Yui NARUSE (Guest)
on 2011-07-25 13:14
(Received via mailing list)
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
Posted by ko1 (Koichi Sasada) (Guest)
on 2012-06-25 22:25
(Received via mailing list)
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
Posted by KOSAKI Motohiro (Guest)
on 2012-06-25 23:25
(Received via mailing list)
> $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<N$F$k$s$@$C$1!J(Brealtime 
signal $B0J30!K!%(B

C$B8@8l$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
Posted by SASADA Koichi (Guest)
on 2012-06-25 23:32
(Received via mailing list)
(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<N$F$k$s$@$C$1!J(Brealtime 
signal $B0J30!K!%(B
> C$B8@8l$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 
$B$@$1$r6X;_!$$b$7$/(B
$B$O(B trap $BA4It$r6X;_!%(B

$B!!$=$&$$$($P!$(Bunmask $B$r$I$&$9$k$+!$$@$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
Posted by KOSAKI Motohiro (Guest)
on 2012-06-26 04:40
(Received via mailing list)
2012/6/25 SASADA Koichi <ko1@atdot.net>:
>
> $B!!$3$A$i!$$I$&;W$$$^$9!)!!$D$^$j!$Mh$?%7%0%J%k$N(B trap $B$@$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$&$9$k$+!$$@$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
Posted by ko1 (Koichi Sasada) (Guest)
on 2012-11-26 01:22
(Received via mailing list)
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
Posted by kosaki (Motohiro KOSAKI) (Guest)
on 2012-11-26 12:05
(Received via mailing list)
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
Please log in before posting. Registration is free and takes only a minute.
Existing account (Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
No account? Register here.