Actions
Bug #19348
closedGVL being released earlier than expected when loading iseqs
Bug #19348:
GVL being released earlier than expected when loading iseqs
Description
When using the debug gem in a Rails app with Ruby 3.2, I noticed that if the VS Code editor connects to the debugger during the app boot, this error could occur:
DEBUGGER: ReaderThreadError: uninitialized InstructionSequence
┃ DEBUGGER: Disconnected.
┃ ["/opt/rubies/ruby-3.2.0/lib/ruby/gems/3.2.0/gems/debug-1.7.1/lib/debug/breakpoint.rb:247:in `absolute_path'",
┃ "/opt/rubies/ruby-3.2.0/lib/ruby/gems/3.2.0/gems/debug-1.7.1/lib/debug/breakpoint.rb:247:in `block in iterate_iseq'",
┃ "/opt/rubies/ruby-3.2.0/lib/ruby/gems/3.2.0/gems/debug-1.7.1/lib/debug/breakpoint.rb:246:in `each_iseq'",
...
After investigating it with @peterzhu2118 (Peter Zhu), we found that it's because:
- During the Rails app's boot time, it uses
bootsnapto load iseqs, which uses theibf_load_iseq_eachfunction underneath. - After commit e35c528d721d209ed8531b10b46c2ac725ea7bf5 (added in 3.2), that function starts calling
rb_vm_pop_frameat the end of execution. - Because
rb_vm_pop_frametriggers the release of GVL, iseqs that just being loaded now become accessible by other threads, even though they're not ready to be used. - Now, if the
debuggem callsObjectSpace.each_iseqto activate aLineBreakpointfrom its own thread, it'd gain access to those unready iseqs and try to read their state, which would then cause theuninitialized InstructionSequenceerror.
Actions