proxy-wasm-cpp-sdk
proxy-wasm-cpp-sdk copied to clipboard
Support for exceptions .. Disabling emscripten-cxx-exceptions
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//:hostUse --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.
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.
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?
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: https://github.com/proxy-wasm/proxy-wasm-cpp-host/issues/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?
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"], )
Are you sure that we need both -fexceptions
(enabled by --features=exceptions
) and -fwasm-exceptions
?
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.