Skip to content

Fix memory leaks in WASI setjmp handler #12995

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Mar 31, 2025

Conversation

white-axe
Copy link
Contributor

This pull request fixes two memory leaks in the implementation of setjmp in WASI (WebAssembly) builds of Ruby:

  • The first commit fixes a problem where the stack pointer is not reset after a longjmp, leading to leaking of parts of the stack. This also causes leaking of Ruby objects since the garbage collector looks for GC roots on the stack.
  • The second commit fixes a problem where the VM jump buffers are not freed after a longjmp. In WASI builds of Ruby, jump buffers are allocated on the heap instead of on the stack, so they need to be manually deallocated. I changed the implementations of rb_vm_tag_jmpbuf_init() and rb_vm_tag_jmpbuf_deinit() to clean up leaked jump buffers before initializing/deinitializing jump buffers.

@white-axe white-axe marked this pull request as draft March 27, 2025 05:20
@white-axe white-axe marked this pull request as ready for review March 27, 2025 06:05
@white-axe
Copy link
Contributor Author

@kateinoigakukun, since you maintain the WASI builds of Ruby, can you take a look at this?

@kateinoigakukun
Copy link
Member

Let me execute ruby.wasm test suite with this change: ruby/ruby.wasm#586

@white-axe
Copy link
Contributor Author

Here's a test to see if a WASI build is affected by these two memory leaks. This script causes all of the current WASI builds from https://github.com/ruby/ruby.wasm to rapidly consume around 800 mebibytes of memory due to the jump buffer leak and then crash from what I believe is stack buffer overflow caused by the stack pointer leak:

loop do
  array = [0]
  for item in array
    break
  end
end

To test it out, save it as test.rb in the current working directory, and then:

curl -Lo ruby.tar.gz https://github.com/ruby/ruby.wasm/releases/download/2.7.1/ruby-3.4-wasm32-unknown-wasip1-full.tar.gz
tar xzf ruby.tar.gz --strip-components=1
wasmtime --dir .::/ usr/local/bin/ruby test.rb

Copy link
Member

@kateinoigakukun kateinoigakukun left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really good catch, the patch looks good to me.

@kateinoigakukun kateinoigakukun merged commit 372515f into ruby:master Mar 31, 2025
76 checks passed
@white-axe white-axe deleted the wasi-leak branch March 31, 2025 15:54
white-axe added a commit to white-axe/mkxp-z that referenced this pull request Mar 31, 2025
@kateinoigakukun
Copy link
Member

kateinoigakukun commented Apr 1, 2025

Hi @white-axe, the change seems causing OOM on ruby.wasm test suite, so I'm reverting this for now #13026

@white-axe
Copy link
Contributor Author

I'll find some other way to fix the second memory leak then

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

2 participants