[MacRuby] #1347: Segfault occurs when invoked a Module#define_method within some threads.
#1347: Segfault occurs when invoked a Module#define_method within some threads. ----------------------------------+----------------------------------------- Reporter: watson1978@… | Owner: lsansonetti@… Type: defect | Status: new Priority: blocker | Milestone: Component: MacRuby | Keywords: ----------------------------------+----------------------------------------- Test Script: {{{ #!ruby m1 = Module.new m2 = Module.new Thread.new { 100.times do |i| m1.instance_eval{ define_method("m1#{i}", Proc.new{}) } end } 100.times do |i| m2.instance_eval{ define_method("m2#{i}", Proc.new{}) } end }}} BackTrace: {{{ (gdb) t a a bt Thread 4 (process 19426): #0 0x0000000000000000 in ?? () Thread 3 (process 19426): #0 0x00007fff83cc7116 in free () #1 0x00000001009084d2 in std::_Rb_tree<void const*, std::pair<void const* const, llvm::Pass*>, std::_Select1st<std::pair<void const* const, llvm::Pass*> >, std::less<void const*>, std::allocator<std::pair<void const* const, llvm::Pass*> > >::erase () at StringRef.h:59 #2 0x0000000100903e1b in llvm::PMDataManager::freePass () at StringRef.h:59 #3 0x000000010090449c in llvm::PMDataManager::removeDeadPasses () at StringRef.h:59 #4 0x0000000100904e3d in llvm::FPPassManager::runOnFunction () at StringRef.h:59 #5 0x000000010090513c in llvm::FunctionPassManagerImpl::run () at StringRef.h:59 #6 0x0000000100905429 in llvm::FunctionPassManager::run () at StringRef.h:59 #7 0x0000000100142761 in RoxorCore::optimize (this=0x102068200, func=0x10360c2f0) at vm.cpp:554 #8 0x00000001001427da in RoxorCore::compile (this=0x102068200, func=0x10360c2f0, run_optimize=true) at vm.cpp:591 #9 0x0000000100146054 in rb_vm_define_method3 (klass=0x200020760, mid=13008, block=0x2000b9a60) at vm.cpp:2738 #10 0x0000000100033109 in rb_mod_define_method (mod=8590067552, sel=0x101150790, argc=2, argv=0x10177dd58) at proc.c:1025 #11 0x000000010012e2b3 in ruby_dispatch [inlined] () at /Users/watson/src /macruby-master/dispatcher.cpp:448 #12 0x000000010012e2b3 in rb_vm_dispatch () at dispatcher.cpp:872 #13 0x0000000101500764 in ?? () #14 0x0000000101501469 in ?? () #15 0x0000000100135ddb in __rb_vm_bcall [inlined] () at /Users/watson/src /macruby-master/dispatcher.cpp:98 #16 0x0000000100135ddb in vm_block_eval [inlined] () at /Users/watson/src /macruby-master/dispatcher.cpp:1221 #17 0x0000000100135ddb in rb_vm_yield_under () at dispatcher.cpp:1321 #18 0x00000001000db958 in specific_eval (argc=0, argv=0x0, klass=8590067488, self=8590067552) at vm_eval.c:339 #19 0x00000001000dbee3 in rb_obj_instance_eval_imp (self=8590067552, sel=0x100fde130, top=8590062336, argc=0, argv=0x0) at vm_eval.c:507 #20 0x000000010012e366 in ruby_dispatch [inlined] () at /Users/watson/src /macruby-master/dispatcher.cpp:457 #21 0x000000010012e366 in rb_vm_dispatch () at dispatcher.cpp:872 #22 0x0000000101500764 in ?? () #23 0x0000000101500fe3 in ?? () #24 0x0000000100134ccb in __rb_vm_bcall [inlined] () at /Users/watson/src /macruby-master/dispatcher.cpp:100 #25 0x0000000100134ccb in vm_block_eval [inlined] () at /Users/watson/src /macruby-master/dispatcher.cpp:1221 #26 0x0000000100134ccb in rb_vm_yield_args () at dispatcher.cpp:1278 #27 0x00000001000db2fd in rb_vm_yield (argc=1, argv=0x10177f928) at vm.h:697 #28 0x00000001000db2d0 in rb_yield (val=141) at vm_eval.c:183 #29 0x000000010004d1da in int_dotimes (num=401, sel=0x100fe7350) at numeric.c:3241 #30 0x000000010012e8b4 in __rb_vm_rcall [inlined] () at /Users/watson/src /macruby-master/dispatcher.cpp:159 #31 0x000000010012e8b4 in ruby_dispatch [inlined] () at /Users/watson/src /macruby-master/dispatcher.cpp:466 #32 0x000000010012e8b4 in rb_vm_dispatch () at dispatcher.cpp:872 #33 0x0000000101500764 in ?? () #34 0x0000000101500ca1 in ?? () #35 0x0000000100132c67 in __rb_vm_bcall [inlined] () at /Users/watson/src /macruby-master/dispatcher.cpp:98 #36 0x0000000100132c67 in vm_block_eval [inlined] () at /Users/watson/src /macruby-master/dispatcher.cpp:1221 #37 0x0000000100132c67 in rb_vm_block_eval (b=0x200020ba0, argc=0, argv=0x0) at dispatcher.cpp:1228 #38 0x000000010014d093 in rb_vm_thread_run (thread=8590068192) at vm.cpp:4856 #39 0x00007fff83cf9fd6 in _pthread_start () #40 0x00007fff83cf9e89 in thread_start () Thread 2 (process 19426): #0 0x00007fff833eeac0 in Auto::visitAllocatedBlocks<Auto::scan_retained_and_old_blocks_visitor> () #1 0x00007fff833ed944 in Auto::MemoryScanner::scan_retained_and_old_blocks () #2 0x00007fff833e8a47 in Auto::Collector::check_roots () #3 0x00007fff833ed8b1 in Auto::MemoryScanner::scan () #4 0x00007fff833e277d in Auto::Zone::collect () #5 0x00007fff833cba7e in auto_collect_internal () #6 0x00007fff833cc0bd in auto_collection_work () #7 0x00007fff83cfcd64 in _dispatch_call_block_and_release () #8 0x00007fff83cdb8d2 in _dispatch_queue_drain () #9 0x00007fff83cdb734 in _dispatch_queue_invoke () #10 0x00007fff83cdb2de in _dispatch_worker_thread2 () #11 0x00007fff83cdac08 in _pthread_wqthread () #12 0x00007fff83cdaaa5 in start_wqthread () Thread 1 (process 19426): #0 0x00000001006e1299 in llvm::InstCombiner::DoOneIteration () at StringRef.h:59 #1 0x00000001006e29a3 in llvm::InstCombiner::runOnFunction () at StringRef.h:59 #2 0x0000000100904fa0 in llvm::FPPassManager::runOnFunction () at StringRef.h:59 #3 0x000000010090513c in llvm::FunctionPassManagerImpl::run () at StringRef.h:59 #4 0x0000000100905429 in llvm::FunctionPassManager::run () at StringRef.h:59 #5 0x0000000100142761 in RoxorCore::optimize (this=0x102068200, func=0x104835470) at vm.cpp:554 #6 0x00000001001427da in RoxorCore::compile (this=0x102068200, func=0x104835470, run_optimize=true) at vm.cpp:591 #7 0x0000000100146054 in rb_vm_define_method3 (klass=0x200020b20, mid=13000, block=0x2000b99e0) at vm.cpp:2738 #8 0x0000000100033109 in rb_mod_define_method (mod=8590068512, sel=0x101150790, argc=2, argv=0x7fff5fbfb0a8) at proc.c:1025 #9 0x000000010012e2b3 in ruby_dispatch [inlined] () at /Users/watson/src /macruby-master/dispatcher.cpp:448 #10 0x000000010012e2b3 in rb_vm_dispatch () at dispatcher.cpp:872 #11 0x0000000101500764 in ?? () #12 0x0000000101501289 in ?? () #13 0x0000000100135ddb in __rb_vm_bcall [inlined] () at /Users/watson/src /macruby-master/dispatcher.cpp:98 #14 0x0000000100135ddb in vm_block_eval [inlined] () at /Users/watson/src /macruby-master/dispatcher.cpp:1221 #15 0x0000000100135ddb in rb_vm_yield_under () at dispatcher.cpp:1321 #16 0x00000001000db958 in specific_eval (argc=0, argv=0x0, klass=8590068448, self=8590068512) at vm_eval.c:339 #17 0x00000001000dbee3 in rb_obj_instance_eval_imp (self=8590068512, sel=0x100fde130, top=8590062336, argc=0, argv=0x0) at vm_eval.c:507 #18 0x000000010012e366 in ruby_dispatch [inlined] () at /Users/watson/src /macruby-master/dispatcher.cpp:457 #19 0x000000010012e366 in rb_vm_dispatch () at dispatcher.cpp:872 #20 0x0000000101500764 in ?? () #21 0x0000000101500de3 in ?? () #22 0x0000000100134ccb in __rb_vm_bcall [inlined] () at /Users/watson/src /macruby-master/dispatcher.cpp:100 #23 0x0000000100134ccb in vm_block_eval [inlined] () at /Users/watson/src /macruby-master/dispatcher.cpp:1221 #24 0x0000000100134ccb in rb_vm_yield_args () at dispatcher.cpp:1278 #25 0x00000001000db2fd in rb_vm_yield (argc=1, argv=0x7fff5fbfcc78) at vm.h:697 #26 0x00000001000db2d0 in rb_yield (val=141) at vm_eval.c:183 #27 0x000000010004d1da in int_dotimes (num=401, sel=0x100fe7350) at numeric.c:3241 #28 0x000000010012e8b4 in __rb_vm_rcall [inlined] () at /Users/watson/src /macruby-master/dispatcher.cpp:159 #29 0x000000010012e8b4 in ruby_dispatch [inlined] () at /Users/watson/src /macruby-master/dispatcher.cpp:466 #30 0x000000010012e8b4 in rb_vm_dispatch () at dispatcher.cpp:872 #31 0x0000000101500764 in ?? () #32 0x000000010150027b in ?? () #33 0x000000010014a072 in rb_vm_run (fname=0x2000a8cc0 "/Users/watson/tmp/tt.rb", node=0x2000255e0, binding=0x0, inside_eval=false) at vm.cpp:4115 #34 0x000000010002898b in ruby_run_node (n=0x2000255e0) at eval.c:211 #35 0x0000000100000be3 in main (argc=2, argv=0x100f1c040, envp=0x7fff5fbfde58) at main.cpp:40 (gdb) }}} -- Ticket URL: <http://www.macruby.org/trac/ticket/1347> MacRuby <http://macruby.org/>
#1347: Segfault occurs when invoked a Module#define_method within some threads. ----------------------------------+----------------------------------------- Reporter: watson1978@… | Owner: lsansonetti@… Type: defect | Status: new Priority: blocker | Milestone: Component: MacRuby | Keywords: ----------------------------------+----------------------------------------- Comment(by watson1978@…): To fix this problem and #1348, it looks like it would need to exclusive control as following. {{{ #!diff diff --git a/vm.cpp b/vm.cpp index eebda6d..fb57f37 100644 --- a/vm.cpp +++ b/vm.cpp @@ -1022,6 +1022,7 @@ RoxorCore::add_method(Class klass, SEL sel, IMP imp, IMP ruby_imp, real_node->sel = sel; // Cache the implementation. + GET_CORE()->lock(); std::map<IMP, rb_vm_method_node_t *>::iterator iter2 = ruby_imps.find(imp); rb_vm_method_node_t *node; if (iter2 == ruby_imps.end()) { @@ -1033,6 +1034,7 @@ RoxorCore::add_method(Class klass, SEL sel, IMP imp, IMP ruby_imp, node = iter2->second; assert(node->objc_imp == imp); } + GET_CORE()->unlock(); node->klass = klass; node->arity = arity; node->flags = flags; @@ -3052,7 +3054,7 @@ RoxorCore::gen_to_ocval_convertor(std::string type) #endif } -static const int VM_LVAR_USES_SIZE = 8; +static const int VM_LVAR_USES_SIZE = 16; enum { VM_LVAR_USE_TYPE_BLOCK = 1, VM_LVAR_USE_TYPE_BINDING = 2 @@ -3072,6 +3074,7 @@ rb_vm_add_lvar_use(rb_vm_var_uses **var_uses, void *use, return; } + GET_CORE()->lock(); if ((*var_uses == NULL) || ((*var_uses)->uses_count == VM_LVAR_USES_SIZE)) { @@ -3087,6 +3090,7 @@ rb_vm_add_lvar_use(rb_vm_var_uses **var_uses, void *use, GC_WB(&(*var_uses)->uses[current_index], use); (*var_uses)->use_types[current_index] = use_type; ++(*var_uses)->uses_count; + GET_CORE()->unlock(); } extern "C" }}} MacRuby crashes If does not change VM_LVAR_USES_SIZE. but, I do not know yet why it needs to change :( -- Ticket URL: <http://www.macruby.org/trac/ticket/1347#comment:1> MacRuby <http://macruby.org/>
#1347: Segfault occurs when invoked a Module#define_method within some threads. ----------------------------------+----------------------------------------- Reporter: watson1978@… | Owner: lsansonetti@… Type: defect | Status: new Priority: blocker | Milestone: Component: MacRuby | Keywords: ----------------------------------+----------------------------------------- Comment(by watson1978@…): previous patch had been cause a deadlock :( so, I rewrote a patch. {{{ #!diff diff --git a/vm.cpp b/vm.cpp index eebda6d..9e37186 100644 --- a/vm.cpp +++ b/vm.cpp @@ -2672,8 +2672,10 @@ define_method: char types[100]; resolve_method_type(types, sizeof types, klass, method, sel, types_count); + GET_CORE()->lock(); node = GET_CORE()->add_method(klass, sel, objc_imp, ruby_imp, arity, flags, types); + GET_CORE()->unlock(); if (!redefined) { if (!genuine_selector && arity.max != arity.min) { @@ -3052,7 +3054,7 @@ RoxorCore::gen_to_ocval_convertor(std::string type) #endif } -static const int VM_LVAR_USES_SIZE = 8; +static const int VM_LVAR_USES_SIZE = 16; enum { VM_LVAR_USE_TYPE_BLOCK = 1, VM_LVAR_USE_TYPE_BINDING = 2 @@ -3072,6 +3074,7 @@ rb_vm_add_lvar_use(rb_vm_var_uses **var_uses, void *use, return; } + GET_CORE()->lock(); if ((*var_uses == NULL) || ((*var_uses)->uses_count == VM_LVAR_USES_SIZE)) { @@ -3087,6 +3090,7 @@ rb_vm_add_lvar_use(rb_vm_var_uses **var_uses, void *use, GC_WB(&(*var_uses)->uses[current_index], use); (*var_uses)->use_types[current_index] = use_type; ++(*var_uses)->uses_count; + GET_CORE()->unlock(); } extern "C" }}} To fix #1348, just change a VM_LVAR_USES_SIZE -- Ticket URL: <http://www.macruby.org/trac/ticket/1347#comment:2> MacRuby <http://macruby.org/>
#1347: Segfault occurs when invoked a Module#define_method within some threads. ----------------------------------+----------------------------------------- Reporter: watson1978@… | Owner: lsansonetti@… Type: defect | Status: new Priority: blocker | Milestone: Component: MacRuby | Keywords: ----------------------------------+----------------------------------------- Comment(by lsansonetti@…): I agree for locking around add_method(). But I don't think locking in rb_vm_add_lvar_use() is the way to go. I believe the lvar_use thing has never been designed for thread safety, and I wonder if there isn't a better way to solve these race conditions. -- Ticket URL: <http://www.macruby.org/trac/ticket/1347#comment:3> MacRuby <http://macruby.org/>
participants (1)
-
MacRuby