Stream: git-wasmtime

Topic: wasmtime / issue #10740 Regression for custom LinearMemor...


view this post on Zulip Wasmtime GitHub notifications bot (May 07 2025 at 10:14):

V0ldek opened issue #10740:

Hello.

I've been using wasmtime with a custom memory implementation that is backed by my custom managed virtual mmap. I don't think the implementation details of my custom struct matter. I've been on wasmtime 25.0 and everything worked fine. After an update to wasmtime 32.0 I had to rewrite the wasmtime::LinearMemory impl, but it just got simplified. However, running my code now gets me this panic:

<details>
<summary>Stacktrace</summary>

thread 'main' panicked at /home/mat/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/wasmtime-32.0.0/src/runtime/vm/memory.rs:536:29:
internal error: entered unreachable code: memory_image is Some only for mmap-based memories
stack backtrace:
   0: __rustc::rust_begin_unwind
             at /rustc/a15cce2690e8fab72422515c9dc02c6fbc506733/library/std/src/panicking.rs:697:5
   1: core::panicking::panic_fmt
             at /rustc/a15cce2690e8fab72422515c9dc02c6fbc506733/library/core/src/panicking.rs:75:14
   2: wasmtime::runtime::vm::memory::LocalMemory::new
             at /home/mat/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/wasmtime-32.0.0/src/runtime/vm/memory.rs:536:29
   3: wasmtime::runtime::vm::memory::Memory::new_dynamic
             at /home/mat/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/wasmtime-32.0.0/src/runtime/vm/memory.rs:240:22
   4: <wasmtime::runtime::vm::instance::allocator::on_demand::OnDemandInstanceAllocator as wasmtime::runtime::vm::instance::allocator::InstanceAllocatorImpl>::allocate_memory
             at /home/mat/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/wasmtime-32.0.0/src/runtime/vm/instance/allocator/on_demand.rs:119:22
   5: wasmtime::runtime::vm::instance::allocator::InstanceAllocator::allocate_memories
             at /home/mat/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/wasmtime-32.0.0/src/runtime/vm/instance/allocator.rs:463:27
   6: wasmtime::runtime::vm::instance::allocator::InstanceAllocator::allocate_module::{{closure}}
             at /home/mat/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/wasmtime-32.0.0/src/runtime/vm/instance/allocator.rs:406:13
   7: wasmtime::runtime::vm::instance::allocator::InstanceAllocator::allocate_module
             at /home/mat/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/wasmtime-32.0.0/src/runtime/vm/instance/allocator.rs:405:15
   8: wasmtime::runtime::instance::Instance::new_raw
             at /home/mat/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/wasmtime-32.0.0/src/runtime/instance.rs:285:13
   9: wasmtime::runtime::instance::Instance::new_started_impl
             at /home/mat/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/wasmtime-32.0.0/src/runtime/instance.rs:207:33
  10: wasmtime::runtime::instance::Instance::new_started
             at /home/mat/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/wasmtime-32.0.0/src/runtime/instance.rs:195:9
  11: wasmtime::runtime::instance::InstancePre<T>::instantiate
             at /home/mat/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/wasmtime-32.0.0/src/runtime/instance.rs:904:18
  12: wasmtime::runtime::linker::Linker<T>::instantiate
             at /home/mat/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/wasmtime-32.0.0/src/runtime/linker.rs:1097:9
  13: anyblox::programs::wasm::WasmProgram::prepare::{{closure}}
             at ./anyblox/src/programs/wasm.rs:125:60
...

</details>

where the prepare function at the bottom is the one that instantiates a module with:

linker.instantiate(&mut store, &self.module)

I see how this gets caused under the hood, namely the LinearMemoryProxy always creates a Raw memory from a pointer and the LocalMemory::new function then enters the unreachable branch, but I don't understand if this is intentional or an overlook during the refactoring between versions 25 and 32.

I'd be interested on why this behaviour changed and if it's possible to restore the ability to use mem images with custom memory implementations. My custom linear memory is backed by an mmap as well, so there should not be any fundamental issues preventing it.

view this post on Zulip Wasmtime GitHub notifications bot (May 07 2025 at 14:45):

alexcrichton edited issue #10740:

Hello.

I've been using wasmtime with a custom memory implementation that is backed by my custom managed virtual mmap. I don't think the implementation details of my custom struct matter. I've been on wasmtime 25.0 and everything worked fine. After an update to wasmtime 32.0 I had to rewrite the wasmtime::LinearMemory impl, but it just got simplified. However, running my code now gets me this panic:

<details>
<summary>Stacktrace</summary>

thread 'main' panicked at /home/mat/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/wasmtime-32.0.0/src/runtime/vm/memory.rs:536:29:
internal error: entered unreachable code: memory_image is Some only for mmap-based memories
stack backtrace:
   0: __rustc::rust_begin_unwind
             at /rustc/a15cce2690e8fab72422515c9dc02c6fbc506733/library/std/src/panicking.rs:697:5
   1: core::panicking::panic_fmt
             at /rustc/a15cce2690e8fab72422515c9dc02c6fbc506733/library/core/src/panicking.rs:75:14
   2: wasmtime::runtime::vm::memory::LocalMemory::new
             at /home/mat/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/wasmtime-32.0.0/src/runtime/vm/memory.rs:536:29
   3: wasmtime::runtime::vm::memory::Memory::new_dynamic
             at /home/mat/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/wasmtime-32.0.0/src/runtime/vm/memory.rs:240:22
   4: <wasmtime::runtime::vm::instance::allocator::on_demand::OnDemandInstanceAllocator as wasmtime::runtime::vm::instance::allocator::InstanceAllocatorImpl>::allocate_memory
             at /home/mat/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/wasmtime-32.0.0/src/runtime/vm/instance/allocator/on_demand.rs:119:22
   5: wasmtime::runtime::vm::instance::allocator::InstanceAllocator::allocate_memories
             at /home/mat/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/wasmtime-32.0.0/src/runtime/vm/instance/allocator.rs:463:27
   6: wasmtime::runtime::vm::instance::allocator::InstanceAllocator::allocate_module::{{closure}}
             at /home/mat/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/wasmtime-32.0.0/src/runtime/vm/instance/allocator.rs:406:13
   7: wasmtime::runtime::vm::instance::allocator::InstanceAllocator::allocate_module
             at /home/mat/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/wasmtime-32.0.0/src/runtime/vm/instance/allocator.rs:405:15
   8: wasmtime::runtime::instance::Instance::new_raw
             at /home/mat/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/wasmtime-32.0.0/src/runtime/instance.rs:285:13
   9: wasmtime::runtime::instance::Instance::new_started_impl
             at /home/mat/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/wasmtime-32.0.0/src/runtime/instance.rs:207:33
  10: wasmtime::runtime::instance::Instance::new_started
             at /home/mat/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/wasmtime-32.0.0/src/runtime/instance.rs:195:9
  11: wasmtime::runtime::instance::InstancePre<T>::instantiate
             at /home/mat/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/wasmtime-32.0.0/src/runtime/instance.rs:904:18
  12: wasmtime::runtime::linker::Linker<T>::instantiate
             at /home/mat/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/wasmtime-32.0.0/src/runtime/linker.rs:1097:9
  13: anyblox::programs::wasm::WasmProgram::prepare::{{closure}}
             at ./anyblox/src/programs/wasm.rs:125:60
...

</details>

where the prepare function at the bottom is the one that instantiates a module with:

linker.instantiate(&mut store, &self.module)

I see how this gets caused under the hood, namely the LinearMemoryProxy always creates a Raw memory from a pointer and the LocalMemory::new function then enters the unreachable branch, but I don't understand if this is intentional or an overlook during the refactoring between versions 25 and 32.

I'd be interested on why this behaviour changed and if it's possible to restore the ability to use mem images with custom memory implementations. My custom linear memory is backed by an mmap as well, so there should not be any fundamental issues preventing it.

view this post on Zulip Wasmtime GitHub notifications bot (May 07 2025 at 14:49):

alexcrichton commented on issue #10740:

Thanks for the report, and seems reasonable to fix! I got about halfway through removing/resolving the differences between LinearMemory and RuntimeLinearMemory but never finished the work, and I think that would probably help here. Agreed we should fix this though, and if you're interested to work on it I'd be happy to help review a PR.

view this post on Zulip Wasmtime GitHub notifications bot (May 08 2025 at 09:59):

V0ldek commented on issue #10740:

What would you see as a good fix here?

I'm not sure what the invariants for the code in vm/memory.rs are, but if it needs to know if the memory is mmapped or not then I was thinking maybe instead of LinearMemory::as_ptr(&self) -> *mut u8 there should be LinearMemory::as_base(&self) -> MemoryBase that explicitly says if this is just any pointer or an mmap?

view this post on Zulip Wasmtime GitHub notifications bot (May 08 2025 at 15:47):

alexcrichton commented on issue #10740:

Unfortunately I don't think there's any fix for this right now without changing the APIs themselves. You're right though in that the fix will be somewhere around here. Personally I'd like to remove the need for LinearMemoryProxy and changing the raw runtime internals to "just" using LinearMemory, updating the signatures as necessary to morally match RuntimeLinearMemory. I'm not certain we'll want MemoryBase as an externally-facing abstraction, though.

view this post on Zulip Wasmtime GitHub notifications bot (May 22 2025 at 15:46):

V0ldek commented on issue #10740:

I currently don't have cycles to tackle this, but I wanted to note one more thing that would be good for ergonomics of custom memory:

I'd like to be able to access the specific Box<dyn LinearMemory> out of an Instance after it's instantiated. Currently it doesn't seem to be possible even in host functions that get a Caller.


Last updated: Dec 06 2025 at 06:05 UTC