Is there a way to enable RUST_BACKTRACE in wasm32-unknown-unknown builds?

Wasm normally doesn't have a concept of an "environment" so wasm32-unknown-unknown target just returns None in getenv. Relevant code:

So RUST_BACKTRACE is never enabled in wasm32-unknown-unknown builds.

I'm wondering if there's another way of enabling backtraces. Is this possible? I asked this many times in different places before and the answer was always "no", but I'm wondering if anything changed.

If the answer is still "no" then there's no way to enable Rust backtraces in wasm32-unknown-unknown builds, which is unfortunate. Does anyone know any workarounds for this? Or any hacks? I searched for open issues in Rust GH page but couldn't find anything relevant.

Thanks.

WASM code doesn't have access to it's stack. If you are panicking, you should see an exception with a backtrace on the console that includes all javascript and WASM frames on the stack. If not, you will need to call into a javascript function that gets the backtrace using new Error().

I'm not talking about Wasm stack, I'm talking about Rust stack. Rust compiled to WASI or emscripten can already dump backtraces when run with RUST_BACKTRACE=1 wasmtime .... I need something like that, but for wasm32-unknown-unknown target.

Here's an example:

$ cat src/main.rs
fn main() {
    panic!()
}

$ cargo build --target=wasm32-wasi
   Compiling wasm_backtrace v0.1.0 (/home/omer/rust/wasm_backtrace)
    Finished dev [unoptimized + debuginfo] target(s) in 0.34s

$ wasmtime target/wasm32-wasi/debug/wasm_backtrace.wasm
thread 'main' panicked at 'explicit panic', src/main.rs:2:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Error: failed to run main module `target/wasm32-wasi/debug/wasm_backtrace.wasm`

Caused by:
    0: failed to invoke command default
    1: wasm trap: unreachable
       wasm backtrace:
         0: 0x6c1c - <unknown>!__rust_start_panic
         1: 0x68c7 - <unknown>!rust_panic
         2: 0x65a1 - <unknown>!std::panicking::rust_panic_with_hook::h2345fb0909b53e12
         3: 0x10c3 - <unknown>!std::panicking::begin_panic::{{closure}}::h86678b4e45fbd7fa
         4: 0x1cc8 - <unknown>!std::sys_common::backtrace::__rust_end_short_backtrace::h8c7fe73fc6112e0e
         5:  0xfb1 - <unknown>!std::panicking::begin_panic::h5a83b3bb18195122
         6: 0x1fd5 - <unknown>!wasm_backtrace::main::h9fc5985544d26b7b
         7: 0x1bea - <unknown>!core::ops::function::FnOnce::call_once::hfd088d5879747b81
         8: 0x1cff - <unknown>!std::sys_common::backtrace::__rust_begin_short_backtrace::h2d7439e32125816a
         9:  0x4a1 - <unknown>!std::rt::lang_start::{{closure}}::hc9be9987846fa67a
         10: 0x69d8 - <unknown>!std::rt::lang_start_internal::h260050c92cd470af
         11:  0x453 - <unknown>!std::rt::lang_start::hd15e4b73e676a12b
         12: 0x1ff3 - <unknown>!__original_main
         13:  0x393 - <unknown>!_start

$ RUST_BACKTRACE=1 wasmtime target/wasm32-wasi/debug/wasm_backtrace.wasm
thread 'main' panicked at 'explicit panic', src/main.rs:2:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Error: failed to run main module `target/wasm32-wasi/debug/wasm_backtrace.wasm`

Caused by:
    0: failed to invoke command default
    1: wasm trap: unreachable
       wasm backtrace:
         0: 0x6c1c - <unknown>!__rust_start_panic
         1: 0x68c7 - <unknown>!rust_panic
         2: 0x65a1 - <unknown>!std::panicking::rust_panic_with_hook::h2345fb0909b53e12
         3: 0x10c3 - <unknown>!std::panicking::begin_panic::{{closure}}::h86678b4e45fbd7fa
         4: 0x1cc8 - <unknown>!std::sys_common::backtrace::__rust_end_short_backtrace::h8c7fe73fc6112e0e
         5:  0xfb1 - <unknown>!std::panicking::begin_panic::h5a83b3bb18195122
         6: 0x1fd5 - <unknown>!wasm_backtrace::main::h9fc5985544d26b7b
         7: 0x1bea - <unknown>!core::ops::function::FnOnce::call_once::hfd088d5879747b81
         8: 0x1cff - <unknown>!std::sys_common::backtrace::__rust_begin_short_backtrace::h2d7439e32125816a
         9:  0x4a1 - <unknown>!std::rt::lang_start::{{closure}}::hc9be9987846fa67a
         10: 0x69d8 - <unknown>!std::rt::lang_start_internal::h260050c92cd470af
         11:  0x453 - <unknown>!std::rt::lang_start::hd15e4b73e676a12b
         12: 0x1ff3 - <unknown>!__original_main
         13:  0x393 - <unknown>!_start


Stack backtrace:
   0: wasmtime::func::Func::call
   1: wasmtime_cli::commands::run::RunCommand::invoke_func
   2: wasmtime_cli::commands::run::RunCommand::execute
   3: wasmtime::main
   4: std::rt::lang_start::{{closure}}
   5: std::rt::lang_start_internal::{{closure}}
             at src/libstd/rt.rs:52
      std::panicking::try::do_call
             at src/libstd/panicking.rs:348
      std::panicking::try
             at src/libstd/panicking.rs:325
      std::panic::catch_unwind
             at src/libstd/panic.rs:394
      std::rt::lang_start_internal
             at src/libstd/rt.rs:51
   6: main
   7: __libc_start_main
   8: _start

Hmm, maybe I'm confused. In the two stack traces shown above, the first one is Rust stack trace. The second one is wasmtime. So Rust backtrace is dumped even without RUST_BACKTRACE=1. I'm guessing that means it's not Rust runtime/core/std that prints the backtrace, but wasmtime.

Also, without WASI a Wasm program can't print anything, so it doesn't make sense to expect a backtrace to be printed in wasm32-unknown-unknown program.

Closing.

In the wasmtime example it is wasmtime itself that prints the wasm stack when an unreachable wasm trap occurs. Because the rust code is compiled to wasm, this is also the rust stack. When running in the browser, it would be the browser that attaches the combined wasm+javascript stack to the exception thrown when the wasm trap occurs.