capi.md: document that dfree handlers must not re-enter the VM

The `dfree` callback registered via `mrb_data_type.dfree` runs from
inside GC sweep, so allocating Ruby objects, calling `mrb_funcall` /
`mrb_yield`, raising exceptions, or otherwise re-entering the VM
can trigger a recursive GC that revisits the same object and causes
double-free (see #6316). Make the rule explicit in the "Wrapping C
Structures" section.

close #6316

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Yukihiro "Matz" Matsumoto
2026-05-11 14:39:01 +09:00
parent 3fc7dd1858
commit 322642364a
+7
View File
@@ -381,6 +381,13 @@ mrb_define_method(mrb, point, "initialize", point_init, MRB_ARGS_REQ(2));
mrb_define_method(mrb, point, "x", point_x, MRB_ARGS_NONE());
```
**Do not call into mruby from a `dfree` handler.** The handler runs
from inside GC sweep; allocating Ruby objects, calling
`mrb_funcall`, `mrb_yield`, raising exceptions, or otherwise
re-entering the VM can trigger a recursive GC that revisits the
same object and causes double-free. Keep `dfree` to `mrb_free` /
plain C cleanup of the wrapped data only.
## Exception Handling
### Raising Exceptions