From: Eric Wong Date: 2011-04-06T08:50:37+09:00 Subject: [ruby-core:35622] Re: [Ruby 1.9 - Bug #4289] Timeouts in threads cause SEGV 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 > 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