rustwasm/wasm-bindgen

improve panic message when compiling to wasi

proohit opened this issue · 8 comments

Describe the Bug

wasm-bindgen cli is panicking when passed a wasm binary.

Steps to Reproduce

  1. Run cargo wasi build --release or cargo build --target=wasm32-wasi --release
  2. If cargo wasi was used, then the error occurs. If not, run wasm-bindgen target/wasm32-wasi/release/smartcore_wasi_lib.wasm --out-dir pkg
  3. see error

smartcore-wasi.zip

Expected Behavior

Expected wasm-bindgen to process WASM file and output bindings into pkg.

Actual Behavior

Panic at wasm-bindgen-wasm-interpreter/src/lib.rs:363 with following output:

$ RUST_BACKTRACE=full wasm-bindgen target/wasm32-wasi/release/smartcore_wasi_lib.wasm --out-dir pkg
thread 'main' panicked at 'unknown instruction LocalTee(LocalTee { local: Id { idx: 707 } })', /home/direnc/.cargo/registry/src/github.com-1ecc6299db9ec823/wasm-bindgen-wasm-interpreter-0.2.74/src/lib.rs:363:18
stack backtrace:
   0:     0x558b1b135460 - std::backtrace_rs::backtrace::libunwind::trace::h25e12e0d899beba0
                               at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/std/src/../../backtrace/src/backtrace/libunwind.rs:90:5
   1:     0x558b1b135460 - std::backtrace_rs::backtrace::trace_unsynchronized::h70e61195d6ae3df6
                               at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/std/src/../../backtrace/src/backtrace/mod.rs:66:5
   2:     0x558b1b135460 - std::sys_common::backtrace::_print_fmt::hba93ab80d779695a
                               at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/std/src/sys_common/backtrace.rs:67:5
   3:     0x558b1b135460 - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::hf092b5883b4b2e50
                               at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/std/src/sys_common/backtrace.rs:46:22
   4:     0x558b1b1555ac - core::fmt::write::hf68bc350a8f2f0dc
                               at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/core/src/fmt/mod.rs:1078:17
   5:     0x558b1b131fa2 - std::io::Write::write_fmt::hf66811b1bc767436
                               at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/std/src/io/mod.rs:1517:15
   6:     0x558b1b137495 - std::sys_common::backtrace::_print::hd425a11bfe1f20f8
                               at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/std/src/sys_common/backtrace.rs:49:5
   7:     0x558b1b137495 - std::sys_common::backtrace::print::h6d678795c1e61e13
                               at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/std/src/sys_common/backtrace.rs:36:9
   8:     0x558b1b137495 - std::panicking::default_hook::{{closure}}::h78a02a4a0dee5e7e
                               at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/std/src/panicking.rs:208:50
   9:     0x558b1b136fea - std::panicking::default_hook::h56eb7eda02f355a7
                               at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/std/src/panicking.rs:225:9
  10:     0x558b1b137c31 - std::panicking::rust_panic_with_hook::hb27ea14285131c61
                               at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/std/src/panicking.rs:591:17
  11:     0x558b1b137777 - std::panicking::begin_panic_handler::{{closure}}::hc552fcee62aad17f
                               at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/std/src/panicking.rs:497:13
  12:     0x558b1b13591c - std::sys_common::backtrace::__rust_end_short_backtrace::hb9f0aa9a78e885a0
                               at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/std/src/sys_common/backtrace.rs:141:18
  13:     0x558b1b1376d9 - rust_begin_unwind
                               at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/std/src/panicking.rs:493:5
  14:     0x558b1b13768b - std::panicking::begin_panic_fmt::h1b56a0ef7fd4e8be
                               at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/std/src/panicking.rs:435:5
  15:     0x558b1afc8469 - wasm_bindgen_wasm_interpreter::Interpreter::call::hf288d862b49b4cb2
  16:     0x558b1afc821d - wasm_bindgen_wasm_interpreter::Interpreter::call::hf288d862b49b4cb2
  17:     0x558b1afc821d - wasm_bindgen_wasm_interpreter::Interpreter::call::hf288d862b49b4cb2
  18:     0x558b1afc821d - wasm_bindgen_wasm_interpreter::Interpreter::call::hf288d862b49b4cb2
  19:     0x558b1afc76ed - wasm_bindgen_wasm_interpreter::Interpreter::interpret_descriptor::hf5ad99a2145dbbf1
  20:     0x558b1ae8dd47 - wasm_bindgen_cli_support::descriptors::execute::h6fbf32d04313d008
  21:     0x558b1ae4b243 - wasm_bindgen_cli_support::Bindgen::generate_output::h14e956345173d1e3
  22:     0x558b1ae33fd0 - wasm_bindgen_cli_support::Bindgen::generate::h6809547547e36f6a
  23:     0x558b1ae373ed - wasm_bindgen::main::hee5e827d0edbc295
  24:     0x558b1ae35503 - std::sys_common::backtrace::__rust_begin_short_backtrace::h9cfcdf9ad5f819c8
  25:     0x558b1ae35519 - std::rt::lang_start::{{closure}}::h38bd124e7b579a70
  26:     0x558b1b138147 - core::ops::function::impls::<impl core::ops::function::FnOnce<A> for &F>::call_once::h78040f802d89ccdc
                               at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/core/src/ops/function.rs:259:13
  27:     0x558b1b138147 - std::panicking::try::do_call::h6853cad536dd09a1
                               at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/std/src/panicking.rs:379:40
  28:     0x558b1b138147 - std::panicking::try::h827495f03a9fbb9a
                               at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/std/src/panicking.rs:343:19
  29:     0x558b1b138147 - std::panic::catch_unwind::h4bdf17571090eb17
                               at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/std/src/panic.rs:396:14
  30:     0x558b1b138147 - std::rt::lang_start_internal::h2f319c33bb013f29
                               at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/std/src/rt.rs:51:25
  31:     0x558b1ae37872 - main
  32:     0x7ff2b3e810b3 - __libc_start_main
  33:     0x558b1ae330ae - _start
  34:                0x0 - <unknown>

Additional Context

I've tried it with several versions of wasm-bindgen, going from 0.74.0 down to 0.54.0. Using rustc 1.54.0.

Thanks for the report! The issue here, though, is that the wasm32-wasi target is not compatible with wasm-bindgen. The error message isn't great but it's probably not what you're going to want.

I'll leave this open though to improve the error message.

Thanks for your quick response!

My intention is to use the wasm binary server-side and since wasm-bindgen also handles other proposals like reference types, it was my go-to tool. Is a target, not web specific, planned for this tool?

And while I have a wasm guru here, maybe you can help me with my problem. :P My main problem are type bindings such as str from other runtimes (wasmtime-py, wasmer, node-wasi...). Do you have other leads to take on in order to solve this problem?

Ah yes this is definitely a problem, and you're not the first to run into it! The interface types proposal for WebAssembly is intended to be the basis of the solution here for interop between languages and wasm, but it's unfortunately still under development at this time.

Alright got it. Thanks for your efforts!

I've read about interface types but unfortunately runtimes may or may not implement them, or remove them at some point. Guess it's highly experimental.

dxps commented

While I'm evaluating wasmtime and wasmtime-go, I also got into this issue while just following the simple example officially described in WebAssembly Interface Types.

@alexcrichton Any help, please?

Thank you

UPDATE 1:
Actually, I see that's also officially stated that it shouldn't work anymore, according to this issue. Sorry for the noise ... 😵‍💫

UPDATE 2:
It all started while trying to use wasmtime-go with a simple .wasm file.
Thus, following Writing Libraries section, I get a WASM file that strangely enough - ok, maybe not - it has 4 imports,
confirmed also by wasm2wat demo:

  (import "wasi_snapshot_preview1" "fd_write" (func $wasi::lib_generated::wasi_snapshot_preview1::fd_write::h6a67043e9c1785e7 (type $t12)))
  (import "wasi_snapshot_preview1" "environ_get" (func $__imported_wasi_snapshot_preview1_environ_get (type $t6)))
  (import "wasi_snapshot_preview1" "environ_sizes_get" (func $__imported_wasi_snapshot_preview1_environ_sizes_get (type $t6)))
  (import "wasi_snapshot_preview1" "proc_exit" (func $__imported_wasi_snapshot_preview1_proc_exit (type $t2)))

So, I'd have to adapt the following code (more precisely, the imports part) to eventually work:

	engine := wasmtime.NewEngine()
	store := wasmtime.NewStore(engine)
	module, err := wasmtime.NewModuleFromFile(store.Engine, "wasm_rust_hello.wasm")

        imports := make([]wasmtime.AsExtern, 4)
	instance, err := wasmtime.NewInstance(store, module, imports)

while currently it actually get a seg fault:

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x18 pc=0x66ca44]

goroutine 1 [running]:
github.com/bytecodealliance/wasmtime-go.NewInstance({0x10559d0?, 0xc000098210}, 0xc0000b2028, {0xc00005af30, 0x4, 0x4})
	/home/dxps/go/pkg/mod/github.com/bytecodealliance/wasmtime-go@v0.35.0/instance.go:27 +0x204
main.main()
	/home/dxps/dev/dxps-gh/go_playground/test-wasmtime-go/hello-2/main.go:28 +0x16f
exit status 2

@dxps

Note that there are actually two issues here:

  1. wasm-bindgen isn't compatible with WASI (actual issue report). Wasm-bindgen would generate some data type bindings specific for js (e.g. strings). Those abstractions cannot be done in a standardized way without Interface types, thus no general platform independent support.
  2. However wasmtime dropped support for Interface types and may add them later when the proposal is finished.
dxps commented

@proohit Thanks for the feedback! You're absolutely right.
Meanwhile, I got deeper into this space to understand the concepts and the ecosystem around it.

I have the same problem and it would help a lot speed-wise if I can directly call wasi-compatible crates from my rust-web-frontend. Another solution would be to create two separate modules, one using wasm-bindgen and one wasm32-wasi and interfacing them through javascript. (Using https://www.wasmtutor.com/webassembly-barebones-wasi, I was able to load a wasi wasm into browser.) But I feel the two-modules approach would slow the application down a lot, as I need to do very frequent calls to the wasi one.

Using wasm2wat I see that the generated from cargo build --target=wasm32-wasi --release wasm, has the wasm-bindgen along with the wasi_snapshot_preview1 imports. Has anyone tried gluing them together somehow?

EDIT: Solution: I managed to do this with wasmer-js