From: "peterzhu2118 (Peter Zhu) via ruby-core" <ruby-core@ml.ruby-lang.org>
To: ruby-core@ml.ruby-lang.org
Cc: "peterzhu2118 (Peter Zhu)" <noreply@ruby-lang.org>
Subject: [ruby-core:116577] [Ruby master Bug#20169] `GC.compact` can raises `EFAULT` on IO
Date: Sun, 04 Feb 2024 22:14:41 +0000 (UTC) [thread overview]
Message-ID: <redmine.journal-106592.20240204221440.17@ruby-lang.org> (raw)
In-Reply-To: redmine.issue-20169.20240109103749.17@ruby-lang.org
Issue #20169 has been updated by peterzhu2118 (Peter Zhu).
> I want to try and spell out what it means for "the rules" for extensions if we accept it.
I don't think this implies any new rules. IMO it's undefined behaviour to use a Ruby object in a non-GVL scenario, this just fixes the issue inside of Ruby using a hack. Extension developers should not be relying on anything implied by this patch.
> It is illegal to directly access any field in a struct RBasic, struct RString, etc
It's already illegal (or undefined behaviour) to do this.
> Possibly, although these are the rules that seem to apply within cruby
They're not exactly rules in CRuby. The implementation inside of CRuby is tightly coupled, so changing the implementation of one thing can lead to many other things needing their implementation changed.
----------------------------------------
Bug #20169: `GC.compact` can raises `EFAULT` on IO
https://bugs.ruby-lang.org/issues/20169#change-106592
* 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/
next prev parent reply other threads:[~2024-02-04 22:14 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-01-09 10:37 [ruby-core:116114] [Ruby master Bug#20169] `GC.compact` can raises `EFAULT` on IO ko1 (Koichi Sasada) via ruby-core
2024-01-09 11:05 ` [ruby-core:116115] " kjtsanaktsidis (KJ Tsanaktsidis) via ruby-core
2024-01-10 23:39 ` [ruby-core:116164] " kjtsanaktsidis (KJ Tsanaktsidis) via ruby-core
2024-01-11 3:28 ` [ruby-core:116167] " luke-gru (Luke Gruber) via ruby-core
2024-01-13 2:58 ` [ruby-core:116188] " kjtsanaktsidis (KJ Tsanaktsidis) via ruby-core
2024-01-15 5:25 ` [ruby-core:116212] " kjtsanaktsidis (KJ Tsanaktsidis) via ruby-core
2024-01-16 9:34 ` [ruby-core:116224] " kjtsanaktsidis (KJ Tsanaktsidis) via ruby-core
2024-02-02 17:03 ` [ruby-core:116560] " peterzhu2118 (Peter Zhu) via ruby-core
2024-02-03 1:37 ` [ruby-core:116562] " kjtsanaktsidis (KJ Tsanaktsidis) via ruby-core
2024-02-04 22:14 ` peterzhu2118 (Peter Zhu) via ruby-core [this message]
2024-02-04 23:41 ` [ruby-core:116578] " kjtsanaktsidis (KJ Tsanaktsidis) via ruby-core
2024-05-28 21:24 ` [ruby-core:118049] " k0kubun (Takashi Kokubun) via ruby-core
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.ruby-lang.org/en/community/mailing-lists/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=redmine.journal-106592.20240204221440.17@ruby-lang.org \
--to=ruby-core@ruby-lang.org \
--cc=noreply@ruby-lang.org \
--cc=ruby-core@ml.ruby-lang.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).