[MacRuby] #620: Yielding a block inside a loop in a thread crashes the VM
#620: Yielding a block inside a loop in a thread crashes the VM ---------------------------------+------------------------------------------ Reporter: honglilai@… | Owner: lsansonetti@… Type: defect | Status: new Priority: blocker | Milestone: Component: MacRuby | Keywords: ---------------------------------+------------------------------------------ Yielding a block inside a loop directly in the Thread block results in a VM crash: {{{ Assertion failed: ((b->flags & flags) == flags), function rb_vm_prepare_block, file dispatcher.cpp, line 1737. Abort trap }}} Interestingly, the problem doesn't occur of the loop is wrapped inside a function. Reproduce with: {{{ require 'thread' def do_yield yield end # This doesn't crash. Thread.new do do_yield do end do_yield do end do_yield do end end.join # This doesn't crash either. def do_yield_loop_in_function while true do_yield do end end end Thread.new do do_yield_loop_in_function end.join # This crashes. Thread.new do 3.times do do_yield do end end end.join # This crashes too. Thread.new do while true do_yield do end end end.join }}} -- Ticket URL: <http://www.macruby.org/trac/ticket/620> MacRuby <http://macruby.org/>
#620: Yielding a block inside a loop in a thread crashes the VM ---------------------------------+------------------------------------------ Reporter: honglilai@… | Owner: lsansonetti@… Type: defect | Status: new Priority: blocker | Milestone: Component: MacRuby | Keywords: ---------------------------------+------------------------------------------ Comment(by watson1978@…): In dispatcher.cpp: When removed flag of VM_BLOCK_THREAD from b->flags in rb_vm_yield_args(), * Other than a main thread * returned "*cached = true" in RoxorVM::uncache_or_create_block() At the above condition, VM_BLOCK_THREAD does not set to b->flags. So, calls yield at second time, assertion failed at "assert((b->flags & flags) == flags);" in rb_vm_prepare_block(). I atach a patch file. Please check it. -- Ticket URL: <http://www.macruby.org/trac/ticket/620#comment:3> MacRuby <http://macruby.org/>
#620: Yielding a block inside a loop in a thread crashes the VM ---------------------------------+------------------------------------------ Reporter: honglilai@… | Owner: lsansonetti@… Type: defect | Status: new Priority: blocker | Milestone: Component: MacRuby | Keywords: ---------------------------------+------------------------------------------ Comment(by lsansonetti@…): Thanks for the detective work & patch! It seems clearer now. I wonder if the following patch isn't safer, though. {{{ Index: dispatcher.cpp =================================================================== --- dispatcher.cpp (revision 4369) +++ dispatcher.cpp (working copy) @@ -1338,7 +1338,7 @@ } else { assert(b->dvars_size == dvars_size); - assert((b->flags & flags) == flags); + assert((b->flags & flags) == (flags & ~VM_BLOCK_THREAD)); } b->proc = Qnil; }}} Actually, I wonder if we shouldn't get rid of this assert. -- Ticket URL: <http://www.macruby.org/trac/ticket/620#comment:4> MacRuby <http://macruby.org/>
#620: Yielding a block inside a loop in a thread crashes the VM ---------------------------------+------------------------------------------ Reporter: honglilai@… | Owner: lsansonetti@… Type: defect | Status: new Priority: blocker | Milestone: Component: MacRuby | Keywords: ---------------------------------+------------------------------------------ Comment(by watson1978@…): With your patch,in the following conditions, I think that assertion failed occures. * b->flags = VM_BLOCK_THREAD * flags = VM_BLOCK_THREAD * b->flags & flags => VM_BLOCK_THREAD * (flags & ~VM_BLOCK_THREAD) => 0 -- Ticket URL: <http://www.macruby.org/trac/ticket/620#comment:5> MacRuby <http://macruby.org/>
#620: Yielding a block inside a loop in a thread crashes the VM ---------------------------------+------------------------------------------ Reporter: honglilai@… | Owner: lsansonetti@… Type: defect | Status: closed Priority: blocker | Milestone: MacRuby 0.7 Component: MacRuby | Resolution: fixed Keywords: | ---------------------------------+------------------------------------------ Changes (by lsansonetti@…): * status: new => closed * resolution: => fixed * milestone: => MacRuby 0.7 Comment: I see, I think you're right :-) I merged your patch in r4379. Thanks a lot for taking the time to work on this :-) -- Ticket URL: <http://www.macruby.org/trac/ticket/620#comment:6> MacRuby <http://macruby.org/>
#620: Yielding a block inside a loop in a thread crashes the VM ---------------------------------+------------------------------------------ Reporter: honglilai@… | Owner: lsansonetti@… Type: defect | Status: closed Priority: blocker | Milestone: MacRuby 0.7 Component: MacRuby | Resolution: fixed Keywords: | ---------------------------------+------------------------------------------ Comment(by watson1978@…): Thank you for fixing this issue! :) -- Ticket URL: <http://www.macruby.org/trac/ticket/620#comment:7> MacRuby <http://macruby.org/>
participants (1)
-
MacRuby