Skip to content

Exceptions thrown and caught within WebAssembly make Envoy drop the connection #80

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

Open
robertpanzer opened this issue Dec 9, 2020 · 5 comments

Comments

@robertpanzer
Copy link

When the code inside a wasm module throws an exception, and catches it within the same execution so that it does not cross the boundary between wasm and Envoy it drops the connection without a response.

I have created a reproducer for Istio Proxy 1.8.1 at https://github.com/robertpanzer/wasm-extensions
The README explains how to test it.

Expected behavior:
A wasm module should be able to throw and catch exceptions within Context::onRequestHeaders as long as onRequestHeaders does not return exceptionally.

Observed behavior:
When a method throws an exception that is transitively called by onRequestHeaders, and the exception is caught by some other method in that call stack, Envoy drops the downstream connnection without providing any response.

@kyessenov
Copy link
Collaborator

kyessenov commented Dec 9, 2020 via email

@kyessenov
Copy link
Collaborator

kyessenov commented Dec 9, 2020 via email

@robertpanzer
Copy link
Author

The project is simply generated from this document: https://github.com/istio-ecosystem/wasm-extensions/blob/master/doc/write-a-wasm-extension-with-cpp.md

I just read up a bit on relooper, I don't fully understand though how it would help with exception handling?
It seems to process a CFG, that is it should work on a single function.
So would that still work for a construct where exceptions are thrown between multiple larger building blocks, like from an AntLR parser to the plugin?

@PiotrSikora
Copy link
Member

@kyessenov while this is true that exceptions should be avoided in new code targeting Wasm (or all code, depending on your preferences), sometimes you need to use existing C/C++ libraries that require them.

In any case, I've spent some time digging into this today, and I might have misrepresented the state of support for C++ exceptions a bit in our last meeting.

Emscripten supports C++ exceptions perfectly fine using -s DISABLE_EXCEPTION_CATCHING=0. We don't currently expose this in the SDK (cc @bianpengyuan), but you can add it to toolchain/emcc.sh in the C++ SDK and use --override_repository to test it for the time being.

However, using Wasm modules built this way requires non-trivial support from the host implementation (i.e. Envoy), which is completely missing right now. I filed an issue (proxy-wasm/proxy-wasm-cpp-host#116) to add support for it, but I don't have any ETA right now.

@kyessenov
Copy link
Collaborator

I just read up a bit on relooper, I don't fully understand though how it would help with exception handling?
It seems to process a CFG, that is it should work on a single function.
So would that still work for a construct where exceptions are thrown between multiple larger building blocks, like from an AntLR parser to the plugin?

Emscripten uses Relooper under the hood (in fact, it's the main technical difficulty) for all non-local jumps (switch fallthrough, goto's). It should work for most code with exceptions. The main problem is it creates a lot more code and variables, which has a performance cost, some of it is gained back with compiler optimizations. But it's hard to say how much overhead it adds without measuring it. The perf overhead of exceptions is something that is hard to fix without Wasm changing itself.

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

No branches or pull requests

3 participants