From: Yusuke ENDOH Date: 2010-01-07T23:28:45+09:00 Subject: [ruby-core:27471] Re: [Feature #2012] Set event_flags on thread creation if hook exists Hi -- Sorry for very late response! 2009/8/30 Mark Moseley : > In ruby-debug, when a user sets a breakpoint that ends up executed by a later-created thread, then nothing will happen. Confirmed. $ ./ruby.org -e ' > set_trace_func(proc {|*a| p a }) > Thread.new { puts "foo" }.join > ' ["c-return", "-e", 2, :set_trace_func, #, Kernel] ["line", "-e", 3, nil, #, nil] ["c-call", "-e", 3, :new, #, Thread] ["c-call", "-e", 3, :initialize, #, Thread] ["c-return", "-e", 3, :initialize, #, Thread] foo ["c-return", "-e", 3, :new, #, Thread] ["c-call", "-e", 3, :join, #, Thread] ["c-return", "-e", 3, :join, #, Thread] ("c-call" event to the method `puts' is not found) This issue affects the coverage feature too. It fails to measure coverage that is run in sub thread. [ruby-dev:39950] > I propose adding the following patch to the core: > > Index: thread.c > =================================================================== > --- thread.c (revision 24710) > +++ thread.c (working copy) > @@ -497,6 +497,9 @@ > th->thgroup = GET_THREAD()->thgroup; > > native_mutex_initialize(&th->interrupt_lock); > + if (GET_VM()->event_hooks != NULL) > + th->event_flags |= RUBY_EVENT_VM; > + > /* kick thread */ > st_insert(th->vm->living_threads, thval, (st_data_t) th->thread_id); > native_thread_create(th); Basically I agree with your patch. But it leaves event_flags true even if all vm-level hooks are removed. How about this patch: diff --git a/thread.c b/thread.c index 0ba41c7..c082471 100644 --- a/thread.c +++ b/thread.c @@ -531,6 +531,9 @@ thread_create_core(VALUE thval, VALUE args, VALUE (*fn)(ANYARGS)) th->thgroup = GET_THREAD()->thgroup; native_mutex_initialize(&th->interrupt_lock); + if (GET_VM()->event_hooks != NULL) + th->event_flags |= RUBY_EVENT_VM; + /* kick thread */ st_insert(th->vm->living_threads, thval, (st_data_t) th->thread_id); err = native_thread_create(th); @@ -3750,7 +3753,12 @@ rb_threadptr_exec_event_hooks(rb_thread_t *th, rb_event_flag_t flag, VALUE self, exec_event_hooks(th->event_hooks, flag, self, id, klass); } if (wait_event & RUBY_EVENT_VM) { - exec_event_hooks(th->vm->event_hooks, flag, self, id, klass); + if (th->vm->event_hooks == NULL) { + th->event_flags &= (~RUBY_EVENT_VM); + } + else { + exec_event_hooks(th->vm->event_hooks, flag, self, id, klass); + } } th->errinfo = errinfo; } -- Yusuke ENDOH