Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Asyncify + Try-Catch [Can't build web-gphoto2 with -fwasm-exceptions instead of -fexceptions] #4470

Open
RReverser opened this issue Jan 21, 2022 · 8 comments

Comments

@RReverser
Copy link
Member

web-gphoto2 builds with pthreads, Asyncify, exceptions and LTO, and I'm not sure which combo is specifically problematic here, but the end result is that it crashes when trying to switch from -fexceptions to -fwasm-exceptions:

unexpected expression type
UNREACHABLE executed at /b/s/w/ir/cache/builder/emscripten-releases/binaryen/src/passes/Asyncify.cpp:998!
emcc: error: '/emsdk/upstream/bin/wasm-opt --strip-dwarf --post-emscripten -Os --low-memory-unused --asyncify [email protected]_*,env.__call_main,env.emscripten_sleep,env.emscripten_wget,env.emscripten_wget_data,env.emscripten_idb_load,env.emscripten_idb_store,env.emscripten_idb_delete,env.emscripten_idb_exists,env.emscripten_idb_load_blob,env.emscripten_idb_store_blob,env.SDL_Delay,env.emscripten_scan_registers,env.emscripten_lazy_load_code,env.emscripten_fiber_swap,wasi_snapshot_preview1.fd_sync,env.__wasi_fd_sync,env._emval_await,env._dlopen_js,env.__asyncjs__* --zero-filled-memory --strip-debug --strip-producers ui/libapi.wasm -o ui/libapi.wasm --mvp-features --enable-threads --enable-mutable-globals --enable-bulk-memory --enable-sign-ext --enable-exception-handling' failed (received SIGABRT (-6))

A branch that's failing can be checked out from here: https://github.com/GoogleChromeLabs/web-gphoto2/tree/fwasm-exceptions. It should be pretty reproducible as it uses Docker, so all you need to do is run ./build.sh in the checkout folder.

@RReverser
Copy link
Member Author

cc @kripken @aheejin

@kripken
Copy link
Member

kripken commented Jan 21, 2022

I think that is this:

// We must handle all control flow above, and all things that can change
// the state, so there should be nothing that can reach here - add it
// earlier as necessary.
// std::cout << *curr << '\n';
WASM_UNREACHABLE("unexpected expression type");

So the issue is supporting the Try control flow structure in that pass. It needs special handling for each one since it needs to be able to resume execution back into the middle.

For Try, the hard part would be to get back into the catch when rewinding... maybe we could construct and throw another exception just to get there? Or maybe we should move the code out of the catch, and guard it with a condition, so it can be reached either from the catch or from a resume, something like that.

@kripken kripken changed the title Can't build web-gphoto2 with -fwasm-exceptions instead of -fexceptions Support Asyncify + Try-Catch [Can't build web-gphoto2 with -fwasm-exceptions instead of -fexceptions] Jan 21, 2022
@allsey87
Copy link

allsey87 commented Apr 8, 2022

@RReverser did you find a work around (other than just sticking with -fexceptions) for this?

@allsey87
Copy link

allsey87 commented Apr 8, 2022

This code here seems sufficient enough to reproduce the problem:

#include <iostream>
#include <stdexcept>

__attribute__((import_module("env"), import_name("external_async_function")))
void external_async_function();

int main() {
    try {
        throw std::invalid_argument("test");
    }
    catch(const std::invalid_argument& e) {
        std::cout << "caught" << std::endl;    
    }
    std::cout << "before" << std::endl;
    external_async_function();
    std::cout << "after" << std::endl;
    return 0;
}

compiling with: em++ -fwasm-exceptions -s WARN_ON_UNDEFINED_SYMBOLS=0 -s ASYNCIFY -s 'ASYNCIFY_IMPORTS=["external_async_function"]' index.cpp -o index.html

  • wasm-opt version: 103 (version_103-24-g62d83d5fc)
  • emcc version: 3.0.1 (5ebe1d4)

@allsey87
Copy link

allsey87 commented Apr 8, 2022

Tested the same code with the latest versions (as follows) but I seem to hit the same error.

  • wasm-opt version: 106 (version_106-10-g22d24fda9)
  • emcc version: 3.1.8 (3ff7eff)

@kripken
Copy link
Member

kripken commented Apr 8, 2022

Yes, no work has been done on this so far. The work that would need to be done is mentioned in #4470 (comment)

@allsey87
Copy link

@RReverser this might be possible soon: #5475

@germandiagogomez
Copy link

@allsey87 fwiw I am porting a game of my own from desktop to wasm and I would like to use wasm exceptions but, so far, I will also need ASYNCIFY. So this support would be great.

aykevl added a commit to tinygo-org/tinygo that referenced this issue Aug 4, 2024
Add unwinding and recover support for wasm using WebAssembly exception
handling. This still has a few gotchas:

  * Many WASI systems don't support exception handling yet.
    For example, see:
    bytecodealliance/wasmtime#2049
  * Asyncify doesn't support wasm exception handling:
    WebAssembly/binaryen#4470
    This means it's not possible to use goroutines together with
    panic/recover.
  * The current way that exceptions are implemented pretend to be C++
    exceptions, but work slightly differently. If C++ code is called
    (for example through CGo) that raises an exception, that exception
    will be eaten by TinyGo and not be propagated. This is fixable, it
    just hasn't been implemented (because we don't actually support C++
    right now).

I hope that these issues will be resolved over time. At least for now,
people who need `recover()` have a way to use it.
aykevl added a commit to tinygo-org/tinygo that referenced this issue Aug 4, 2024
Add unwinding and recover support for wasm using WebAssembly exception
handling. This still has a few gotchas:

  * Many WASI systems don't support exception handling yet.
    For example, see:
    bytecodealliance/wasmtime#2049
  * Asyncify doesn't support wasm exception handling:
    WebAssembly/binaryen#4470
    This means it's not possible to use goroutines together with
    panic/recover.
  * The current way that exceptions are implemented pretend to be C++
    exceptions, but work slightly differently. If C++ code is called
    (for example through CGo) that raises an exception, that exception
    will be eaten by TinyGo and not be propagated. This is fixable, it
    just hasn't been implemented (because we don't actually support C++
    right now).

I hope that these issues will be resolved over time. At least for now,
people who need `recover()` have a way to use it.
aykevl added a commit to tinygo-org/tinygo that referenced this issue Aug 14, 2024
Add unwinding and recover support for wasm using WebAssembly exception
handling. This still has a few gotchas:

  * Many WASI systems don't support exception handling yet.
    For example, see:
    bytecodealliance/wasmtime#2049
  * Asyncify doesn't support wasm exception handling:
    WebAssembly/binaryen#4470
    This means it's not possible to use goroutines together with
    panic/recover.
  * The current way that exceptions are implemented pretend to be C++
    exceptions, but work slightly differently. If C++ code is called
    (for example through CGo) that raises an exception, that exception
    will be eaten by TinyGo and not be propagated. This is fixable, it
    just hasn't been implemented (because we don't actually support C++
    right now).

I hope that these issues will be resolved over time. At least for now,
people who need `recover()` have a way to use it.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants