Hello all! For a little context, I'm trying to compile and run Ruby 3.2 as a component. I have a core module compiled of the Ruby runtime, which I then encode as a component using the command variant of the preview1 adapter.
Executing the component with Wasmtime throws the following error:
error while executing at wasm backtrace:
0: 0xf50b06 - wit-component:adapter:wasi_snapshot_preview1!wasi_snapshot_preview1::bindings::wasi::cli_base::exit::exit::hf14a756e1735c0fa
1: 0xf4ff1e - wit-component:adapter:wasi_snapshot_preview1!proc_exit
2: 0xf55660 - wit-component:shim!adapt-wasi_snapshot_preview1-proc_exit
3: 0x4aa733 - <unknown>!<wasm function 5297>
4: 0x5147 - <unknown>!<wasm function 39>
5: 0xf46400 - wit-component:adapter:wasi_snapshot_preview1!run
Grepping the Ruby component with wasm-tools print
looking for whatever function 39 is, I see these lines:
(func $adapt-wasi_snapshot_preview1-environ_get (;39;) (type 15) (param i32 i32) (result i32)
i32.const 39
(export "39" (func $adapt-wasi_snapshot_preview1-environ_get))
which I believe indicates that the crash stems from a call to environ_get
-- the Ruby runtime checks the value of env var RUBY_PLATFORM
, so it makes sense that the crash is happening early.
I'm using the Rust wasmtime
crate, pinned to GitHub rev a330867
. The component encoding uses the Rust wasm-tools
crate, pinned to GitHub rev 0263c2f
. I believe both of these revs are current with recent changes to the preview1 shim. The adapter module itself is compiled from latest wasmtime rev 80e68c3
.
I guess at the moment I'm trying to figure out if this is a bug in the preview1 adapter, or if I've maybe missed something on my end? Please let me know if I can provide more detail!
the Ruby runtime checks the value of env var RUBY_PLATFORM, so it makes sense that the crash is happening early
sorry I worded this strangely; I meant that the crash seemed to be happening early (before trying to run the script specified in the arguments) and the RUBY_PLATFORM check also happens early, so it tracks to me that the error would originate from environ_get
That looks like ruby itself might be calling exit from the stack trace. Is it possible to build ruby with debug info or symbols? Alternatively you can pass -p to print to get offsets to correlate
The <unknown> module in the backtrace is likely ruby and everything else looks like adapter or wit component stuff
@Alex Crichton I've just tried compiling ruby with -O0 -fno-fast-math -ggdb3
however I now get a cranelift panic when loading the module:
thread '<unnamed>' panicked at 'assertion failed: x < (1 << bits)', /home/xlem/.cargo/git/checkouts/wasmtime-41807828cb3a7a7e/a330867/cranelift/codegen/src/ir/dfg.rs:551:9
I will try matching up the offsets with wasm-print -p
on the release build shortly and report back!
oh dear! If you can share that module that'd be much appreicated to reproduce the cranelift issue
Sure no problem! The module I'm testing has another WIT component embedded which is specific to my project; would it be easier to debug with a "vanilla" build (i.e. just debug mode ruby encoded with the preview1 adapter)?
if you've got some binary blob that panics cranelift that's good enough to send over and we can dig in from there
ok great; blob attached (compressed as tar.gz). thanks for looking into this!
ok I'll try and minimize the panic, but for the runtime issue there's unfortunately no easy way to reproduce outside of an embedding right now due to no CLI support for components, so if you're able to keep pushing on that it'd be appreciated
for sure! I'll be working on this some more later this afternoon, I'll let you know where I end up with it
First look at this is that there's probably a giant function in rubyfn.wasm
which should give a better error, but it's blowing a limit in cranelift which leads to a panic as opposed to a first-class error
oof there are some big functions in here, taking upwards of 10s to compile
ok looks like this is definitely a case of "that function is too big". If you pass --opt-level 0
to wasmtime compile
the panic goes away, but cranelift fails with Error: Compilation error: Code for function is too large
when it runs out of virtual registers during register allocation for one of the functions. My guess is that -ggdb3
deoptimized a bit too much and the function is just way too big.
You could try passing -O1
to the C compiler to get at least symbols, or perhaps -gline-tables-only
(I forget what that option is actually called, -g1
?) to generate less debuginfo which may deoptimize less
hmm so passing -O1
and -g1
compiles, but doesn't provide any extra info in the stack trace of the crash. I'll keep playing with it
I think I remember there's a common issue of the names section getting stripped out by the toolchain. Maybe it was that clang invokes wasm-opt by default if that's installed?
A-ha! yes you're right. After passing -O1 -g
to wasm-opt I get useful debugging symbols (the Ruby build uses a dummy wasm-opt at first, then calls wasm-opt itself with specified args).
This revealed that it is indeed Ruby itself calling proc_exit. I was thinking it was weird that no errors were logged prior to the exit, and in a case of "changing too many things at once", I realized that this particular code path didn't attach stderr
to the module ... enabling that I found that I'd built Ruby without a required built-in gem.
Now it executes fine! Or at least without error. It never seems to run my script, but that is likely another application-level issue on my part so I'll mark this as resolved.
tyvm @Alex Crichton and @Jamey Sharp !!
Dan has marked this topic as resolved.
Last updated: Dec 23 2024 at 14:03 UTC