Issue #15821 has been updated by methodmissing (Lourens Naud=E9).


As outlined in the proposal, the following diff fixes the WB miss local to =
`process_options`

```
diff --git a/ruby.c b/ruby.c
index bf94b8ee13..b7648934d6 100644
--- a/ruby.c
+++ b/ruby.c
@@ -1726,6 +1726,7 @@ process_options(int argc, char **argv, ruby_cmdline_o=
ptions_t *opt)
            path =3D rb_enc_associate(rb_str_dup(path), lenc);
 #endif
            if (mark) rb_ivar_set(path, id_initial_load_path_mark, path);
+           rb_ary_modify(load_path);
            RARRAY_ASET(load_path, i, path);
        }
     }
```

```
lourens@CarbonX1:~/src/ruby/ruby$ RUBY_DEBUG=3Dgc_stress ./ruby --disable-g=
ems -ve 1
ruby 2.7.0dev (2019-05-05 trunk 594a033ff0) [x86_64-linux]
gc_check_after_marks_i: 0x000055a590d68018 [3  P  ] T_STRING (String) pp is=
 not marked and not oldgen.
gc_check_after_marks_i: 0x55a590d68018 is referred from <root@machine_conte=
xt> (marked from machine stack).
-e:1: warning: possibly useless use of a literal in void context
```

Running `make check` with GC stress enabled comes back mostly clean (ran it=
 for a few minutes) except for these warnings, which as I understand can be=
 false positives:

```
./revision.h unchanged
generating encdb.h
gc_check_after_marks_i: 0x000055607246c008 [0  P  ] T_STRING format is not =
marked and not oldgen.
gc_check_after_marks_i: 0x55607246c008 is referred from <root@machine_conte=
xt> (marked from machine stack).
gc_check_after_marks_i: 0x00005560723c4010 [3  P  ] T_STRING (String)  is n=
ot marked and not oldgen.
gc_check_after_marks_i: 0x5560723c4010 is referred from <root@machine_conte=
xt> (marked from machine stack).
gc_check_after_marks_i: 0x00005560723c4010 [3  P  ] T_STRING (String) =

 is not marked and not oldgen.
gc_check_after_marks_i: 0x5560723c4010 is referred from <root@machine_conte=
xt> (marked from machine stack).
gc_check_after_marks_i: 0x00005560723c4010 [3  P  ] T_STRING (String) CGI i=
s not marked and not oldgen.
gc_check_after_marks_i: 0x5560723c4010 is referred from <root@machine_conte=
xt> (marked from machine stack).
gc_check_after_marks_i: 0x00005560723c4010 [2  P  ] T_STRING (String) time =
is not marked and not oldgen.
gc_check_after_marks_i: 0x5560723c4010 is referred from <root@machine_conte=
xt> (marked from machine stack).
gc_check_after_marks_i: 0x00005560723c4010 [3  P  ] T_STRING (String)     t=
 =3D time.clone.gmtime
 is not marked and not oldgen.
gc_check_after_marks_i: 0x5560723c4010 is referred from <root@machine_conte=
xt> (marked from machine stack).
gc_check_after_marks_i: 0x00005560723c4010 [3  P  ] T_STRING (String)   end
 is not marked and not oldgen.
gc_check_after_marks_i: 0x5560723c4010 is referred from <root@machine_conte=
xt> (marked from machine stack).
gc_check_after_marks_i: 0x00005560723c4010 [3  P  ] T_STRING (String)   # +=
string+ is the HTML string to indent.  +shift+ is the indentation
```

----------------------------------------
Bug #15821: ruby_process_options() may cause "WB miss (O->Y)"
https://bugs.ruby-lang.org/issues/15821#change-77909

* Author: wanabe (_ wanabe)
* Status: Open
* Priority: Normal
* Assignee: =

* Target version: =

* ruby -v: ruby 2.7.0dev (2019-05-04 trunk b72623012d) [x86_64-linux]
* Backport: 2.4: UNKNOWN, 2.5: UNKNOWN, 2.6: UNKNOWN
----------------------------------------
## Problem

Ruby interpreter may cause error "WB miss (O->Y)" on some conditions that a=
re `RGENGC_CHECK_MODE=3D5` and `RUBY_DEBUG=3Dgc_stress`

## How to reproduce

1. build ruby with high RGENGC_CHECK_MODE
   * `make ruby optflags=3D"-O3 -DRGENGC_CHECK_MODE=3D5"`
2. run ruby with gc_stress
   * `RUBY_DEBUG=3Dgc_stress ./ruby --disable-gems -ve 1`

## Probable cause

1. `rb_construct_expanded_load_path` calls `rb_ary_replace(vm->load_path_sn=
apshot, vm->load_path)`.
2. It creates shared root array and makes `vm->load_path` SHARED_ARRAY.
3. After a while, `process_options` calls `RARRAY_ASET(load_path, i, path)`.
4. It calls `rb_gc_writebarrier` -> `gc_writebarrier_generational`.
   * Incremental mark phase is finished because of `RUBY_DEBUG=3Dgc_stress`.
5. It makes `vm->load_path` remembered, but not shared root array!
6. "WB miss (O->Y)" is done.
   * Old parent is shared root array.
   * New child is `path` of above 3.

## Proposal

How about call `rb_ary_modify` before `RARRAY_SET` in `process_options`?
Or using `rb_ary_store` instead of `RARRAY_SET` may avoid the error.

## Sample output

An example of full output is attached.
(Sorry, I GZipped it because of file-size limitation)
The snippet is here:

```
ruby 2.7.0dev (2019-05-04 trunk b72623012d) [x86_64-linux]
verify_internal_consistency_reachable_i: WB miss (O->Y) 0x000055c3262f3610 =
[3LM   ] T_ARRAY [   ] len: 20, capa:2 ptr:0x000055c326498380 -> 0x000055c3=
262f3908 [2  P  ] T_STRING (String) /home/wanabe/.rbenv/versions/trunk/lib/=
ruby/site_ruby/2.7.0
[all refs] (size: 5307)
(snip)
[allrefs_dump_i] 0x000055c3263349f8 [3LMP  ] T_ARRAY [E ] len: 0 (embed) <-=
 <0x000055c326336f28 [0  P U] VM/thread (Thread) VM/thread>
./ruby: [BUG] Segmentation fault at 0x0000000000000010
ruby 2.7.0dev (2019-05-04 trunk b72623012d) [x86_64-linux]

-- Control frame information -----------------------------------------------
c:0001 p:0000 s:0003 E:0022c0 (none) [FINISH]


-- Machine register context ------------------------------------------------
 RIP: 0x000055c32452e15a RBP: 0x0000000000000001 RSP: 0x00007ffea126d470
 RAX: 0x0000000000000000 RBX: 0x000055c3262ef3c8 RCX: 0x0000000000000001
 RDX: 0x000055c324773446 RDI: 0x00007ff8c77cb680 RSI: 0x0000000000000001
  R8: 0x000055c3262ef3b8  R9: 0x0000000000000018 R10: 0x0000000000000018
 R11: 0x0000000000000246 R12: 0x0000000000000100 R13: 0x0000000000000005
 R14: 0x000055c3262f3c28 R15: 0x000055c3262ef1b0 EFL: 0x0000000000010206

-- C level backtrace information -------------------------------------------
/home/wanabe/work/prog/ruby/ruby/tmp/trunk/ruby(rb_vm_bugreport+0x554) [0x5=
5c324769fa4] ../../vm_dump.c:715
[0x55c324760088]
/home/wanabe/work/prog/ruby/ruby/tmp/trunk/ruby(sigsegv+0x42) [0x55c324640d=
42] ../../signal.c:997
/lib/x86_64-linux-gnu/libpthread.so.0(__restore_rt+0x0) [0x7ff8c797ff40]
/home/wanabe/work/prog/ruby/ruby/tmp/trunk/ruby(allrefs_dump+0x1a) [0x55c32=
452e15a] /usr/include/x86_64-linux-gnu/bits/stdio2.h:100
[0x55c32453a478]
[0x55c32453a64c]
[0x55c32453f874]
/home/wanabe/work/prog/ruby/ruby/tmp/trunk/ruby(rb_str_dup+0x29) [0x55c3246=
5aa59] ../../string.c:722
[0x55c32463f2e1]
/home/wanabe/work/prog/ruby/ruby/tmp/trunk/ruby(ruby_process_options+0xc0) =
[0x55c3246404a0] ../../ruby.c:2380
/home/wanabe/work/prog/ruby/ruby/tmp/trunk/ruby(ruby_options+0xca) [0x55c32=
451e1ea] ../../eval.c:118
/home/wanabe/work/prog/ruby/ruby/tmp/trunk/ruby(main+0x67) [0x55c324519ec7]=
 ../../main.c:42
(snip)
Aborted (core dumped)
```

---Files--------------------------------
out.log.gz (114 KB)


-- =

https://bugs.ruby-lang.org/

Unsubscribe: <mailto:ruby-core-request / ruby-lang.org?subject=3Dunsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>