Hi --

Sorry for very late response!


2009/8/30 Mark Moseley <redmine / ruby-lang.org>:
> 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, #<Binding:0x824d10c>, Kernel]
    ["line", "-e", 3, nil, #<Binding:0x824cfe0>, nil]
    ["c-call", "-e", 3, :new, #<Binding:0x824cf04>, Thread]
    ["c-call", "-e", 3, :initialize, #<Binding:0x824ce00>, Thread]
    ["c-return", "-e", 3, :initialize, #<Binding:0x824ccfc>, Thread]
    foo
    ["c-return", "-e", 3, :new, #<Binding:0x824cc0c>, Thread]
    ["c-call", "-e", 3, :join, #<Binding:0x824cb30>, Thread]
    ["c-return", "-e", 3, :join, #<Binding:0x824ca54>, 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 <mame / tsg.ne.jp>