Motohiro KOSAKI wrote:
>  Running deadlock_test.rb in [Bug#4266] on trunk makes segfault. git bisect indicate
>  first bad commit is below.
>  
>  ---------------------------------------------------------------------------
>  commit d295957957c828588a8ca3c7b8619c7a93be6b5c
>  Author: akr <akr / b2dd03c8-39d4-4d8f-98ff-823fe69b080e>
>  Date:   Tue Nov 2 22:37:08 2010 +0000
>  
>      * vm_method.c (rb_clear_cache_by_class): just return if the class has
>        no method.  reported by Eric Wong.  [ruby-core:32689]
>  
>  
>      git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@29673 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
>  
>  --------------------------------------------------------------------------------
>  
>  Plus, I've confirmed latest trunk + revert d2959579 doesn't makes segfault.

Yes, r29673 is bad, I think.  The method cache caches for the subclass
even if the method belongs to a superclass.  I confirmed it with the
following debug patch that writes to stderr whenever a method-less class
is cleared:

diff --git a/vm_method.c b/vm_method.c
index 278941a..021b703 100644
--- a/vm_method.c
+++ b/vm_method.c
@@ -84,9 +84,10 @@ void
 rb_clear_cache_by_class(VALUE klass)
 {
     struct cache_entry *ent, *end;
+    int nr_cleared = 0, check_empty = 0;
 
     if (RCLASS_M_TBL(klass)->num_entries == 0)
-        return;
+	check_empty = 1;
 
     rb_vm_change_state();
 
@@ -98,9 +99,12 @@ rb_clear_cache_by_class(VALUE klass)
 	if (ent->klass == klass || (ent->me && ent->me->klass == klass)) {
 	    ent->me = 0;
 	    ent->mid = 0;
+	    ++nr_cleared;
 	}
 	ent++;
     }
+    if (check_empty && nr_cleared)
+	fprintf(stderr, "cleared %d methods for method-less class\n", nr_cleared);
 }
 
 VALUE

-- 
Eric Wong