
Issue #19348 has been reported by st0012 (Stan Lo). ---------------------------------------- Bug #19348: GVL being released earlier than expected when loading iseqs https://bugs.ruby-lang.org/issues/19348 * Author: st0012 (Stan Lo) * Status: Open * Priority: Normal * ruby -v: 3.2.0 * Backport: 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN ---------------------------------------- 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, we found that it's because: 1. During the Rails app's boot time, it uses `bootsnap` to load iseqs, which uses the [`ibf_load_iseq_each `](https://github.com/ruby/ruby/blob/9399352a43253e2905d76d21774fb0301069197b/c...) function underneath. 2. After commit [e35c528d721d209ed8531b10b46c2ac725ea7bf5](https://github.com/ruby/ruby/commit/e35c528d721d209ed8531b10b46c2ac725ea7bf5) (added in 3.2), that function starts calling `rb_vm_pop_frame` at the end of execution. 3. Because `rb_vm_pop_frame` triggers the release of GVL, iseqs that just being loaded now become accessible by other threads, even though they're not ready to be used. 4. Now, if the `debug` gem calls [`ObjectSpace.each_iseq`](https://github.com/ruby/debug/blob/0fcfc28acae33ec1c08068fb7c33703cfa681fa7/...) to [activate a `LineBreakpoint`](https://github.com/ruby/debug/blob/0fcfc28acae33ec1c08068fb7c33703cfa681fa7/...) from its own thread, it'd gain access to those unready iseqs and try to read their state, which would then cause the [`uninitialized InstructionSequence` error](https://github.com/ruby/ruby/blob/40a9964b893fee5680b455d0e905155be3360685/i...). -- https://bugs.ruby-lang.org/