Bug #15424
closedRuby 2.6.0rc1 & 2.6.0rc2 mutex exception
Description
Steps to reproduce
At the end of a bootstraped rails application (tested with a postgres database) put the following code:
pid = fork do
STDOUT.sync = true
STDERR.sync = true
require('rake')
Application.load_tasks
Rake::Task['environment'].invoke
print("app 6")
end
Expected behavior
Successful start of the rails application, and the output of app 6
Actual behavior
/.../config/application.rb:107: [BUG] invalid keeping_mutexes: Attempt to unlock a mutex which is locked by another thread
ruby 2.6.0rc2 (2018-12-15 trunk 66408) [armv8l-linux-eabihf]
-- Control frame information -----------------------------------------------
c:0017 p:---- s:0112 e:000111 CFUNC :fork
c:0016 p:0151 s:0108 e:000107 TOP /home/halley/hub/config/application.rb:107 [FINISH]
c:0015 p:---- s:0103 e:000102 CFUNC :require
c:0014 p:0110 s:0098 e:000097 METHOD /usr/local/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54
c:0013 p:0019 s:0086 e:000085 BLOCK /usr/local/lib/ruby/2.6.0/rails/commands/server/server_command.rb:151 [FINISH]
c:0012 p:---- s:0082 e:000081 CFUNC :tap
c:0011 p:0037 s:0078 e:000077 METHOD /usr/local/lib/ruby/2.6.0/rails/commands/server/server_command.rb:145
c:0010 p:0064 s:0074 e:000073 METHOD /usr/local/lib/ruby/2.6.0/thor/command.rb:27
c:0009 p:0047 s:0066 e:000065 METHOD /usr/local/lib/ruby/2.6.0/thor/invocation.rb:126
c:0008 p:0266 s:0059 e:000058 METHOD /usr/local/lib/ruby/2.6.0/thor.rb:390
c:0007 p:0043 s:0046 e:000045 METHOD /usr/local/lib/ruby/2.6.0/rails/command/base.rb:65
c:0006 p:0130 s:0039 e:000038 METHOD /usr/local/lib/ruby/2.6.0/rails/command.rb:46
c:0005 p:0059 s:0028 e:000027 TOP /usr/local/lib/ruby/2.6.0/rails/commands.rb:18 [FINISH]
c:0004 p:---- s:0023 e:000022 CFUNC :require
c:0003 p:0110 s:0018 e:000017 METHOD /usr/local/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54
c:0002 p:0031 s:0006 e:000005 EVAL bin/rails:4 [FINISH]
c:0001 p:0000 s:0003 E:ffffe3d8 (none) [FINISH]
-- Ruby level backtrace information ----------------------------------------
bin/rails:4:in <main>' /usr/local/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in
require'
/usr/local/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in require' /usr/local/lib/ruby/2.6.0/rails/commands.rb:18:in
<top (required)>'
/usr/local/lib/ruby/2.6.0/rails/command.rb:46:in invoke' /usr/local/lib/ruby/2.6.0/rails/command/base.rb:65:in
perform'
/usr/local/lib/ruby/2.6.0/thor.rb:390:in dispatch' /usr/local/lib/ruby/2.6.0/thor/invocation.rb:126:in
invoke_command'
/usr/local/lib/ruby/2.6.0/thor/command.rb:27:in run' /usr/local/lib/ruby/2.6.0/rails/commands/server/server_command.rb:145:in
perform'
/usr/local/lib/ruby/2.6.0/rails/commands/server/server_command.rb:145:in tap' /usr/local/lib/ruby/2.6.0/rails/commands/server/server_command.rb:151:in
block in perform'
/usr/local/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in require' /usr/local/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in
require'
/home/halley/hub/config/application.rb:107:in <top (required)>' /home/halley/hub/config/application.rb:107:in
fork'
System configuration
Rails version: 5.2.1
Ruby version: 2.6.0rc2
Last known working version 2.6.0preview2
I've tried but the only way I can replicate it is a combination of fork and the rails active record connection system.
I'm likely missing something in understanding the replicating factor, something rails specific.
Updated by normalperson (Eric Wong) about 6 years ago
mat999@gmail.com wrote:
/.../config/application.rb:107: [BUG] invalid keeping_mutexes: Attempt to unlock a mutex which is locked by another thread
ruby 2.6.0rc2 (2018-12-15 trunk 66408) [armv8l-linux-eabihf]
Are you able to replicate this on x86 or x86-64?
Also, is this glibc, musl or some other userspace C library?
I don't have access to other hardware, haven't tried QEMU in a
while and not sure how slow it is for me.
Last known working version 2.6.0preview2
OK, thanks. It helps us narrow it down. Can you try "git bisect"?
I've tried but the only way I can replicate it is a
combination of fork and the rails active record connection
system.
Can you reproduce it on sqlite and perhaps share a standalone
repo? I haven't setup postgres or mysql in years, now.
I'm likely missing something in understanding the replicating
factor, something rails specific.
It may just be down to threads and mutexes...
It's generallly a bad idea to fork w/o immediate exec while
Threads are already running. Ruby supports it right now because
of some nasty hacks (GVL), but maybe we won't be able to in
the future.
Updated by normalperson (Eric Wong) about 6 years ago
- Status changed from Open to Closed
Applied in changeset trunk|r66438.
thread_sync.c (mutex_ptr): only reinitalize waitqueue at fork
Mutexes need to remain locked after forking.
This fixes "[BUG] invalid keeping_mutexes: Attempt to unlock a
mutex which is locked by another thread" and should
fix test_fork_while_parent_locked failures in CI
[ruby-core:90581] [Bug #15424]
[ruby-core:90595] [Bug #15430]
Fixes: r66230 ("handle mutexes held by parent threads in children")
Updated by normalperson (Eric Wong) about 6 years ago
r66438 should fix it. Sorry for the bugs :x