def_delegators causes random errors in MRI 2.4.0
In the Capybara project we use the rack_test gem which uses
def_delegators to forward
@rack_mock_session - https://github.com/brynary/rack-test/blob/master/lib/rack/test.rb#L29
When running the Capybara test test suite calling last_reponse on a rack_test Session object will sporadically result in a
TypeError from forwardable.rb
TypeError: wrong argument type Integer (expected Proc)
Patching around the delegator with
class Rack::Test::Session def last_response @rack_mock_session.last_response end end
stops the error from occurring, so it appears that something
def_delegators is doing is causing problems. Unfortunately I have not yet been able to establish exactly what causes the issues to produce a simple test case.
vm_insnhelper.c: block argument at tailcall
- vm_insnhelper.c (vm_call_iseq_setup_tailcall): check interrupts after set up the new frame, not the passed block to be clobbered by invoked finalizers and so on. [Bug #13107]
#2 [ruby-core:79010] Updated by eugeneius (Eugene Kenny) 6 months ago
mongo gem is also affected by this bug (https://jira.mongodb.org/browse/RUBY-1191). Running the tests in the
spec/mongo/grid/stream/read_spec.rb file reliably reproduces it.
I bisected the changes to forwardable.rb between v2.3.0 and v2.4.0, and determined that the bug was introduced in r55376.
I've attached a patch that fixes the problem, although it effectively reverts the optimisation from r55376, so there may be a performance impact.
#3 [ruby-core:79012] Updated by eugeneius (Eugene Kenny) 6 months ago
Here's another patch that also fixes the problem, while keeping the optimisation from r55376.
I'll admit that I have no idea what this option does or how it could cause this bug - I noticed that the "portable" implementation of
forwardable/impl.rb wasn't affected, and fiddled with the MRI-specific one until it worked. Please review this patch carefully if you intend to use it!
tailcall_optimization also appears to work, although I think we need that option to get a sensible stack trace. Maybe
trace_instruction: false, tailcall_optimization: true is an invalid combination?
#6 Updated by nobu (Nobuyoshi Nakada) 6 months ago
- Status changed from Feedback to Closed
#7 [ruby-core:79018] Updated by nobu (Nobuyoshi Nakada) 6 months ago
When interrupted by a finalizer during setting up tailcall frame, a block argument on the stack was overwritten by the magic number in the finalizer frame which looks an
I tried in vain to make a test case, but a failure in mongo-ruby-driver seems fixed.
Could you try the latest trunk?
#11 [ruby-core:79120] Updated by vo.x (Vit Ondruch) 5 months ago
And I can confirm that also rack-test test suite is passing with this patch .
#13 [ruby-core:80207] Updated by Benoit_Tigeot (Benoit Tigeot) 3 months ago
firstname.lastname@example.org (Thomas Walpole) wrote:
This appears to be fixed in latest trunk now. Is there any info on when a 2.4.1 will be released - seems like a pretty serious issue.
I am in the same situation actually. Locked because of this issue. Any idea when 2.4.1 will be released?