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 for exceptions .. Disabling emscripten-cxx-exceptions #140

Open
jlb6740 opened this issue Aug 3, 2022 · 6 comments
Open

Support for exceptions .. Disabling emscripten-cxx-exceptions #140

jlb6740 opened this issue Aug 3, 2022 · 6 comments

Comments

@jlb6740
Copy link

jlb6740 commented Aug 3, 2022

Hi .. Enabling exceptions for WASM seems to conflict with an -fno-exceptions flag being used by emscripten during linking.
For example, if I add a try and catch in the example and build with:

bazel build //example:http_wasm_example.wasm --features=exceptions

The build fails with the following error:

jlbirch@jlbirch:~/proxy-wasm-cpp-sdk-jlb6740/example$ bazel build //example:http_wasm_example.wasm --features=exceptions --verbose_failures
INFO: Analyzed target //example:http_wasm_example.wasm (0 packages loaded, 0 targets configured).
INFO: Found 1 target...
ERROR: /home/jlbirch/proxy-wasm-cpp-sdk-jlb6740/example/BUILD:5:21: Linking example/proxy_wasm_http_wasm_example failed: (Exit 1): emcc_link.sh failed: error executing command
(cd /home/jlbirch/.cache/bazel/_bazel_jlbirch/7341316095ecd002ea18765f811f48f4/sandbox/linux-sandbox/26/execroot/proxy_wasm_cpp_sdk &&
exec env -
EMCC_WASM_BACKEND=1
EM_BIN_PATH=external/emscripten_bin_linux
EM_CONFIG_PATH=external/emsdk/emscripten_toolchain/emscripten_config
PATH=/home/jlbirch/.cache/bazelisk/downloads/bazelbuild/bazel-4.1.0-linux-x86_64/bin:/home/jlbirch/.wasmer/bin:/home/jlbirch/emsdk:/home/jlbirch/emsdk/upstream/emscripten:/home/jlbirch/emsdk/node/14.18.2_64bit/bin:/opt/intel/oneapi/vtune/2022.2.0/bin64:/opt/intel/oneapi/vtune/latest/bin64:/opt/intel/oneapi/vtune/latest/android_target:/home/jlbirch/.wasmtime/bin:/home/jlbirch/.vscode-server/bin/6cba118ac49a1b88332f312a8f67186f7f3c1643/bin:/home/jlbirch/.local/bin:/home/jlbirch/.wasmer/bin:/home/jlbirch/.cargo/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/jlbirch/sde-external-9.0.0-2021-11-07-lin/:/home/jlbirch/wabt/build/:/home/jlbirch/node-v16.16.0-linux-x64/bin/:/home/jlbirch/.wasmer/globals/wapm_packages/.bin:/home/jlbirch/.wasmer/globals/wapm_packages/.bin
PWD=/proc/self/cwd
external/emsdk/emscripten_toolchain/emcc_link.sh @bazel-out/wasm-fastbuild-ST-7840e1c24980/bin/example/proxy_wasm_http_wasm_example-2.params)
Execution platform: @local_config_platform//:host

Use --sandbox_debug to see verbose messages from the sandbox
error: DISABLE_EXCEPTION_THROWING was set (likely due to -fno-exceptions), which means no C++ exception throwing support code is linked in, but exception catching code appears. Either do not set DISABLE_EXCEPTION_THROWING (if you do want exception throwing) or compile all source files with -fno-except (so that no exceptions support code is required); also make sure DISABLE_EXCEPTION_CATCHING is set to the right value - if you want exceptions, it should be off, and vice versa.
error: DISABLE_EXCEPTION_THROWING was set (likely due to -fno-exceptions), which means no C++ exception throwing support code is linked in, but exception catching code appears. Either do not set DISABLE_EXCEPTION_THROWING (if you do want exception throwing) or compile all source files with -fno-except (so that no exceptions support code is required); also make sure DISABLE_EXCEPTION_CATCHING is set to the right value - if you want exceptions, it should be off, and vice versa.
error: undefined symbol: __resumeException (referenced by top-level compiled C/C++ code)
warning: Link with -s LLD_REPORT_UNDEFINED to get more information on undefined symbols
warning: To disable errors for undefined symbols use -s ERROR_ON_UNDEFINED_SYMBOLS=0
warning: ___resumeException may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
Error: Aborting compilation due to previous errors
emcc: error: '/home/jlbirch/.cache/bazel/_bazel_jlbirch/7341316095ecd002ea18765f811f48f4/sandbox/linux-sandbox/26/execroot/proxy_wasm_cpp_sdk/external/nodejs_linux_amd64/bin/node /home/jlbirch/.cache/bazel/_bazel_jlbirch/7341316095ecd002ea18765f811f48f4/external/emscripten_bin_linux/emscripten/src/compiler.js /tmp/tmpr68z5zhw.json' failed (returned 1)
Target //example:http_wasm_example.wasm failed to build
INFO: Elapsed time: 2.611s, Critical Path: 2.47s
INFO: 5 processes: 2 internal, 3 linux-sandbox.
FAILED: Build did NOT complete successfully

The line in building.py of a very recent version of emscripten that emits the -fno-exceptions looks like this:

if not settings.DISABLE_EXCEPTION_CATCHING:
args += ['-enable-emscripten-cxx-exceptions']

Is there a way to programmatically set the setting of DISABLE_EXCEPTION_CATCHING in bazel build files? Currently I am forced to comment out the lines here.

@PiotrSikora
Copy link
Member

Looking at the errors, it looks that --features=exceptions actually works and enables exceptions.

The issue is that ___resumeException and other hostcalls are not available during build, so you need to either disable this check (--linkopt=-sERROR_ON_UNDEFINED_SYMBOLS=0 should work) or create a JavaScript stub with prototypes for those functions (similarly to how Emscripten is made aware of Proxy-Wasm hostcalls using proxy_wasm_intrinsics.js).

However, even if you get plugins to compile, Proxy-Wasm C++ Host / Envoy / Istio don't support C++ exceptions, so this all might be futile.

@jlb6740
Copy link
Author

jlb6740 commented Aug 3, 2022

Hi @PiotrSikora .. Thanks for the response. So I've updated the BUILD file for the example like this:

proxy_wasm_cc_binary(
name = "http_wasm_example.wasm",
srcs = ["http_wasm_example.cc"],
copts = ["-std=c++17", "-fwasm-exceptions"],
linkopts = ["-fwasm-exceptions -sERROR_ON_UNDEFINED_SYMBOLS=0"],
)

But am still getting the same error? But beyond that we are definitely trying to run a filter that requires exception handling and its disconcerting to hear it won't work in Envoy/Istio. (1) What work is needed to get that support in (and how much/difficult is that work)? (2) Are there workarounds to implement in Envoy/Istio for handling exceptions that wouldn't require modification to the filter?

@PiotrSikora
Copy link
Member

I think you need to add a comma between linkopts.

Regarding support for C++ exceptions in Envoy/Istio, there is a bug tracking it here: proxy-wasm/proxy-wasm-cpp-host#116.

To be honest, I didn't look at it since the support for native Wasm exceptions was added to V8 and Wasmtime. Perhaps it "just works"? But it looks that Emscripten still uses some JavaScript wrappers for them. Maybe @sbc100 can tell us more?

@jlb6740
Copy link
Author

jlb6740 commented Aug 3, 2022

Thanks. Yes, exception support seems to work now in V8 as of I think version v9.5 (the latest envoy is using v10.4) and in emscripten as of 3.1.16. I've tried in node and chrome devtools in the browser and both now show the same behavior as compiling C++ to native for the example tried. Perhaps it will work .. we just need to try?

About the flag, I tried both ways and tried via the command line but it makes no noticeable impact.

proxy_wasm_cc_binary(
name = "http_wasm_example.wasm",
srcs = ["http_wasm_example.cc"],
copts = ["-std=c++17", "-fwasm-exceptions"],
linkopts = ["-fwasm-exceptions", "-sERROR_ON_UNDEFINED_SYMBOLS=0"],
)

@PiotrSikora
Copy link
Member

Are you sure that we need both -fexceptions (enabled by --features=exceptions) and -fwasm-exceptions?

@jlb6740
Copy link
Author

jlb6740 commented Aug 3, 2022

Yeah, the flag combination is just not at clear to me and obviously will be dependent and become even less clear when considering the version of emscripten matters. I'm using very close to the latest release. It seems the fwasm-exceptions is needed. If I remove that then there is an undefined symbol:

wasm-ld: error: bazel-out/wasm-fastbuild-ST-6632493ac585/bin/example/_objs/proxy_wasm_http_wasm_example/http_wasm_example.o: undefined symbol: __wasm_lpad_context

which in quick reading appears to related to the landing location for exception handling. If I remove the -fexceptions on the bazel command I get:

cannot use 'throw' with exceptions disabled

Seems both are needed. I'm wondering if this confusion is managable with bazel build flags or if there is something with emscripten that needs to be filed. I'm hoping to figure this out with the right combination of build flags.

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

2 participants