ruby-core@ruby-lang.org archive (unofficial mirror)
 help / color / mirror / Atom feed
From: "blowfishpro (Talia Wong) via ruby-core" <ruby-core@ml.ruby-lang.org>
To: ruby-core@ml.ruby-lang.org
Cc: "blowfishpro (Talia Wong)" <noreply@ruby-lang.org>
Subject: [ruby-core:117711] [Ruby master Bug#20456] Hash can get stuck marked as iterating through process forking
Date: Thu, 25 Apr 2024 18:47:05 +0000 (UTC)	[thread overview]
Message-ID: <redmine.issue-20456.20240425184704.49402@ruby-lang.org> (raw)
In-Reply-To: redmine.issue-20456.20240425184704.49402@ruby-lang.org

Issue #20456 has been reported by blowfishpro (Talia Wong).

----------------------------------------
Bug #20456: Hash can get stuck marked as iterating through process forking
https://bugs.ruby-lang.org/issues/20456

* Author: blowfishpro (Talia Wong)
* Status: Open
* ruby -v: 3.3.0
* Backport: 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN
----------------------------------------
# Steps to Reproduce

1. Iterate over a hash
1. While that iteration is happening, fork the process
  a. This should be done in a way that causes the iteration to never finish from the child process's view, e.g. fork with a block, or iteration is happening in a different thread than fork
1. Attempt to add a new key to the hash in the child process
  a. This can be before or after the iteration finishes in the parent process, doesn't matter

# Observed Behavior

The child process can never add a new key to the hash, always fails with `RuntimeError: can't add a new key into hash during iteration`

# Desired

The hash is no longer iterating in the child process, so it can be modified as needed

# Examples

## With threads:

```ruby
h = { a: 1 }
t = Thread.new do
  sleep 0.05
  pid = fork do
    sleep 0.1
    puts 'child: before'
    h[:b] = 2
    puts 'child: after'
  end
  Process.wait2(pid)
end

puts 'parent: before'
h.each do
  sleep 0.1
end
puts 'parent: after'
puts t.join.value.inspect
```
produces:
```
parent: before
parent: after
child: before
can't add a new key into hash during iteration (RuntimeError)
[34450, #<Process::Status: pid 34450 exit 1>]
```

## Without threads:

``` ruby
h = { a: 1 }
pid = nil
puts 'parent: before'
h.each do
  pid = fork do
    sleep 0.05
    puts 'child: before'
    h[:b] = 2
    puts 'child: after'
  end
end
puts 'parent: after'
puts Process.wait2(pid).inspect
```
produces:
```
parent: before
parent: after
child: before
can't add a new key into hash during iteration (RuntimeError)
[17809, #<Process::Status: pid 17809 exit 1>]
```

# Platform information

This behavior has been observed in the following environments
- Ruby 3.3.0 on Mac OS 14.4.1 (Apple M1 Max) installed via [asdf](https://asdf-vm.com/)
- Ruby 2.7.5 on Mac OS 14.4.1 (Apple M1 Max) installed via [asdf](https://asdf-vm.com/)
- Ruby 3.2.3 on RockyLinux 8.4 (x86_64) installed from [Fullstaq](https://fullstaqruby.org/)




-- 
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/

       reply	other threads:[~2024-04-25 18:47 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-04-25 18:47 blowfishpro (Talia Wong) via ruby-core [this message]
2024-04-25 19:56 ` [ruby-core:117713] [Ruby master Bug#20456] Hash can get stuck marked as iterating through process forking Eregon (Benoit Daloze) via ruby-core
2024-04-26  7:41 ` [ruby-core:117719] " byroot (Jean Boussier) via ruby-core
2024-04-26  8:19 ` [ruby-core:117720] " mame (Yusuke Endoh) via ruby-core
2024-04-26  8:28 ` [ruby-core:117721] " byroot (Jean Boussier) via ruby-core
2024-04-26  9:54 ` [ruby-core:117724] " Eregon (Benoit Daloze) via ruby-core
2024-04-26 10:06 ` [ruby-core:117725] " byroot (Jean Boussier) 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.issue-20456.20240425184704.49402@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).