You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
UPD: I can confirm that gc_callback can get executed after rb_context_eval_unsafe was called, but before nogvl_context_eval. MEM_SOFTLIMIT_REACHED is set to false in nogvl_context_eval, but isolate execution would still get terminated, leading to the wrong exception being raised.
I've noticed a weird behavior when I set the timeout for the context, it sometimes throws MiniRacer::ScriptTerminatedError exception instead of expected MiniRacer::V8OutOfMemoryError. The script executes fast enough so there shouldn't be the actual timeout error.
Here is an example tests that reproduced the issue:
# This will passdeftest_max_memory_2context=MiniRacer::Context.new(max_memory: 1_000_000)assert_raises(MiniRacer::V8OutOfMemoryError)do500.timesdo |i|
script="var t#{i} = '#{SecureRandom.uuid * 1000}'; Array.from(new Array(10000)).map((e, i) => i + 1)[1];"context.eval(script)sleep0.001endendend# This will fail:deftest_max_memory_3context=MiniRacer::Context.new(max_memory: 1_000_000,timeout: 20_000)assert_raises(MiniRacer::V8OutOfMemoryError)do500.timesdo |i|
script="var t#{i} = '#{SecureRandom.uuid * 1000}'; Array.from(new Array(10000)).map((e, i) => i + 1)[1];"context.eval(script)sleep0.001endendend
.FFailure:
MiniRacerTest#test_max_memory_3 [.../.../mini_racer/test/mini_racer_test.rb:335]:[MiniRacer::V8OutOfMemoryError]exceptionexpected, not
Class: <MiniRacer::ScriptTerminatedError>
Message: <"JavaScript was terminated (either by timeout or explicitly)">
---Backtrace---
.../.../mini_racer/lib/mini_racer.rb:209:in`eval_unsafe'.../.../mini_racer/lib/mini_racer.rb:209:in `block(2levels)ineval'.../.../mini_racer/lib/mini_racer.rb:350:in `timeout'
.../.../mini_racer/lib/mini_racer.rb:208:in`block in eval'.../.../mini_racer/lib/mini_racer.rb:206:in `synchronize'.../.../mini_racer/lib/mini_racer.rb:206:in `eval'
.../.../mini_racer/test/mini_racer_test.rb:338:in`block (2 levels) in test_max_memory_3'.../.../mini_racer/test/mini_racer_test.rb:336:in `times'.../.../mini_racer/test/mini_racer_test.rb:336:in `block in test_max_memory_3'
UPD: I can confirm that
gc_callback
can get executed afterrb_context_eval_unsafe
was called, but beforenogvl_context_eval
.MEM_SOFTLIMIT_REACHED
is set to false innogvl_context_eval
, but isolate execution would still get terminated, leading to the wrong exception being raised.It looks like some operations inside of timeout function(https://github.com/rubyjs/mini_racer/blob/master/lib/mini_racer.rb#L328), like
Mutex.new
are just slow enough to allow for this race condition to happen in the test example.I've noticed a weird behavior when I set the timeout for the context, it sometimes throws
MiniRacer::ScriptTerminatedError
exception instead of expectedMiniRacer::V8OutOfMemoryError
. The script executes fast enough so there shouldn't be the actual timeout error.Here is an example tests that reproduced the issue:
I suspect that might be some sort of race condition with V8 GC and
MEM_SOFTLIMIT_REACHED
flag (https://github.com/rubyjs/mini_racer/blob/master/ext/mini_racer_extension/mini_racer_extension.cc#L336, https://github.com/rubyjs/mini_racer/blob/master/ext/mini_racer_extension/mini_racer_extension.cc#L217), but I haven't got a chance to dig into that yet.The text was updated successfully, but these errors were encountered: