dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
15.26k stars 4.73k forks source link

Issues using Blazor Multithreading within iframes #86696

Closed IsaMorphic closed 1 year ago

IsaMorphic commented 1 year ago

Is there an existing issue for this?

Describe the bug

Using the wasm-buildtools for .NET 8.0 Preview 4, I have come across an unpredictable and frequent runtime bug when embedding a multithreaded Blazor application within an iframe on another page. I've double checked that all CSP and CORS policies are in order and not the root cause.

In fact, I found someone else reporting this exact same issue, only in a completely different use case over by the emscripten repository: https://github.com/emscripten-core/emscripten/issues/18034

The workaround being tossed out there by several developers is to make sure that all calls to emcc use the flag -s TEXTDECODER=0

I've been able to greatly reduce the frequency of this error by adding this flag using these properties: <EmccCompileOptimizationFlag>-O2 -s TEXTDECODER=0</EmccCompileOptimizationFlag> <EmccLinkOptimizationFlag>-O2 -s TEXTDECODER=0</EmccLinkOptimizationFlag> to my csproj file.

I have also confirmed that these flags are being used to compile my assemblies and dependencies. However, I can't figure out a way to add this flag to the main dotnet.wasm emcc command to ensure that my dotnet-runtime.js file does not use TextDecoder to marshal WASM memory across threads.

Interesting to note is that the frequency of this error greatly decreases when embedding the blazor application page with object tags instead of iframe.

Regardless, the error I am receiving exhibits the same, inconsistent behavior. I'm guessing this is a Blazor toolchain issue that can be fixed by making sure that the -s TEXTDECODER=0 flag is used when compiling dotnet-runtime.js at publish-time; to safeguard against any regressions of users this bug doesn't affect, this flag would only be added if WasmEnableThreads is also explicitly enabled. I'm willing to write a PR that implements this.

Expected Behavior

The expected behavior is that I can use my multithreaded Blazor WebAssembly application within an iframe without the previously described inconsistent crashing behavior.

Steps To Reproduce

No response

Exceptions (if any)

Uncaught TypeError: Failed to execute 'decode' on 'TextDecoder': The provided ArrayBufferView value must not be shared.

.NET Version

8.0.100-preview.4.23260.5

Anything else?

No response

IsaMorphic commented 1 year ago

Hey there again everyone,

I managed to isolate the issue after figuring out that I can use an OS-wide environment variable to append whatever arguments I want to all calls to emcc. Its called EMCC_CFLAGS. Turns out that my issue is rooted inside of the mono wasm runtime. I've found the exact fallacious line of code and will open a PR there instead to resolve this.

Here's a link to the problematic method for anyone curious: https://github.com/dotnet/runtime/blob/da30389d2c0c3e5cad98f82e9bee0c9e8cfd78eb/src/mono/wasm/runtime/strings.ts#L74

Thanks, ~Isabelle

ghost commented 1 year ago

Tagging subscribers to 'arch-wasm': @lewing See info in area-owners.md if you want to be subscribed.

Issue Details
### Is there an existing issue for this? - [X] I have searched the existing issues ### Describe the bug Using the wasm-buildtools for .NET 8.0 Preview 4, I have come across an unpredictable and frequent runtime bug when embedding a multithreaded Blazor application within an iframe on another page. I've double checked that all CSP and CORS policies are in order and not the root cause. In fact, I found someone else reporting this exact same issue, only in a completely different use case over by the emscripten repository: https://github.com/emscripten-core/emscripten/issues/18034 The workaround being tossed out there by several developers is to make sure that all calls to `emcc` use the flag `-s TEXTDECODER=0` I've been able to greatly reduce the frequency of this error by adding this flag using these properties: `-O2 -s TEXTDECODER=0` `-O2 -s TEXTDECODER=0` to my csproj file. I have also confirmed that these flags are being used to compile my assemblies and dependencies. However, I can't figure out a way to add this flag to the main dotnet.wasm emcc command to ensure that my dotnet-runtime.js file does not use `TextDecoder` to marshal WASM memory across threads. Interesting to note is that the frequency of this error greatly decreases when embedding the blazor application page with `object` tags instead of `iframe`. Regardless, the error I am receiving exhibits the same, inconsistent behavior. I'm guessing this is a Blazor toolchain issue that can be fixed by making sure that the `-s TEXTDECODER=0` flag is used when compiling dotnet-runtime.js at publish-time; to safeguard against any regressions of users this bug doesn't affect, this flag would only be added if `WasmEnableThreads` is also explicitly enabled. I'm willing to write a PR that implements this. ### Expected Behavior The expected behavior is that I can use my multithreaded Blazor WebAssembly application within an `iframe` without the previously described inconsistent crashing behavior. ### Steps To Reproduce _No response_ ### Exceptions (if any) `Uncaught TypeError: Failed to execute 'decode' on 'TextDecoder': The provided ArrayBufferView value must not be shared.` ### .NET Version 8.0.100-preview.4.23260.5 ### Anything else? _No response_
Author: IsaMorphic
Assignees: -
Labels: `arch-wasm`, `untriaged`, `area-VM-meta-mono`, `area-System.Runtime.InteropServices.JavaScript`
Milestone: -
radical commented 1 year ago

cc @pavelsavara