Fix memory leak in cont_restore_thread in Ruby in libretro builds

This commit is contained in:
刘皓 2025-04-21 11:16:21 -04:00
parent 75946ab6a5
commit 46bd055c0a
No known key found for this signature in database
GPG key ID: 7901753DB465B711

View file

@ -1,5 +1,59 @@
# Fixes a memory leak in WASI builds of Ruby where VM jump buffers are sometimes not freed. # Fixes a memory leak in WASI builds of Ruby where VM jump buffers are sometimes not freed.
--- a/cont.c
+++ b/cont.c
@@ -1518,6 +1518,51 @@ cont_restore_thread(rb_context_t *cont)
rb_raise(rb_eRuntimeError, "can't call across trace_func");
}
+#if defined(__wasm__) && !defined(__EMSCRIPTEN__)
+ if (th->ec->tag != sec->tag) {
+ /* find the lowest common ancestor tag of the current EC and the saved EC */
+
+ struct rb_vm_tag *lowest_common_ancestor = NULL;
+ size_t num_tags = 0;
+ size_t num_saved_tags = 0;
+ for (struct rb_vm_tag *tag = th->ec->tag; tag != NULL; tag = tag->prev) {
+ ++num_tags;
+ }
+ for (struct rb_vm_tag *tag = sec->tag; tag != NULL; tag = tag->prev) {
+ ++num_saved_tags;
+ }
+
+ size_t min_tags = num_tags <= num_saved_tags ? num_tags : num_saved_tags;
+
+ struct rb_vm_tag *tag = th->ec->tag;
+ while (num_tags > min_tags) {
+ tag = tag->prev;
+ --num_tags;
+ }
+
+ struct rb_vm_tag *saved_tag = sec->tag;
+ while (num_saved_tags > min_tags) {
+ saved_tag = saved_tag->prev;
+ --num_saved_tags;
+ }
+
+ while (min_tags > 0) {
+ if (tag == saved_tag) {
+ lowest_common_ancestor = tag;
+ break;
+ }
+ tag = tag->prev;
+ saved_tag = saved_tag->prev;
+ --min_tags;
+ }
+
+ /* free all the jump buffers between the current EC's tag and the lowest common ancestor tag */
+ for (struct rb_vm_tag *tag = th->ec->tag; tag != lowest_common_ancestor; tag = tag->prev) {
+ rb_vm_tag_jmpbuf_deinit(&tag->buf);
+ }
+ }
+#endif
+
/* copy vm stack */
#ifdef CAPTURE_JUST_VALID_VM_STACK
MEMCPY(th->ec->vm_stack,
--- a/signal.c --- a/signal.c
+++ b/signal.c +++ b/signal.c
@@ -849,6 +849,7 @@ check_stack_overflow(int sig, const uintptr_t addr, const ucontext_t *ctx) @@ -849,6 +849,7 @@ check_stack_overflow(int sig, const uintptr_t addr, const ucontext_t *ctx)