Issue #7032 has been updated by ktsj (Kazuki Tsujimoto).


=begin
SEGV???????ゃ????茯??鴻??帥?障????????

?????????医????с?篁ヤ????潟?若?????100%????????障?????

 # Thread(A)
 th = Thread.new { loop { 0 } }
 
 # Thread(B)
 loop do
   # test_remove_in_trace
   func = lambda do |e, f, l, i, b, k|
     set_trace_func(nil)
     eval("self", b) # allocate many objects
   end
   set_trace_func(func)
 end

????????????????罨???????????c??????????????с?????

(1) Thread(B)???set_trace_func(nil)??????hook???RUBY_HOOK_FLAG_DELETED??????違??腴????
(2) ??翫?????Thread(A)?????????帥????????(Thread(A)???trace_running???0???障?障????)exec_hooks???絎?茵??????????clean_hook?????????
(3) hook????筝???≪?????鴻??違???????????吾?с?????????????????????
(4) Thread(B)???祉?????hook?????≦?鴻??ゃ???c????????????????????с????????純?<??

荅?????????違??腴???????鴻????????????c?茹??上??????茵??????????????????????????純?<????????障????????

 diff --git a/vm_trace.c b/vm_trace.c
 index 90c2bd2..1393e89 100644
 --- a/vm_trace.c
 +++ b/vm_trace.c
 @@ -41,6 +41,7 @@ typedef struct rb_event_hook_struct {
      rb_event_flag_t events;
      rb_event_hook_func_t func;
      VALUE data;
 +    rb_thread_id_t deleted_thread_id;
      struct rb_event_hook_struct *next;
  } rb_event_hook_t;
  
 @@ -183,11 +184,13 @@ remove_event_hook(rb_hook_list_t *list, rb_event_hook_func_t func, VALUE data)
  {
      int ret = 0;
      rb_event_hook_t *hook = list->hooks;
 +    rb_thread_t *th = GET_THREAD();
  
      while (hook) {
  	if (func == 0 || hook->func == func) {
  	    if (data == Qundef || hook->data == data) {
  		hook->hook_flags |= RUBY_HOOK_FLAG_DELETED;
 +		hook->deleted_thread_id = th->thread_id;
  		ret+=1;
  		list->need_clean++;
  	    }
 @@ -250,12 +253,13 @@ static void
  clean_hooks(rb_hook_list_t *list)
  {
      rb_event_hook_t *hook, **nextp = &list->hooks;
 +    rb_thread_t *th = GET_THREAD();
  
      list->events = 0;
      list->need_clean = 0;
  
      while ((hook = *nextp) != 0) {
 -	if (hook->hook_flags & RUBY_HOOK_FLAG_DELETED) {
 +	if (hook->hook_flags & RUBY_HOOK_FLAG_DELETED && hook->deleted_thread_id == th->thread_id) {
  	    *nextp = hook->next;
  	    recalc_remove_ruby_vm_event_flags(hook->events);
  	    xfree(hook);
=end

----------------------------------------
Bug #7032: TestSetTraceFunc????茵???紊?????????
https://bugs.ruby-lang.org/issues/7032#change-30588

Author: ktsj (Kazuki Tsujimoto)
Status: Open
Priority: Normal
Assignee: 
Category: 
Target version: 
ruby -v: ruby 2.0.0dev (2012-09-16 trunk 36980) [x86_64-linux]


=begin
莨紙??с?????

篁ヤ???????????????鴻?????絎?茵?????????????障?????TestSetTraceFunc????茵???紊????????????????????????障?????

 $ make TESTS='-vq -j1 objspace/test_objspace.rb \
                       json/test_json_fixtures.rb \
                       json/test_json.rb \
                       xmlrpc/test_marshal.rb \
                       xmlrpc/test_features.rb \
                       uri/test_parser.rb \
                       uri/test_http.rb \
                       uri/test_ftp.rb \
                       uri/test_generic.rb \
                       io/console/test_io_console.rb \
                       rexml/test_stream.rb \
                       rexml/test_light.rb \
                       rexml/test_xpathtext.rb \
                       rexml/test_xpath_pred.rb \
                       rexml/test_rexml_issuezilla.rb \
                       ruby/test_case.rb \
                       ruby/test_hash.rb \
                       ruby/test_marshal.rb \
                       ruby/test_proc.rb \
                       ruby/test_yield.rb \
                       ruby/test_string.rb \
                       ruby/test_settracefunc.rb' test-all

紊掩??????????宴?若?鴻??2??ょ∈茯????????????
1??ゃ?????Ruby???????уけ???????????????:

 TestSetTraceFunc#test_break = 0.00 s = .
 TestSetTraceFunc#test_c_call = 0.00 s = .
 TestSetTraceFunc#test_call = 0.00 s = .
 TestSetTraceFunc#test_class = 0.00 s = .
 TestSetTraceFunc#test_invalid_proc = 0.00 s = .
 TestSetTraceFunc#test_raise = 0.00 s = .
 TestSetTraceFunc#test_raise_in_trace = 0.00 s = .
 TestSetTraceFunc#test_remove_in_trace = 0.00 s = .
 TestSetTraceFunc#test_return = 0.00 s = .
 TestSetTraceFunc#test_return2 = 0.00 s = .
 /home/k_tsj/work/ruby/lib/test/unit/parallel.rb:40:in `rescue in block in _run_suite': undefined local variable or method `local_var' for #<Test::Unit::Worker:0x002aaaaaf8a5a0> (NameError)
         xyzzy:2:in `eval'
         xyzzy:2:in `block in trace_by_tracepoint'
         /home/k_tsj/work/ruby/lib/test/unit/parallel.rb:40:in `rescue in block in _run_suite'
         /home/k_tsj/work/ruby/lib/test/unit/parallel.rb:36:in `block in _run_suite'

2??ゃ?????SEGV???莎激????????????????障?????

 TestSetTraceFunc#test_break = 0.00 s = .
 TestSetTraceFunc#test_c_call = 0.00 s = .
 /home/k_tsj/work/ruby/lib/test/unit/parallel.rb:37: [BUG] Segmentation fault
 ruby 2.0.0dev (2012-09-16 trunk 36980) [x86_64-linux]
 
 -- Control frame information -----------------------------------------------
 c:0002 p:0045 s:0006 b:0005 e:000e40 BLOCK  /home/k_tsj/work/ruby/lib/test/unit/parallel.rb:37 [FINISH]
 c:0001 p:---- s:0002 b:0002 e:000001 TOP    [FINISH]
 
 /home/k_tsj/work/ruby/lib/test/unit/parallel.rb:37:in `block in _run_suite'
=end



-- 
http://bugs.ruby-lang.org/