From: "wanabe (_ wanabe) via ruby-core" Date: 2024-12-08T04:37:45+00:00 Subject: [ruby-core:120130] [Ruby master Bug#20934] `UnboundMethod#bind_call` may cause "double free or corruption" with Ractor Issue #20934 has been updated by wanabe (_ wanabe). Thanks for your comment. It looks like a race condition between `rb_method_definition_release()` and `method_definition_addref()`. Applying the following patch suppressed the problem. ```patch diff --git a/vm_method.c b/vm_method.c index 69a533b182..725b2a99ac 100644 --- a/vm_method.c +++ b/vm_method.c @@ -518,6 +518,7 @@ static void rb_method_definition_release(rb_method_definition_t *def) { if (def != NULL) { + RB_VM_LOCK_ENTER(); const int reference_count = def->reference_count; def->reference_count--; @@ -535,6 +536,7 @@ rb_method_definition_release(rb_method_definition_t *def) if (METHOD_DEBUG) fprintf(stderr, "-%p-%s:%d->%d (dec)\n", (void *)def, rb_id2name(def->original_id), reference_count, def->reference_count); } + RB_VM_LOCK_LEAVE(); } } @@ -621,9 +623,11 @@ setup_method_cfunc_struct(rb_method_cfunc_t *cfunc, VALUE (*func)(ANYARGS), int static rb_method_definition_t * method_definition_addref(rb_method_definition_t *def, bool complemented) { + RB_VM_LOCK_ENTER(); if (!complemented && def->reference_count > 0) def->aliased = true; def->reference_count++; if (METHOD_DEBUG) fprintf(stderr, "+%p-%s:%d\n", (void *)def, rb_id2name(def->original_id), def->reference_count); + RB_VM_LOCK_LEAVE(); return def; } ``` But I don't think it is a good idea because the cost would be high. Hopefully there is a better solution. ---------------------------------------- Bug #20934: `UnboundMethod#bind_call` may cause "double free or corruption" with Ractor https://bugs.ruby-lang.org/issues/20934#change-110880 * Author: wanabe (_ wanabe) * Status: Open * ruby -v: ruby 3.4.0dev (2024-12-06T18:51:08Z :detached: 8ad6860ff7) +PRISM [x86_64-linux] * Backport: 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN ---------------------------------------- When I call `UnboundMethod#bind_call` on both main Ractor and child Ractor, probable errors can be encountered. Here is an issue reproduce script `ractor_issue.rb`. ``` def foo 10000.times do Object.instance_method(:object_id).bind_call(self) end end Ractor.new { foo } foo ``` And there are some examples of execution results. ``` $ ./miniruby -v ractor_issue.rb ruby 3.4.0dev (2024-12-06T18:51:08Z :detached: 8ad6860ff7) +PRISM [x86_64-linux] ractor_issue.rb:7: warning: Ractor is experimental, and the behavior may change in future versions of Ruby! Also there are many implementation issues. double free or corruption (fasttop) Aborted (core dumped) ``` ``` $ ./miniruby -v ractor_issue.rb ruby 3.4.0dev (2024-12-06T18:51:08Z :detached: 8ad6860ff7) +PRISM [x86_64-linux] ractor_issue.rb:7: warning: Ractor is experimental, and the behavior may change in future versions of Ruby! Also there are many implementation issues. # terminated with exception (report_on_exception is true): ractor_issue.rb:3:in 'UnboundMethod#bind_call': undefined method 'object_id' for main (NoMethodError) from ractor_issue.rb:3:in 'block in Object#foo' from :257:in 'Integer#times' from ractor_issue.rb:2:in 'Object#foo' from ractor_issue.rb:8:in '
' ``` Please try running it several times, as there is a probability of successful completion. -- https://bugs.ruby-lang.org/ ______________________________________________ ruby-core mailing list -- ruby-core@ml.ruby-lang.org To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/