[#116534] [Ruby master Bug#20231] Don't wait in io_binwrite_string if not necessary. — "ioquatix (Samuel Williams) via ruby-core" <ruby-core@...>

Issue #20231 has been reported by ioquatix (Samuel Williams).

8 messages 2024/02/01

[#116565] [Ruby master Feature#20235] Deprecate CHAR syntax — "Dan0042 (Daniel DeLorme) via ruby-core" <ruby-core@...>

Issue #20235 has been reported by Dan0042 (Daniel DeLorme).

8 messages 2024/02/03

[#116581] [Ruby master Bug#20237] Unable to unshare(CLONE_NEWUSER) in Linux because of timer thread — "hanazuki (Kasumi Hanazuki) via ruby-core" <ruby-core@...>

Issue #20237 has been reported by hanazuki (Kasumi Hanazuki).

10 messages 2024/02/05

[#116589] [Ruby master Misc#20238] Use prism for mk_builtin_loader.rb — "kddnewton (Kevin Newton) via ruby-core" <ruby-core@...>

Issue #20238 has been reported by kddnewton (Kevin Newton).

22 messages 2024/02/05

[#116640] [Ruby master Feature#20249] Print only backtraces in rb_bug(), by default — "osyoyu (Daisuke Aritomo) via ruby-core" <ruby-core@...>

Issue #20249 has been reported by osyoyu (Daisuke Aritomo).

11 messages 2024/02/09

[#116664] [Ruby master Misc#20254] FYI: Add Launchable into Ruby CI — "ono-max (Naoto Ono) via ruby-core" <ruby-core@...>

Issue #20254 has been reported by ono-max (Naoto Ono).

18 messages 2024/02/10

[#116666] [Ruby master Bug#20255] Embedded arrays aren't moved correctly across ractors — "luke-gru (Luke Gruber) via ruby-core" <ruby-core@...>

Issue #20255 has been reported by luke-gru (Luke Gruber).

18 messages 2024/02/10

[#116681] [Ruby master Misc#20260] ISEQ flag for prism compiler — "kddnewton (Kevin Newton) via ruby-core" <ruby-core@...>

Issue #20260 has been reported by kddnewton (Kevin Newton).

15 messages 2024/02/12

[#116696] [Ruby master Bug#20264] Segfault installing RMagick on M1 Mac — "andy@... (Andy Jeffries) via ruby-core" <ruby-core@...>

Issue #20264 has been reported by andy@andyjeffries.co.uk (Andy Jeffries).

7 messages 2024/02/13

[#116760] [Ruby master Feature#20265] Deprecate and remove rb_newobj and rb_newobj_of — "peterzhu2118 (Peter Zhu) via ruby-core" <ruby-core@...>

SXNzdWUgIzIwMjY1IGhhcyBiZWVuIHJlcG9ydGVkIGJ5IHBldGVyemh1MjExOCAoUGV0ZXIgWmh1

8 messages 2024/02/14

[#116769] [Ruby master Feature#20266] New syntax to escape embed strings in Regexp literal — "usa (Usaku NAKAMURA) via ruby-core" <ruby-core@...>

Issue #20266 has been reported by usa (Usaku NAKAMURA).

8 messages 2024/02/15

[#116819] [Ruby master Feature#20275] Avoid extra backtrace entries for rescue and ensure — "Eregon (Benoit Daloze) via ruby-core" <ruby-core@...>

Issue #20275 has been reported by Eregon (Benoit Daloze).

8 messages 2024/02/17

[#116827] [Ruby master Feature#20276] Introduce Fiber interfaces for Ractors — "forthoney (Seong-Heon Jung) via ruby-core" <ruby-core@...>

Issue #20276 has been reported by forthoney (Seong-Heon Jung).

8 messages 2024/02/17

[#116846] [Ruby master Misc#20281] DevMeeting-2024-03-14 — "mame (Yusuke Endoh) via ruby-core" <ruby-core@...>

Issue #20281 has been reported by mame (Yusuke Endoh).

16 messages 2024/02/19

[#116853] [Ruby master Feature#20282] Enhancing Ruby's Coverage with Per-Test Coverage Reports — "ioquatix (Samuel Williams) via ruby-core" <ruby-core@...>

Issue #20282 has been reported by ioquatix (Samuel Williams).

7 messages 2024/02/19

[#116902] [Ruby master Feature#20290] Add API for C extensions to free memory — "peterzhu2118 (Peter Zhu) via ruby-core" <ruby-core@...>

Issue #20290 has been reported by peterzhu2118 (Peter Zhu).

9 messages 2024/02/21

[#116940] [Ruby master Feature#20300] Hash: set value and get pre-existing value in one call — "AMomchilov (Alexander Momchilov) via ruby-core" <ruby-core@...>

Issue #20300 has been reported by AMomchilov (Alexander Momchilov).

19 messages 2024/02/26

[#116941] [Ruby master Bug#20301] `Set#add?` does two hash look-ups — "AMomchilov (Alexander Momchilov) via ruby-core" <ruby-core@...>

Issue #20301 has been reported by AMomchilov (Alexander Momchilov).

10 messages 2024/02/26

[#116965] [Ruby master Bug#20307] `Hash#update` from compare_by_identity hash can have unfrozen string keys — "nobu (Nobuyoshi Nakada) via ruby-core" <ruby-core@...>

Issue #20307 has been reported by nobu (Nobuyoshi Nakada).

7 messages 2024/02/27

[#116983] [Ruby master Feature#20309] Bundled gems for Ruby 3.5 — "hsbt (Hiroshi SHIBATA) via ruby-core" <ruby-core@...>

Issue #20309 has been reported by hsbt (Hiroshi SHIBATA).

28 messages 2024/02/27

[ruby-core:116562] [Ruby master Bug#20169] `GC.compact` can raises `EFAULT` on IO

From: "kjtsanaktsidis (KJ Tsanaktsidis) via ruby-core" <ruby-core@...>
Date: 2024-02-03 01:37:09 UTC
List: ruby-core #116562
Issue #20169 has been updated by kjtsanaktsidis (KJ Tsanaktsidis).


So I think we can go with that fix, but I want to try and spell out what it means for "the rules" for extensions if we accept it.

AFAICT, by merging https://github.com/ruby/ruby/pull/9817, we are saying the following:

1. It is illegal to dereference or store into any pointer to the Ruby heap in a no-GVL context. This implies:
   a) It is illegal to directly access any field in a `struct RBasic`, `struct RString`, etc,
   b) Thus it implies that things like `RSTRING_PTR(str)` are 100% illegal in a no-GVL context (this shouldn't be controversial)
   c) This rule _does_ allow you to manipulate a C structure/array/etc you received a pointer to from a `struct RThing` (an "external pointer"), provided
       i) you _know_ that this structure is stored in the C heap and not the Ruby heap,
      ii) you obtained this pointer out of the `struct RThing` whilst holding the GVL.
     iii) and you obey the restrictions spelled out in Rule 2 below.
2. You can dereference and read from an "external pointer" in a no-GVL context, provided that
  a) the VALUE from which you obtained the pointer is guaranteed to be GC live AND GC pinned from the beginning of your no-GVL context through to the last access of the pointer.
      i) In practice, normally extension developers will adhere to this rule by inserting an `RB_GC_GUARD` macro after a call to `rb_thread_call_without_gvl` to instruct the compiler to keep the VALUE live on the thread/fiber's C stack and thus visible to Ruby's GC.
     ii) However, there are other ways to meet this requirement too (e.g. adding the object directly as a GC root with `rb_global_variable` or such).
    iii) The reason why it's important for the object to be GC pinned is that if the object is moved, the object's `dcompact` function is called, and this function is allowed to mutate the "external pointer".
  b) No Ruby thread can be using this object, either in C or in Ruby. If an object's "external pointer"s are being used in a no-GVL context, then the object as a whole cannot be used in a GVL context.
  c) the VALUE has not at any point in its lifetime been made visible to Ruby code, IF the value is not frozen.
      i) This obviously means it e.g. cannot have been yielded back to Ruby with `rb_yield`, or previously returned, etc.
     ii) It _also_ means that the object must have been hidden with a call to `rb_gc_hide` _immediately after_ being allocated by the GC. There cannot be any call to Ruby, nor call to the GC, in between where the program allocates the VALUE and hides it. In practice, APIs like the `rb_str_tmp_*` family will return pre-hidden objects which meet these requirements. This ensures that a mutable value being accessed from C was hidden from calls like `ObjectSpace.each_object`.
    iii) However, if an object is frozen, then this requirement does not apply - it _is_ legal to read an "external pointer" in a no-GVL context if the object it was obtained from is frozen, even if that object is visible to Ruby.
     iv) A corollary of iii is that an extension which exposes "external pointers" to C-heap allocated data owned by its T_DATA object cannot mutate this data if the underlying `T_DATA` is frozen. It's fairly uncommon for extensions to actually expose C-level APIs like this, but it is possible by e.g. exporting symbols with `__attribute__((visibility(default)))`.
3. You can write to an "external pointer" in a no-GVL context, provided that you adhere to rule 2, AND that the object is not frozen.
4. When reading from and writing to "external pointers", extension developers are responsible for appropriately synchronizing their reads and writes to this pointer (in practice, most usage of such "external pointers" will be restricted to a single thread, however).


These rules are pretty complicated, but I think this is what's implied by the patch. In particular, i think 2.c.iii is implied by

```
if (OBJ_FROZEN_RAW(orig) && !STR_EMBED_P(orig) && !rb_str_reembeddable_p(orig)) return orig;
```

but was kind of surprising to me. Possibly, although these are the rules that seem to apply _within_ cruby, we want to document a more restrictive set of rules for extension developers which are easier to reason about (perhaps even as far as "don't store results of no-GVL routines into Ruby strings at all in your extension, you must bounce everything through native memory and copy it back into Ruby with the GVL").  

Whatever these rules are, I think we need a clearer description of them in extension.rdoc. If they're different from the internal rules, let's document the "real" messy internal rules in the source tree as well. I'm happy to open a PR to do this once we get some agreement on the broad outlines.

As an aside, I'm researching whether there might be ways to automatically enforce some of this in CI (both for CRuby and for extension developers) by leveraging LLVM's sanitizer infrastructure somehow - I think it would be really helpful to have an executable spec of what the rules are like this!
 

----------------------------------------
Bug #20169: `GC.compact` can raises `EFAULT` on IO
https://bugs.ruby-lang.org/issues/20169#change-106579

* Author: ko1 (Koichi Sasada)
* Status: Open
* Priority: Normal
* Backport: 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN
----------------------------------------
1. `GC.compact` introduces read barriers to detect read accesses to the pages.
2. I/O operations release GVL to pass the control while their execution, and another thread can call `GC.compact` (or auto compact feature I guess, but not checked yet).
3. Call `write(ptr)` can return `EFAULT` when `GC.compact` is running because `ptr` can point read-barrier protected pages (embed strings).

Reproducible steps:


Apply the following patch to increase possibility:

```patch
diff --git a/io.c b/io.c
index f6cd2c1a56..83d67ba2dc 100644
--- a/io.c
+++ b/io.c
@@ -1212,8 +1212,12 @@ internal_write_func(void *ptr)
         }
     }

+    int cnt = 0;
   retry:
-    do_write_retry(write(iis->fd, iis->buf, iis->capa));
+    for (; cnt < 1000; cnt++) {
+        do_write_retry(write(iis->fd, iis->buf, iis->capa));
+        if (result <= 0) break;
+    }

     if (result < 0 && !iis->nonblock) {
         int e = errno;
```

Run the following code:

```ruby
t1 = Thread.new{ 10_000.times.map{"#{_1}"}; GC.compact while true }
t2 = Thread.new{
  i=0
  $stdout.write "<#{i+=1}>" while true
}
t2.join
```

and 

```
$ make run
(snip)
4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4><4>#<Thread:0x00007fa61b4dd758 ../../src/trunk/test.rb:3 run> terminated with exception (report_on_exception is true):
../../src/trunk/test.rb:5:in `write': Bad address @ io_write - <STDOUT> (Errno::EFAULT)
        from ../../src/trunk/test.rb:5:in `block in <main>'
../../src/trunk/test.rb:5:in `write': Bad address @ io_write - <STDOUT> (Errno::EFAULT)
        from ../../src/trunk/test.rb:5:in `block in <main>'
make: *** [uncommon.mk:1383: run] Error 1
```

I think this is why we get `EFAULT` on CI. To increase possibilities running many busy processes (`ruby -e 'loop{}'` for example) will help (and on CI environment there are such busy processes accidentally).



-- 
https://bugs.ruby-lang.org/
 ______________________________________________
 ruby-core mailing list -- ruby-core@ml.ruby-lang.org
 To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org
 ruby-core info -- https://ml.ruby-lang.org/mailman3/postorius/lists/ruby-core.ml.ruby-lang.org/

In This Thread