[ruby-trunk - Bug #7774][Assigned] IFUNC上のbinding呼び出しでSEGV

Issue #7774 has been reported by ktsj (Kazuki Tsujimoto).


Bug #7774: IFUNC上のbinding呼び出しでSEGV

Author: ktsj (Kazuki Tsujimoto)
Status: Assigned
Priority: High
Assignee: ko1 (Koichi Sasada)
Category: core
Target version: 2.0.0
ruby -v: ruby 2.0.0dev (2013-02-03 trunk 39032) [x86_64-linux]

=begin
辻本です。

以下のコードでSEGVします。

tp = TracePoint.new(:raise) do |tp|
tp.binding
end
tp.enable

@obj = Object.new
class << @obj
include Enumerable
def each
yield 1
end
end

@obj.zip({}) {}

バックトレースは以下の通り。

#0 0x00007ffff6ef7445 in raise () from /lib/x86_64-linux-gnu/libc.so.6
#1 0x00007ffff6efabab in abort () from /lib/x86_64-linux-gnu/libc.so.6
#2 0x00005555555ad998 in rb_bug (fmt=0x55555573ecd7 “Segmentation
fault”) at error.c:309
#3 0x000055555567f32f in sigsegv (sig=11, info=0x555555a5aa70,
ctx=0x555555a5a940) at signal.c:649
#4
#5 0x00005555556ea894 in VM_EP_LEP (ep=0xc) at vm.c:28
#6 0x00005555556ea8ec in VM_CF_LEP (cfp=0x7ffff6b08e80) at vm.c:44
#7 0x00005555556ea91f in VM_CF_BLOCK_PTR (cfp=0x7ffff6b08e80) at
vm.c:56
#8 0x0000555555700f57 in check_block (th=0x5555559f0590) at vm.c:646
#9 0x0000555555700fff in vm_yield (th=0x5555559f0590, argc=1,
argv=0x7fffffffba38) at vm.c:666
#10 0x00005555556fd6d3 in rb_yield_0 (argc=1, argv=0x7fffffffba38) at
vm_eval.c:897
#11 0x00005555556fd70d in rb_yield (val=93824999078160) at
vm_eval.c:907
#12 0x00005555555a63c4 in zip_i (val=3, memo=0x555555bdb960, argc=1,
argv=0x7ffff6a09070) at enum.c:2001

binding呼び出しによって環境がヒープに移されますが、
IFUNC上のepがそれに追随できていないのが原因です。

以下の拡張ライブラリのコードでも再現させることができるので、
TracePointのバグというよりはVMのバグといえそうです。

static VALUE
segv_i(VALUE i, VALUE ary, int argc, VALUE *argv)
{
rb_binding_new();
rb_yield(Qnil);
return Qnil;
}

VALUE
rb_segv(VALUE obj)
{
rb_block_call(obj, rb_intern(“m”), 0, 0, segv_i, 0);
return Qnil;
}
=end

(2013/02/03 18:14), ktsj (Kazuki Tsujimoto) wrote:

binding呼び出しによって環境がヒープに移されますが、
IFUNC上のepがそれに追随できていないのが原因です。

あーあーきこえなーい.

じゃなくて,ええと,IFUNC 回りはてきとーですよね.どうしようかな.

RC2 っていつ頃出します?

2013$BG/(B2$B7n(B3$BF|(B 18:35 SASADA Koichi [email protected]:

$B!!(BRC2 $B$C$F$$$D:"=P$7$^$9!)(B

$BO"Mm$7$F$J$/$F$9$_$^$;$s!#(B

rubygems.org $B$N;v7o$K4XO"$7$F(B Eric H. $B$,2?$+$7$i(B rubygems
$B$K(B
$BBP=h$,I,MW$+$r8!F$$7$?$$$H8@$C$F$$$F!"$=$N6qBNE*$J%W%i%s$rLd$$(B
$B9g$o$;$F$$$k$H$3$m$G$9!#!J:#F|Cf$KJV;v$h$3$;$H8@$C$?!K(B

$BL@F|$K$O2?$+$7$i$N%"%J%&%s%9$r=P$7$?$$$H;W$$$^$9!#(B

Issue #7774 has been reported by ktsj (Kazuki Tsujimoto).


Bug #7774: IFUNC上のbinding呼び出しでSEGV
Bug #7774: IFUNC上のbinding呼び出しでSEGV - Ruby master - Ruby Issue Tracking System

ご報告,ありがとうございました.多分,治ったんじゃないかと思います.

binding呼び出しによって環境がヒープに移されますが、
IFUNC上のepがそれに追随できていないのが原因です。

ご指摘の通りでしたので,IFUNC であっても binding が作れるようにしまし
た.何かまずいことでも起こるかなと試してみたんですが,ちょっと試したとこ
ろ大丈夫そうでした.

finish frame も無くしたので,この辺全部整理したい.

(2013/02/05 16:47), ktsj (Kazuki Tsujimoto) wrote:

が、次のコードがSEGVするようになってしまいました。

がーん.callcc 使ったコードなんて知らん,とは言えないかなぁ.
これは何が起きている?

Issue #7774 has been updated by ktsj (Kazuki Tsujimoto).

ご対応ありがとうございます。
が、次のコードがSEGVするようになってしまいました。

require ‘continuation’

tp = TracePoint.new(:raise) do |tp|
tp.binding
end
tp.enable do
obj = Object.new
class << obj
include Enumerable
def each
yield 1
end
end
c = nil
obj.sort_by {|x| callcc {|c2| c ||= c2 }; x }
c.call
end


Bug #7774: IFUNC上のbinding呼び出しでSEGV

Author: ktsj (Kazuki Tsujimoto)
Status: Closed
Priority: High
Assignee: ko1 (Koichi Sasada)
Category: core
Target version: 2.0.0
ruby -v: ruby 2.0.0dev (2013-02-03 trunk 39032) [x86_64-linux]

=begin
辻本です。

以下のコードでSEGVします。

tp = TracePoint.new(:raise) do |tp|
tp.binding
end
tp.enable

@obj = Object.new
class << @obj
include Enumerable
def each
yield 1
end
end

@obj.zip({}) {}

バックトレースは以下の通り。

#0 0x00007ffff6ef7445 in raise () from /lib/x86_64-linux-gnu/libc.so.6
#1 0x00007ffff6efabab in abort () from /lib/x86_64-linux-gnu/libc.so.6
#2 0x00005555555ad998 in rb_bug (fmt=0x55555573ecd7 “Segmentation
fault”) at error.c:309
#3 0x000055555567f32f in sigsegv (sig=11, info=0x555555a5aa70,
ctx=0x555555a5a940) at signal.c:649
#4
#5 0x00005555556ea894 in VM_EP_LEP (ep=0xc) at vm.c:28
#6 0x00005555556ea8ec in VM_CF_LEP (cfp=0x7ffff6b08e80) at vm.c:44
#7 0x00005555556ea91f in VM_CF_BLOCK_PTR (cfp=0x7ffff6b08e80) at
vm.c:56
#8 0x0000555555700f57 in check_block (th=0x5555559f0590) at vm.c:646
#9 0x0000555555700fff in vm_yield (th=0x5555559f0590, argc=1,
argv=0x7fffffffba38) at vm.c:666
#10 0x00005555556fd6d3 in rb_yield_0 (argc=1, argv=0x7fffffffba38) at
vm_eval.c:897
#11 0x00005555556fd70d in rb_yield (val=93824999078160) at
vm_eval.c:907
#12 0x00005555555a63c4 in zip_i (val=3, memo=0x555555bdb960, argc=1,
argv=0x7ffff6a09070) at enum.c:2001

binding呼び出しによって環境がヒープに移されますが、
IFUNC上のepがそれに追随できていないのが原因です。

以下の拡張ライブラリのコードでも再現させることができるので、
TracePointのバグというよりはVMのバグといえそうです。

static VALUE
segv_i(VALUE i, VALUE ary, int argc, VALUE *argv)
{
rb_binding_new();
rb_yield(Qnil);
return Qnil;
}

VALUE
rb_segv(VALUE obj)
{
rb_block_call(obj, rb_intern(“m”), 0, 0, segv_i, 0);
return Qnil;
}
=end

Issue #7774 has been updated by ktsj (Kazuki Tsujimoto).

rb_callccから呼ばれるrb_vm_stack_to_heapでも、
同様にIFUNCの対応が必要ということのようです。

以下のパッチで直りましたがどうでしょうか。

diff --git a/vm.c b/vm.c
index ef5dd97…1429cce 100644
— a/vm.c
+++ b/vm.c
@@ -556,7 +556,7 @@ void
rb_vm_stack_to_heap(rb_thread_t *th)
{
rb_control_frame_t *cfp = th->cfp;

  • while ((cfp = rb_vm_get_ruby_level_next_cfp(th, cfp)) != 0) {
  • while ((cfp = rb_vm_get_binding_creatable_next_cfp(th, cfp)) != 0)
    {
    rb_vm_make_env_object(th, cfp);
    cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
    }

Bug #7774: IFUNC上のbinding呼び出しでSEGV

Author: ktsj (Kazuki Tsujimoto)
Status: Closed
Priority: High
Assignee: ko1 (Koichi Sasada)
Category: core
Target version: 2.0.0
ruby -v: ruby 2.0.0dev (2013-02-03 trunk 39032) [x86_64-linux]

=begin
辻本です。

以下のコードでSEGVします。

tp = TracePoint.new(:raise) do |tp|
tp.binding
end
tp.enable

@obj = Object.new
class << @obj
include Enumerable
def each
yield 1
end
end

@obj.zip({}) {}

バックトレースは以下の通り。

#0 0x00007ffff6ef7445 in raise () from /lib/x86_64-linux-gnu/libc.so.6
#1 0x00007ffff6efabab in abort () from /lib/x86_64-linux-gnu/libc.so.6
#2 0x00005555555ad998 in rb_bug (fmt=0x55555573ecd7 “Segmentation
fault”) at error.c:309
#3 0x000055555567f32f in sigsegv (sig=11, info=0x555555a5aa70,
ctx=0x555555a5a940) at signal.c:649
#4
#5 0x00005555556ea894 in VM_EP_LEP (ep=0xc) at vm.c:28
#6 0x00005555556ea8ec in VM_CF_LEP (cfp=0x7ffff6b08e80) at vm.c:44
#7 0x00005555556ea91f in VM_CF_BLOCK_PTR (cfp=0x7ffff6b08e80) at
vm.c:56
#8 0x0000555555700f57 in check_block (th=0x5555559f0590) at vm.c:646
#9 0x0000555555700fff in vm_yield (th=0x5555559f0590, argc=1,
argv=0x7fffffffba38) at vm.c:666
#10 0x00005555556fd6d3 in rb_yield_0 (argc=1, argv=0x7fffffffba38) at
vm_eval.c:897
#11 0x00005555556fd70d in rb_yield (val=93824999078160) at
vm_eval.c:907
#12 0x00005555555a63c4 in zip_i (val=3, memo=0x555555bdb960, argc=1,
argv=0x7ffff6a09070) at enum.c:2001

binding呼び出しによって環境がヒープに移されますが、
IFUNC上のepがそれに追随できていないのが原因です。

以下の拡張ライブラリのコードでも再現させることができるので、
TracePointのバグというよりはVMのバグといえそうです。

static VALUE
segv_i(VALUE i, VALUE ary, int argc, VALUE *argv)
{
rb_binding_new();
rb_yield(Qnil);
return Qnil;
}

VALUE
rb_segv(VALUE obj)
{
rb_block_call(obj, rb_intern(“m”), 0, 0, segv_i, 0);
return Qnil;
}
=end

$BDTK$G$9!#(B

Subject: [ruby-dev:46921] Re: [ruby-dev:46908] [ruby-trunk -
Bug#7774][Assigned] IFUNC$B>e$N(Bbinding$B8F$S=P$7$G(BSEGV
From: SASADA Koichi [email protected]
Date: Tue, 5 Feb 2013 15:15:30 +0900

$B!!$4Js9p!$$"$j$,$H$&$4$6$$$^$7$?!%B?J,!$<#$C$?$s$8$c$J$$$+$H;W$$$^$9!%(B

$B$?$S$?$S$9$_$^$;$s!#$3$N=$@5$G$9$,!"2<5-$NJQ99$O0U?^$5$l$?$b$N$G$7$g$&$+!#(B

r39067$B$h$jA0$G$O!“(B+$B%a%=%C%I(B/inject$B%a%=%C%I$GNc30$,5/$-$?>l9g$ON>J}$H$b%a%=%C%I5/F0;~$N%3%s%F%-%9%H(B($BNc$G$O(Bmain)$B$N(Bbinding$B$,JV$C$F$-$F$$$?!#(B
*
r39067$B0J9_$O!”(Binject$B%a%=%C%I$GNc30$,5/$-$?>l9g$NF0$-$,JQ99$5$l%l%7!<%P$N(Bbinding$B$,JV$C$F$/$k$h$&$K$J$C$?!#(B(+$B%a%=%C%I$OJQ99$J$7(B)

$B8D?ME*$K$O$3$l$^$G$N5sF0$N$[$&$,JXMx$G$7$?!#(B

def m1(arg)
arg + nil
rescue
end

def m2(arg)
arg.inject(:+)
rescue
end

TracePoint

tp = TracePoint.new(:raise) do |tp|
$b = tp.binding
end

tp.enable do
m1(0)
p A: eval(‘self’, $b)
p B: eval(‘arg rescue nil’, $b)

m2([0, nil])
p C: eval(‘self’, $b)
p D: eval(‘arg rescue nil’, $b)
end

set_trace_func

set_trace_func ->(event, file, line, id, binding, klass) do
if event == ‘raise’
$b = binding
end
end

m1(0)
p E: eval(‘self’, $b)
p F: eval(‘arg rescue nil’, $b)

m2([0, nil])
p G: eval(‘self’, $b)
p H: eval(‘arg rescue nil’, $b)

r39066

{:A=>main}

{:B=>0}

{:C=>main}

{:D=>[0, nil]}

{:E=>main}

{:F=>0}

{:G=>main}

{:H=>[0, nil]}

r39067

{:A=>main}

{:B=>0}

{:C=>[0, nil]}

{:D=>nil}

{:E=>main}

{:F=>0}

{:G=>[0, nil]}

{:H=>nil}

$BDTK$G$9(B

Subject: [ruby-dev:46961] Re: [ruby-trunk - Bug #7774][Assigned]
IFUNC$B>e$N(Bbinding$B8F$S=P$7$G(BSEGV
From: SASADA Koichi [email protected]
Date: Sat, 9 Feb 2013 13:12:59 +0900

$B!!$H$^$!!$$3$s$J46$8$G!$!V8F$S=P$7B&$N%U%l!<%`$rJV$9!W$H$$$&;EMM$G$O$J(B
$B$+$C$?$o$1$G$9!%(B

$B!!$b$7!$0JA0$N5sF0$KLa$9$J$i!$(Bifuc $B$N(B binding $B$r:n$j$D$D!$(Bruby-level
$B%U(B
$B%l!<%$^$GAL$C$F!$$=$N(B ruby-level $B%U%l!<%$N(B binding
$B$rJV$9!$$H$$$&$N$,(B
$B;W$$$D$-$^$7$?!%$3$l$G2r7h$7$=$&$G$O$"$j$^$9!%(B

$B4JC1$K;EMM$r$^$H$a$k$H$3$s$J46$8$G$7$g$&$+!#(B

1.9.3/2.0.0rc1
Ruby$B%a%=%C%I(B:
$B:G8e$N(Bruby-level$B%U%l!<%(B($B8F$S=P$7B&%U%l!<%$+$I$&$+$OL54X78(B)
C$B%a%=%C%I(B: $BF1>e(B

2.0.0rc2
Ruby$B%a%=%C%I(B:
$B:G8e$N(Bruby-level$B%U%l!<%(B($B8F$S=P$7B&%U%l!<%$+$I$&$+$OL54X78(B)
C$B%a%=%C%I(B:
$B:G8e$N(Bruby-level$B$^$?$O(BC-level$B%U%l!<%`(B($B%a%=%C%I$N<BAu$K$h$k(B)

$BLa$9$K$7$F$b!"%?%$%_%s%0$,LdBj$G$9$M!#(B

(2013/02/09 12:12), Kazuki Tsujimoto wrote:

$B$?$S$?$S$9$_$^$;$s!#$3$N=$@5$G$9$,!"2<5-$NJQ99$O0U?^$5$l$?$b$N$G$7$g$&$+!#(B

r39067$B$h$jA0$G$O!"(B+$B%a%=%C%I(B/inject$B%a%=%C%I$GNc30$,5/$-$?>l9g$ON>J}$H$b%a%=%C%I5/F0;~$N%3%s%F%-%9%H(B($BNc$G$O(Bmain)$B$N(Bbinding$B$,JV$C$F$-$F$$$?!#(B

r39067$B0J9_$O!"(Binject$B%a%=%C%I$GNc30$,5/$-$?>l9g$NF0$-$,JQ99$5$l%l%7!<%P$N(Bbinding$B$,JV$C$F$/$k$h$&$K$J$C$?!#(B(+$B%a%=%C%I$OJQ99$J$7(B)

$B8D?ME*$K$O$3$l$^$G$N5sF0$N$[$&$,JXMx$G$7$?!#(B

$B!!3N$+$K!%5sF0$OJQ$o$i$J$$$H;W$C$F$$$?$s$@$1$I!$(Bbinding
$B$N0LCV$O$:$l$^$9(B
$B$J!%$I$&$7$?$b$N$G$9$+$M$’!%(B

$B!!@5D>!$$I$N(B binding
$B$rJV$9$+!$$C$F$-$A$s$H$7$?%3%s%;%s%5%9$,<h$l$F$J$$(B
$B$H;W$&$N$G$9$h!%$?$^$?$^!$(BC
$B$G<BAu$5$l$?$b$N$@$C$?>l9g$K$O!$$=$N>e$N%U(B
$B%l!<%`$N(B binding $B$,5"$C$F$-$F$$$k46$8$G$9!%(B

$B!!Nc$($P!$(BRuby $B$G(B + $B$r<BAu$7$?(B XYZZY
$B$H$$$&%/%i%9$,Nc30$rEG$/>l9g!$$d$O(B
$B$j8F$S=P$7B&$N%U%l!<%$G$O$J$/!$(BXYZZY#+ $B$N%U%l!<%$N(B Binding
$B%*%V%8%’%/(B
$B%H$,JV$j$^$9!%(B

def m1(arg)
arg + nil
rescue
end

def m2(arg)
arg.inject(:+)
rescue
end

class XYZZY
def +(o)
raise
end
end

TracePoint

tp = TracePoint.new(:raise) do |tp|
$b = tp.binding
end

tp.enable do
m1(0)
p A: eval(‘self’, $b)
p B: eval(‘arg rescue nil’, $b)

m2([0, nil])
p C: eval(‘self’, $b)
p D: eval(‘arg rescue nil’, $b)

m1(XYZZY.new)
p X: eval(‘self’, $b)
p Y: eval(‘arg rescue nil’, $b)
end

set_trace_func

set_trace_func ->(event, file, line, id, binding, klass) do
if event == ‘raise’
$b = binding
end
end

m1(0)
p E: eval(‘self’, $b)
p F: eval(‘arg rescue nil’, $b)

m2([0, nil])
p G: eval(‘self’, $b)
p H: eval(‘arg rescue nil’, $b)

m1(XYZZY.new)
p XX: eval(‘self’, $b)
p YY: eval(‘arg rescue nil’, $b)

#=>
ruby 2.0.0dev (2012-12-21 trunk 38515) [i386-mswin32_100]
t.rb:19: warning: shadowing outer local variable - tp
{:A=>main}
{:B=>0}
{:C=>main}
{:D=>[0, nil]}
{:X=>#XYZZY:0xb2a0d4}
{:Y=>nil}
{:E=>main}
{:F=>0}
{:G=>main}
{:H=>[0, nil]}
{:XX=>#XYZZY:0xb12a60}
{:YY=>nil}

$B!!$H$^$!!$$3$s$J46$8$G!$!V8F$S=P$7B&$N%U%l!<%`$rJV$9!W$H$$$&;EMM$G$O$J(B
$B$+$C$?$o$1$G$9!%(B

$B!!$b$7!$0JA0$N5sF0$KLa$9$J$i!$(Bifuc $B$N(B binding
$B$r:n$j$D$D!$(Bruby-level $B%U(B
$B%l!<%$^$GAL$C$F!$$=$N(B ruby-level $B%U%l!<%$N(B binding
$B$rJV$9!$$H$$$&$N$,(B
$B;W$$$D$-$^$7$?!%$3$l$G2r7h$7$=$&$G$O$"$j$^$9!%(B

$B!!$I$&$7$?$b$s$G$7$g$&$+!)(B

$B$I$N(B reversion $B$r%P%C%/%]!<%H$9$k$H$$$&OC!)(B

rc1 $B$+$i$N(B regression $B$J$i$^$“$$$$$H;W$$$^$9$,!”(B
$B=$@5$,Bg$-$$$H8e$m8~$-$K$J$k$+$b!#(B

2013$BG/(B2$B7n(B9$BF|(B 17:14 SASADA Koichi [email protected]:

SEGV
$B$rD>$9$H$-$K!$$&$C$+$j0U?^$7$J$$Hs8_49$,:.F~$5$l$F$7$^$$$^$7$?!$$H(B
$B$$$&M}6~$G!$$3$l$O(B 2_0_0
$B$N$[$&$K%P%C%/%]!<%H$7$F$b$$$$$G$7$g$&$+(B
$B!d(Bmame $B$5$s(B

Binding
$B$O$I$&<h$l$k$Y$-$+!$$K$D$$$F$O<B$O$=$s$J$K<+L@$G$O$J$$$N$G!$:#EY(B
$BC/$+5DO@$5$;$F2<$5$$!%$3$NJU!$:#$OK\Ev$K!V<BAu$,$=$&$@$C$?$+$i!W0J30$8$c(B
$B$J$$$h$&$J5$$,$7$F$$$^$9!%(B

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

Status changed from Closed to Assigned


Bug #7774: IFUNC上のbinding呼び出しでSEGV

Author: ktsj (Kazuki Tsujimoto)
Status: Assigned
Priority: High
Assignee: ko1 (Koichi Sasada)
Category: core
Target version: 2.0.0
ruby -v: ruby 2.0.0dev (2013-02-03 trunk 39032) [x86_64-linux]

=begin
辻本です。

以下のコードでSEGVします。

tp = TracePoint.new(:raise) do |tp|
tp.binding
end
tp.enable

@obj = Object.new
class << @obj
include Enumerable
def each
yield 1
end
end

@obj.zip({}) {}

バックトレースは以下の通り。

#0 0x00007ffff6ef7445 in raise () from /lib/x86_64-linux-gnu/libc.so.6
#1 0x00007ffff6efabab in abort () from /lib/x86_64-linux-gnu/libc.so.6
#2 0x00005555555ad998 in rb_bug (fmt=0x55555573ecd7 “Segmentation
fault”) at error.c:309
#3 0x000055555567f32f in sigsegv (sig=11, info=0x555555a5aa70,
ctx=0x555555a5a940) at signal.c:649
#4
#5 0x00005555556ea894 in VM_EP_LEP (ep=0xc) at vm.c:28
#6 0x00005555556ea8ec in VM_CF_LEP (cfp=0x7ffff6b08e80) at vm.c:44
#7 0x00005555556ea91f in VM_CF_BLOCK_PTR (cfp=0x7ffff6b08e80) at
vm.c:56
#8 0x0000555555700f57 in check_block (th=0x5555559f0590) at vm.c:646
#9 0x0000555555700fff in vm_yield (th=0x5555559f0590, argc=1,
argv=0x7fffffffba38) at vm.c:666
#10 0x00005555556fd6d3 in rb_yield_0 (argc=1, argv=0x7fffffffba38) at
vm_eval.c:897
#11 0x00005555556fd70d in rb_yield (val=93824999078160) at
vm_eval.c:907
#12 0x00005555555a63c4 in zip_i (val=3, memo=0x555555bdb960, argc=1,
argv=0x7ffff6a09070) at enum.c:2001

binding呼び出しによって環境がヒープに移されますが、
IFUNC上のepがそれに追随できていないのが原因です。

以下の拡張ライブラリのコードでも再現させることができるので、
TracePointのバグというよりはVMのバグといえそうです。

static VALUE
segv_i(VALUE i, VALUE ary, int argc, VALUE *argv)
{
rb_binding_new();
rb_yield(Qnil);
return Qnil;
}

VALUE
rb_segv(VALUE obj)
{
rb_block_call(obj, rb_intern(“m”), 0, 0, segv_i, 0);
return Qnil;
}
=end

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

Status changed from Closed to Assigned
Assignee changed from ko1 (Koichi Sasada) to mame (Yusuke E.)

反応が悪くて申し訳ないです。
先ほどコミットした r39275 になります。

SEGV はしませんが、若干の非互換となります。

Bug #7774: IFUNC上のbinding呼び出しでSEGV

Author: ktsj (Kazuki Tsujimoto)
Status: Assigned
Priority: High
Assignee: mame (Yusuke E.)
Category: core
Target version: 2.0.0
ruby -v: ruby 2.0.0dev (2013-02-03 trunk 39032) [x86_64-linux]

=begin
辻本です。

以下のコードでSEGVします。

tp = TracePoint.new(:raise) do |tp|
tp.binding
end
tp.enable

@obj = Object.new
class << @obj
include Enumerable
def each
yield 1
end
end

@obj.zip({}) {}

バックトレースは以下の通り。

#0 0x00007ffff6ef7445 in raise () from /lib/x86_64-linux-gnu/libc.so.6
#1 0x00007ffff6efabab in abort () from /lib/x86_64-linux-gnu/libc.so.6
#2 0x00005555555ad998 in rb_bug (fmt=0x55555573ecd7 “Segmentation
fault”) at error.c:309
#3 0x000055555567f32f in sigsegv (sig=11, info=0x555555a5aa70,
ctx=0x555555a5a940) at signal.c:649
#4
#5 0x00005555556ea894 in VM_EP_LEP (ep=0xc) at vm.c:28
#6 0x00005555556ea8ec in VM_CF_LEP (cfp=0x7ffff6b08e80) at vm.c:44
#7 0x00005555556ea91f in VM_CF_BLOCK_PTR (cfp=0x7ffff6b08e80) at
vm.c:56
#8 0x0000555555700f57 in check_block (th=0x5555559f0590) at vm.c:646
#9 0x0000555555700fff in vm_yield (th=0x5555559f0590, argc=1,
argv=0x7fffffffba38) at vm.c:666
#10 0x00005555556fd6d3 in rb_yield_0 (argc=1, argv=0x7fffffffba38) at
vm_eval.c:897
#11 0x00005555556fd70d in rb_yield (val=93824999078160) at
vm_eval.c:907
#12 0x00005555555a63c4 in zip_i (val=3, memo=0x555555bdb960, argc=1,
argv=0x7ffff6a09070) at enum.c:2001

binding呼び出しによって環境がヒープに移されますが、
IFUNC上のepがそれに追随できていないのが原因です。

以下の拡張ライブラリのコードでも再現させることができるので、
TracePointのバグというよりはVMのバグといえそうです。

static VALUE
segv_i(VALUE i, VALUE ary, int argc, VALUE *argv)
{
rb_binding_new();
rb_yield(Qnil);
return Qnil;
}

VALUE
rb_segv(VALUE obj)
{
rb_block_call(obj, rb_intern(“m”), 0, 0, segv_i, 0);
return Qnil;
}
=end

Issue #7774 has been updated by mame (Yusuke E.).

Assignee changed from mame (Yusuke E.) to ko1 (Koichi Sasada)

了解です。ありがとうございます。バックポートお願いします。


Yusuke E. [email protected]

Bug #7774: IFUNC上のbinding呼び出しでSEGV

Author: ktsj (Kazuki Tsujimoto)
Status: Assigned
Priority: High
Assignee: ko1 (Koichi Sasada)
Category: core
Target version: 2.0.0
ruby -v: ruby 2.0.0dev (2013-02-03 trunk 39032) [x86_64-linux]

=begin
辻本です。

以下のコードでSEGVします。

tp = TracePoint.new(:raise) do |tp|
tp.binding
end
tp.enable

@obj = Object.new
class << @obj
include Enumerable
def each
yield 1
end
end

@obj.zip({}) {}

バックトレースは以下の通り。

#0 0x00007ffff6ef7445 in raise () from /lib/x86_64-linux-gnu/libc.so.6
#1 0x00007ffff6efabab in abort () from /lib/x86_64-linux-gnu/libc.so.6
#2 0x00005555555ad998 in rb_bug (fmt=0x55555573ecd7 “Segmentation
fault”) at error.c:309
#3 0x000055555567f32f in sigsegv (sig=11, info=0x555555a5aa70,
ctx=0x555555a5a940) at signal.c:649
#4
#5 0x00005555556ea894 in VM_EP_LEP (ep=0xc) at vm.c:28
#6 0x00005555556ea8ec in VM_CF_LEP (cfp=0x7ffff6b08e80) at vm.c:44
#7 0x00005555556ea91f in VM_CF_BLOCK_PTR (cfp=0x7ffff6b08e80) at
vm.c:56
#8 0x0000555555700f57 in check_block (th=0x5555559f0590) at vm.c:646
#9 0x0000555555700fff in vm_yield (th=0x5555559f0590, argc=1,
argv=0x7fffffffba38) at vm.c:666
#10 0x00005555556fd6d3 in rb_yield_0 (argc=1, argv=0x7fffffffba38) at
vm_eval.c:897
#11 0x00005555556fd70d in rb_yield (val=93824999078160) at
vm_eval.c:907
#12 0x00005555555a63c4 in zip_i (val=3, memo=0x555555bdb960, argc=1,
argv=0x7ffff6a09070) at enum.c:2001

binding呼び出しによって環境がヒープに移されますが、
IFUNC上のepがそれに追随できていないのが原因です。

以下の拡張ライブラリのコードでも再現させることができるので、
TracePointのバグというよりはVMのバグといえそうです。

static VALUE
segv_i(VALUE i, VALUE ary, int argc, VALUE *argv)
{
rb_binding_new();
rb_yield(Qnil);
return Qnil;
}

VALUE
rb_segv(VALUE obj)
{
rb_block_call(obj, rb_intern(“m”), 0, 0, segv_i, 0);
return Qnil;
}
=end

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

r39305 で backport しました。

が、redmine のほうには backport issue にしていないから
自動的に close されてないんかな。


Bug #7774: IFUNC上のbinding呼び出しでSEGV

Author: ktsj (Kazuki Tsujimoto)
Status: Assigned
Priority: High
Assignee: ko1 (Koichi Sasada)
Category: core
Target version: 2.0.0
ruby -v: ruby 2.0.0dev (2013-02-03 trunk 39032) [x86_64-linux]

=begin
辻本です。

以下のコードでSEGVします。

tp = TracePoint.new(:raise) do |tp|
tp.binding
end
tp.enable

@obj = Object.new
class << @obj
include Enumerable
def each
yield 1
end
end

@obj.zip({}) {}

バックトレースは以下の通り。

#0 0x00007ffff6ef7445 in raise () from /lib/x86_64-linux-gnu/libc.so.6
#1 0x00007ffff6efabab in abort () from /lib/x86_64-linux-gnu/libc.so.6
#2 0x00005555555ad998 in rb_bug (fmt=0x55555573ecd7 “Segmentation
fault”) at error.c:309
#3 0x000055555567f32f in sigsegv (sig=11, info=0x555555a5aa70,
ctx=0x555555a5a940) at signal.c:649
#4
#5 0x00005555556ea894 in VM_EP_LEP (ep=0xc) at vm.c:28
#6 0x00005555556ea8ec in VM_CF_LEP (cfp=0x7ffff6b08e80) at vm.c:44
#7 0x00005555556ea91f in VM_CF_BLOCK_PTR (cfp=0x7ffff6b08e80) at
vm.c:56
#8 0x0000555555700f57 in check_block (th=0x5555559f0590) at vm.c:646
#9 0x0000555555700fff in vm_yield (th=0x5555559f0590, argc=1,
argv=0x7fffffffba38) at vm.c:666
#10 0x00005555556fd6d3 in rb_yield_0 (argc=1, argv=0x7fffffffba38) at
vm_eval.c:897
#11 0x00005555556fd70d in rb_yield (val=93824999078160) at
vm_eval.c:907
#12 0x00005555555a63c4 in zip_i (val=3, memo=0x555555bdb960, argc=1,
argv=0x7ffff6a09070) at enum.c:2001

binding呼び出しによって環境がヒープに移されますが、
IFUNC上のepがそれに追随できていないのが原因です。

以下の拡張ライブラリのコードでも再現させることができるので、
TracePointのバグというよりはVMのバグといえそうです。

static VALUE
segv_i(VALUE i, VALUE ary, int argc, VALUE *argv)
{
rb_binding_new();
rb_yield(Qnil);
return Qnil;
}

VALUE
rb_segv(VALUE obj)
{
rb_block_call(obj, rb_intern(“m”), 0, 0, segv_i, 0);
return Qnil;
}
=end

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

Status changed from Assigned to Closed


Bug #7774: IFUNC上のbinding呼び出しでSEGV

Author: ktsj (Kazuki Tsujimoto)
Status: Closed
Priority: High
Assignee: ko1 (Koichi Sasada)
Category: core
Target version: 2.0.0
ruby -v: ruby 2.0.0dev (2013-02-03 trunk 39032) [x86_64-linux]

=begin
辻本です。

以下のコードでSEGVします。

tp = TracePoint.new(:raise) do |tp|
tp.binding
end
tp.enable

@obj = Object.new
class << @obj
include Enumerable
def each
yield 1
end
end

@obj.zip({}) {}

バックトレースは以下の通り。

#0 0x00007ffff6ef7445 in raise () from /lib/x86_64-linux-gnu/libc.so.6
#1 0x00007ffff6efabab in abort () from /lib/x86_64-linux-gnu/libc.so.6
#2 0x00005555555ad998 in rb_bug (fmt=0x55555573ecd7 “Segmentation
fault”) at error.c:309
#3 0x000055555567f32f in sigsegv (sig=11, info=0x555555a5aa70,
ctx=0x555555a5a940) at signal.c:649
#4
#5 0x00005555556ea894 in VM_EP_LEP (ep=0xc) at vm.c:28
#6 0x00005555556ea8ec in VM_CF_LEP (cfp=0x7ffff6b08e80) at vm.c:44
#7 0x00005555556ea91f in VM_CF_BLOCK_PTR (cfp=0x7ffff6b08e80) at
vm.c:56
#8 0x0000555555700f57 in check_block (th=0x5555559f0590) at vm.c:646
#9 0x0000555555700fff in vm_yield (th=0x5555559f0590, argc=1,
argv=0x7fffffffba38) at vm.c:666
#10 0x00005555556fd6d3 in rb_yield_0 (argc=1, argv=0x7fffffffba38) at
vm_eval.c:897
#11 0x00005555556fd70d in rb_yield (val=93824999078160) at
vm_eval.c:907
#12 0x00005555555a63c4 in zip_i (val=3, memo=0x555555bdb960, argc=1,
argv=0x7ffff6a09070) at enum.c:2001

binding呼び出しによって環境がヒープに移されますが、
IFUNC上のepがそれに追随できていないのが原因です。

以下の拡張ライブラリのコードでも再現させることができるので、
TracePointのバグというよりはVMのバグといえそうです。

static VALUE
segv_i(VALUE i, VALUE ary, int argc, VALUE *argv)
{
rb_binding_new();
rb_yield(Qnil);
return Qnil;
}

VALUE
rb_segv(VALUE obj)
{
rb_block_call(obj, rb_intern(“m”), 0, 0, segv_i, 0);
return Qnil;
}
=end