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

ruby-changes:55683

From: Aaron <ko1@a...>
Date: Thu, 9 May 2019 07:26:38 +0900 (JST)
Subject: [ruby-changes:55683] Aaron Patterson: c53f87943e (trunk): Calling `obj_info` during sweep is unsafe

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

From c53f87943e53c96b86d50b496d2a410ff1245b4c Mon Sep 17 00:00:00 2001
From: Aaron Patterson <tenderlove@r...>
Date: Wed, 8 May 2019 15:19:59 -0700
Subject: Calling `obj_info` during sweep is unsafe

`obj_info` will look at references of objects in some cases (for example
it will try to access path information on ISeq objects).  But during the
sweep phase, if the referenced object is collected before `obj_info` is
called, then it could be a bad ref and a segv will occur.

For example:

A -> B

Sweep phase:

1. obj_info(B)
2. Sweep and free B
3. obj_info(A); A tries to read B
4. SEGV

This commit simply removes the call to `obj_info` during the sweep
phase.

diff --git a/gc.c b/gc.c
index b629c03..163a680 100644
--- a/gc.c
+++ b/gc.c
@@ -1064,6 +1064,7 @@ tick(void) https://github.com/ruby/ruby/blob/trunk/gc.c#L1064
 #define RVALUE_AGE_SHIFT 5 /* FL_PROMOTED0 bit */
 
 static int rgengc_remembered(rb_objspace_t *objspace, VALUE obj);
+static int rgengc_remembered_sweep(rb_objspace_t *objspace, VALUE obj);
 static int rgengc_remember(rb_objspace_t *objspace, VALUE obj);
 static void rgengc_mark_and_rememberset_clear(rb_objspace_t *objspace, rb_heap_t *heap);
 static void rgengc_rememberset_mark(rb_objspace_t *objspace, rb_heap_t *heap);
@@ -3822,7 +3823,7 @@ gc_page_sweep(rb_objspace_t *objspace, rb_heap_t *heap, struct heap_page *sweep_ https://github.com/ruby/ruby/blob/trunk/gc.c#L3823
 #if USE_RGENGC && RGENGC_CHECK_MODE
 			  if (!is_full_marking(objspace)) {
 			      if (RVALUE_OLD_P((VALUE)p)) rb_bug("page_sweep: %p - old while minor GC.", (void *)p);
-			      if (rgengc_remembered(objspace, (VALUE)p)) rb_bug("page_sweep: %p - remembered.", (void *)p);
+			      if (rgengc_remembered_sweep(objspace, (VALUE)p)) rb_bug("page_sweep: %p - remembered.", (void *)p);
 			  }
 #endif
 			  if (obj_free(objspace, (VALUE)p)) {
@@ -6294,14 +6295,20 @@ rgengc_remember(rb_objspace_t *objspace, VALUE obj) https://github.com/ruby/ruby/blob/trunk/gc.c#L6295
 }
 
 static int
-rgengc_remembered(rb_objspace_t *objspace, VALUE obj)
+rgengc_remembered_sweep(rb_objspace_t *objspace, VALUE obj)
 {
     int result = rgengc_remembersetbits_get(objspace, obj);
     check_rvalue_consistency(obj);
-    gc_report(6, objspace, "rgengc_remembered: %s\n", obj_info(obj));
     return result;
 }
 
+static int
+rgengc_remembered(rb_objspace_t *objspace, VALUE obj)
+{
+    gc_report(6, objspace, "rgengc_remembered: %s\n", obj_info(obj));
+    return rgengc_remembered_sweep(objspace, obj);
+}
+
 #ifndef PROFILE_REMEMBERSET_MARK
 #define PROFILE_REMEMBERSET_MARK 0
 #endif
-- 
cgit v0.10.2


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

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