From 2d523c507ec0945a356137833db55980ba6d75f3 Mon Sep 17 00:00:00 2001 From: Guenther Schmuelling Date: Mon, 28 Nov 2022 10:24:34 -0800 Subject: [PATCH] for wasm catch exceptions at top level api (#13644) fix for https://github.com/microsoft/onnxruntime/issues/13383, https://github.com/microsoft/onnxruntime/issues/13408 Currently ort-web doesn't catch exceptions because turning on exception catching increases the binary size by 3MB (~30%). But ort can throw (ie onnx errors or ORT_ENFORCE) and there is no useable error message. Turning on exception catching just for top level api released file will fix the error messages at minimal increase of binary size. --- cmake/CMakeLists.txt | 4 +- cmake/onnxruntime_webassembly.cmake | 40 ++++++++++++------- tools/ci_build/build.py | 12 ++++++ .../azure-pipelines/templates/web-ci.yml | 2 +- 4 files changed, 40 insertions(+), 18 deletions(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 7906a01a81..e0ad8ed51a 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -160,6 +160,7 @@ option(onnxruntime_BUILD_WEBASSEMBLY "Enable this option to create WebAssembly b option(onnxruntime_BUILD_WEBASSEMBLY_STATIC_LIB "Enable this option to create WebAssembly static library" OFF) option(onnxruntime_ENABLE_WEBASSEMBLY_THREADS "Enable this option to create WebAssembly byte codes with multi-threads support" OFF) option(onnxruntime_ENABLE_WEBASSEMBLY_EXCEPTION_CATCHING "Enable this option to turn on exception catching" OFF) +option(onnxruntime_ENABLE_WEBASSEMBLY_API_EXCEPTION_CATCHING "Enable this option to turn on api exception catching" OFF) option(onnxruntime_ENABLE_WEBASSEMBLY_EXCEPTION_THROWING "Enable this option to turn on exception throwing even if the build disabled exceptions support" OFF) option(onnxruntime_ENABLE_WEBASSEMBLY_DEBUG_INFO "Enable this option to turn on DWARF format debug info" OFF) option(onnxruntime_ENABLE_WEBASSEMBLY_PROFILING "Enable this option to turn on WebAssembly profiling and preserve function names" OFF) @@ -362,8 +363,7 @@ if (onnxruntime_BUILD_WEBASSEMBLY) # NOTE: With debug info enabled, web assembly artifacts will be very huge (>1GB). So we offer an option to build without debug info. set(CMAKE_CXX_FLAGS_DEBUG "-g3") else() - # do not generate any debug info. This helps to accelerate building process and reduce binary size. - set(CMAKE_CXX_FLAGS_DEBUG "-g0") + set(CMAKE_CXX_FLAGS_DEBUG "-g2") endif() if (onnxruntime_ENABLE_WEBASSEMBLY_SIMD) diff --git a/cmake/onnxruntime_webassembly.cmake b/cmake/onnxruntime_webassembly.cmake index 12d0c68785..19ac1ce1f5 100644 --- a/cmake/onnxruntime_webassembly.cmake +++ b/cmake/onnxruntime_webassembly.cmake @@ -160,6 +160,17 @@ else() ${onnxruntime_webassembly_src} ) + if (onnxruntime_ENABLE_WEBASSEMBLY_API_EXCEPTION_CATCHING) + # we catch exceptions at the api level + file(GLOB_RECURSE onnxruntime_webassembly_src_exc CONFIGURE_DEPENDS + "${ONNXRUNTIME_ROOT}/wasm/api.cc" + "${ONNXRUNTIME_ROOT}/core/session/onnxruntime_c_api.cc" + ) + set (WASM_API_EXCEPTION_CATCHING "-s DISABLE_EXCEPTION_CATCHING=0") + message(STATUS "onnxruntime_ENABLE_WEBASSEMBLY_EXCEPTION_CATCHING_ON_API set") + set_source_files_properties(${onnxruntime_webassembly_src_exc} PROPERTIES COMPILE_FLAGS ${WASM_API_EXCEPTION_CATCHING}) + endif() + target_link_libraries(onnxruntime_webassembly PRIVATE nsync_cpp ${PROTOBUF_LIB} @@ -187,19 +198,20 @@ else() set(EXPORTED_RUNTIME_METHODS "['stackAlloc','stackRestore','stackSave','UTF8ToString','stringToUTF8','lengthBytesUTF8']") - set_target_properties(onnxruntime_webassembly PROPERTIES LINK_FLAGS " \ + set_target_properties(onnxruntime_webassembly PROPERTIES LINK_FLAGS " \ -s \"EXPORTED_RUNTIME_METHODS=${EXPORTED_RUNTIME_METHODS}\" \ - -s \"EXPORTED_FUNCTIONS=_malloc,_free\" \ - -s MAXIMUM_MEMORY=4294967296 \ - -s WASM=1 \ - -s NO_EXIT_RUNTIME=0 \ - -s ALLOW_MEMORY_GROWTH=1 \ - -s MODULARIZE=1 \ - -s EXPORT_ALL=0 \ - -s LLD_REPORT_UNDEFINED \ - -s VERBOSE=0 \ - -s NO_FILESYSTEM=1 \ - --closure 1 \ + -s \"EXPORTED_FUNCTIONS=_malloc,_free\" \ + -s MAXIMUM_MEMORY=4294967296 \ + -s WASM=1 \ + -s NO_EXIT_RUNTIME=0 \ + -s ALLOW_MEMORY_GROWTH=1 \ + -s MODULARIZE=1 \ + -s EXPORT_ALL=0 \ + -s LLD_REPORT_UNDEFINED \ + -s VERBOSE=0 \ + -s NO_FILESYSTEM=1 \ + ${WASM_API_EXCEPTION_CATCHING} \ + --closure 1 \ --no-entry") if (onnxruntime_EMSCRIPTEN_SETTINGS) @@ -216,9 +228,7 @@ else() endif() # Set link flag to enable exceptions support, this will override default disabling exception throwing behavior when disable exceptions. - if (onnxruntime_ENABLE_WEBASSEMBLY_EXCEPTION_THROWING) - set_property(TARGET onnxruntime_webassembly APPEND_STRING PROPERTY LINK_FLAGS " -s DISABLE_EXCEPTION_THROWING=0") - endif() + set_property(TARGET onnxruntime_webassembly APPEND_STRING PROPERTY LINK_FLAGS " -s DISABLE_EXCEPTION_THROWING=0") if (onnxruntime_ENABLE_WEBASSEMBLY_PROFILING) set_property(TARGET onnxruntime_webassembly APPEND_STRING PROPERTY LINK_FLAGS " --profiling --profiling-funcs") diff --git a/tools/ci_build/build.py b/tools/ci_build/build.py index 077d9932dc..72db402cbe 100644 --- a/tools/ci_build/build.py +++ b/tools/ci_build/build.py @@ -395,6 +395,9 @@ def parse_arguments(): parser.add_argument( "--disable_wasm_exception_catching", action="store_true", help="Disable exception catching in WebAssembly." ) + parser.add_argument( + "--enable_wasm_api_exception_catching", action="store_true", help="Catch exceptions at top level api." + ) parser.add_argument( "--enable_wasm_exception_throwing_override", action="store_true", @@ -672,6 +675,13 @@ def parse_arguments(): if args.android_ndk_path: args.android_ndk_path = os.path.normpath(args.android_ndk_path) + if args.enable_wasm_api_exception_catching: + # if we catch on api level, we don't want to catch all + args.disable_wasm_exception_catching = True + if not args.disable_wasm_exception_catching or args.enable_wasm_api_exception_catching: + # doesn't make sense to catch if no one throws + args.enable_wasm_exception_throwing_override = True + return args @@ -926,6 +936,8 @@ def generate_build_tree( "-Donnxruntime_BUILD_WEBASSEMBLY_STATIC_LIB=" + ("ON" if args.build_wasm_static_lib else "OFF"), "-Donnxruntime_ENABLE_WEBASSEMBLY_EXCEPTION_CATCHING=" + ("OFF" if args.disable_wasm_exception_catching else "ON"), + "-Donnxruntime_ENABLE_WEBASSEMBLY_API_EXCEPTION_CATCHING=" + + ("ON" if args.enable_wasm_api_exception_catching else "OFF"), "-Donnxruntime_ENABLE_WEBASSEMBLY_EXCEPTION_THROWING=" + ("ON" if args.enable_wasm_exception_throwing_override else "OFF"), "-Donnxruntime_ENABLE_WEBASSEMBLY_THREADS=" + ("ON" if args.enable_wasm_threads else "OFF"), diff --git a/tools/ci_build/github/azure-pipelines/templates/web-ci.yml b/tools/ci_build/github/azure-pipelines/templates/web-ci.yml index df53f23a26..ec7c89fccd 100644 --- a/tools/ci_build/github/azure-pipelines/templates/web-ci.yml +++ b/tools/ci_build/github/azure-pipelines/templates/web-ci.yml @@ -71,7 +71,7 @@ stages: parameters: CommitOverride: true BuildConfig: 'Release' - ExtraBuildArgs: '--skip_tests --disable_wasm_exception_catching --disable_rtti $(ExtraBuildArgs)' + ExtraBuildArgs: '--skip_tests --enable_wasm_api_exception_catching --disable_rtti $(ExtraBuildArgs)' PoolName: ${{ parameters.PoolName }} - ${{ if eq(parameters.BuildStaticLib, 'true') }}: