[前][次][番号順一覧][スレッド一覧]

ruby-changes:56743

From: =E5=8D=9C=E9=83=A8=E6=98=8C=E5=B9=B3 <ko1@a...>
Date: Thu, 1 Aug 2019 16:04:25 +0900 (JST)
Subject: [ruby-changes:56743] 卜部昌平: 5d33f78716 (master): fix tracepoint + backtrace SEGV

https://git.ruby-lang.org/ruby.git/commit/?id=5d33f78716

From 5d33f787169bcc3594d2264726695d58c4a06899 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=8D=9C=E9=83=A8=E6=98=8C=E5=B9=B3?=
 <shyouhei@r...>
Date: Wed, 31 Jul 2019 23:00:15 +0900
Subject: fix tracepoint + backtrace SEGV

PC modification in gc_event_hook_body was careless.  There are (so
to say) abnormal iseqs stored in the cfp.  We have to check sanity
before we touch the PC.

This has not been fixed because there was no way to (ab)use the
setup from pure-Ruby.  However by using our official C APIs it is
possible to touch such frame(s), resulting in SEGV.

Fixes [Bug #14834].

diff --git a/ext/-test-/bug-14834/bug-14384.c b/ext/-test-/bug-14834/bug-14384.c
new file mode 100644
index 0000000..58abd6d
--- /dev/null
+++ b/ext/-test-/bug-14834/bug-14384.c
@@ -0,0 +1,35 @@ https://github.com/ruby/ruby/blob/trunk/ext/-test-/bug-14834/bug-14384.c#L1
+#include <ruby/ruby.h>
+#include <ruby/debug.h>
+
+static NOINLINE(VALUE f(VALUE));
+static NOINLINE(void g(VALUE, void*));
+extern NOINLINE(void Init_bug_14384(void));
+
+void
+Init_bug_14834(void)
+{
+    VALUE q = rb_define_module("Bug");
+    rb_define_module_function(q, "bug_14834", f, 0);
+}
+
+VALUE
+f(VALUE q)
+{
+    int   w[] = { 0, 1024 };
+    VALUE e   = rb_tracepoint_new(Qnil, RUBY_INTERNAL_EVENT_NEWOBJ, g, w);
+
+    rb_tracepoint_enable(e);
+    return rb_ensure(rb_yield, q, rb_tracepoint_disable, e);
+}
+
+void
+g(MAYBE_UNUSED(VALUE q), void* w)
+{
+    const int *e = (const int *)w;
+    const int  r = *e++;
+    const int  t = *e++;
+    VALUE      y[t];
+    int        u[t];
+
+    rb_profile_frames(r, t, y, u);
+}
diff --git a/ext/-test-/bug-14834/depend b/ext/-test-/bug-14834/depend
new file mode 100644
index 0000000..5206f99
--- /dev/null
+++ b/ext/-test-/bug-14834/depend
@@ -0,0 +1,14 @@ https://github.com/ruby/ruby/blob/trunk/ext/-test-/bug-14834/depend#L1
+# AUTOGENERATED DEPENDENCIES START
+bug-14384.o: $(RUBY_EXTCONF_H)
+bug-14384.o: $(arch_hdrdir)/ruby/config.h
+bug-14384.o: $(hdrdir)/ruby/assert.h
+bug-14384.o: $(hdrdir)/ruby/backward.h
+bug-14384.o: $(hdrdir)/ruby/debug.h
+bug-14384.o: $(hdrdir)/ruby/defines.h
+bug-14384.o: $(hdrdir)/ruby/intern.h
+bug-14384.o: $(hdrdir)/ruby/missing.h
+bug-14384.o: $(hdrdir)/ruby/ruby.h
+bug-14384.o: $(hdrdir)/ruby/st.h
+bug-14384.o: $(hdrdir)/ruby/subst.h
+bug-14384.o: bug-14384.c
+# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/-test-/bug-14834/extconf.rb b/ext/-test-/bug-14834/extconf.rb
new file mode 100644
index 0000000..e8f3f1f
--- /dev/null
+++ b/ext/-test-/bug-14834/extconf.rb
@@ -0,0 +1,2 @@ https://github.com/ruby/ruby/blob/trunk/ext/-test-/bug-14834/extconf.rb#L1
+# frozen_string_literal: true
+create_makefile("-test-/bug_14834")
diff --git a/gc.c b/gc.c
index 1b0f13e..fd30c75 100644
--- a/gc.c
+++ b/gc.c
@@ -1925,8 +1925,11 @@ rb_objspace_set_event_hook(const rb_event_flag_t event) https://github.com/ruby/ruby/blob/trunk/gc.c#L1925
 static void
 gc_event_hook_body(rb_execution_context_t *ec, rb_objspace_t *objspace, const rb_event_flag_t event, VALUE data)
 {
-    /* increment PC because source line is calculated with PC-1 */
-    const VALUE *pc = ec->cfp->pc++;
+    const VALUE *pc = ec->cfp->pc;
+    if (VM_FRAME_RUBYFRAME_P(ec->cfp)) {
+        /* increment PC because source line is calculated with PC-1 */
+        ec->cfp->pc++;
+    }
     EXEC_EVENT_HOOK(ec, event, ec->cfp->self, 0, 0, 0, data);
     ec->cfp->pc = pc;
 }
diff --git a/test/-ext-/test_bug-14834.rb b/test/-ext-/test_bug-14834.rb
new file mode 100644
index 0000000..a3623b8
--- /dev/null
+++ b/test/-ext-/test_bug-14834.rb
@@ -0,0 +1,12 @@ https://github.com/ruby/ruby/blob/trunk/test/-ext-/test_bug-14834.rb#L1
+# frozen_string_literal: true
+
+class Test_BUG_14834 < Test::Unit::TestCase
+  def test
+    assert_ruby_status [], <<~'end;', '[ruby-core:87449] [Bug #14834]'
+      require '-test-/bug_14834'
+      Bug.bug_14834 do
+        [123].group_by {}
+      end
+    end;
+  end
+end
-- 
cgit v0.10.2


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]