Stream: wasmtime

Topic: How to deal with "GC heap out of memory" errors?


view this post on Zulip Alex (Nov 18 2024 at 13:43):

I'm experimenting with Kotlin as a Wasm guest. It requires Wasm GC proposal to be implemented by the runtime. The only version that works currently is the prerelease one so I apologize if this is an issue related to the code that is WIP.

I'm embedding Wasmtime in Go (I've updated Wasmtime version in wasmtime-go manually) and running a benchmark that calls a simple guest function multiple times:

@OptIn(UnsafeWasmMemoryApi::class)
@WasmExport("test")
fun memSimple4IntsVoid(callId: ULong, dataSize: Int) {
    withScopedMemoryAllocator { allocator ->
            val ptr = allocator.allocate(dataSize)
            val result = requestHostToStoreArguments(callId, ptr.address)
           // ... error handling

            val x = ptr.loadInt()
            println("Received $x")
        }
}

After several successful calls of this function from the host, GC heap out of memory error happens which I assume is a Wasmtime error. Kotlin's withScopedMemoryAllocator is supposed to free all the memory allocated, instance.GetExport(store, "memory").Memory().Size(store) shows that at the time when the error happens there is still just 1 page allocated so memory doesn't grow during the test.

Memory section of the guest looks like this:

Memory[1]:
 - memory[0] pages: initial=1

Max memory is not limited in the module, nor do I use Wasmtime Limitter.

I'm not sure where exactly the error happens, I've attempted to catch(e: Throwable) in the guest and print it to stdout but it doesn't catch anything.

Is this a Kotlin issue, Wasmtime issue or this is some sort of bug/misconfiguration on my side? Thank you!

view this post on Zulip Alex (Nov 18 2024 at 16:00):

Ok, I see now that Wasm GC memory is supposed to be separate from linear memory according to the proposal. Is its size configurable?

view this post on Zulip Lann Martin (Nov 18 2024 at 16:05):

You might have to wait for @fitzgen (he/him) to get back from vacation to get much help on GC; there aren't many of us that understand Wasmtime GC yet as (afaik) it is still a work in progress.

view this post on Zulip Alex Crichton (Nov 18 2024 at 16:26):

Yes wasm gc memory is separate from linear memory. What'll need to happen here is either:

What you're running into is most likely an instance of the first here where a GC should be performed but it's not being performed automatically. (Nick would know more). The second point here isn't currently possible from Go I believe as the GC operation isn't exposed in the C API which is what wasmtime-go builds on.

view this post on Zulip Alex (Nov 18 2024 at 17:19):

Ok, got it, thank you!

view this post on Zulip Zalim Bashorov (Kotlin_, JetBrains) (Nov 19 2024 at 20:12):

GC heap out of memory

Looks like an issue on wasmtime side -- it seems like you are out of heap (GCed) memory.

Kotlin's withScopedMemoryAllocator uses Wasm linear memory, which is separate from the GC heap in terms of wasm.

I've attempted to catch(e: Throwable) in the guest and print it to stdout but it doesn't catch anything.

It's not an error from Kotlin, so you can't catch it.
Additionally, wasmtime doesn't support Exception Handling proposal yet, which is used for exceptions in Kotlin, so if you try to throw an exception from Kotlin code you will get a trap at that point at runtime, which basically means that execution of wasm module will be stopped.

view this post on Zulip Alex (Nov 20 2024 at 12:55):

Thanks, I'll retest when Wasm GC is officially released in Wasmtime.


Last updated: Nov 22 2024 at 16:03 UTC