[ruby-core:117725] [Ruby master Bug#20456] Hash can get stuck marked as iterating through process forking
From:
"byroot (Jean Boussier) via ruby-core" <ruby-core@...>
Date:
2024-04-26 10:06:07 UTC
List:
ruby-core #117725
Issue #20456 has been updated by byroot (Jean Boussier).
> I think we should remove [auto unlock of mutexes owned by dead thread]
I very strongly oppose that.
----------------------------------------
Bug #20456: Hash can get stuck marked as iterating through process forking
https://bugs.ruby-lang.org/issues/20456#change-108133
* 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 -- [email protected]
To unsubscribe send an email to [email protected]
ruby-core info -- https://ml.ruby-lang.org/mailman3/postorius/lists/ruby-core.ml.ruby-lang.org/