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

.NET 8 WebAssembly AOT not generating trampoline functions #97906

Closed
AshleighAdams opened this issue Feb 3, 2024 · 8 comments
Closed

.NET 8 WebAssembly AOT not generating trampoline functions #97906

AshleighAdams opened this issue Feb 3, 2024 · 8 comments
Assignees
Labels
arch-wasm WebAssembly architecture area-Interop-mono
Milestone

Comments

@AshleighAdams
Copy link

AshleighAdams commented Feb 3, 2024

Description

When building trampoline functions to call into native code, delegates marked the the UnmanagedFunctionPointer attribute in .NET 6, and .NET 7 (tho not upon initial release) are taken into account.

Since .NET 8, natively calling into these methods once again causes mono_wasm_get_interp_to_native_trampoline() to fail, and the application to crash.

Reproduction Steps

A minimal WebGL sample that encounters the bug is located here: AshleighAdams/dotnet-webgl-sample#6

Note, that you must AOT build the sample:

$ dotnet publish --configuration Release -p:OutputPath="$(pwd)/build" && (cd build/AppBundle/ && dotnet serve -o)

Internally, the sample is calling into emscripten's GL via Silk.NET, and in the project the following delegate can be found to get AOT to trampoline the function:

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void glClearColor_t(float red, float green, float blue, float alpha);

Expected behavior

Expect .NET to trampoline the call into native code correctly

Actual behavior

Crashes with an exception:

ht@http://localhost:50621/AppBundle/_framework/dotnet.runtime.js:3:12765
Ul<@http://localhost:50621/AppBundle/_framework/dotnet.runtime.js:3:175673
@http://localhost:50621/AppBundle/_framework/dotnet.native.wasm:wasm-function[23542]:0x4f3254
@http://localhost:50621/AppBundle/_framework/dotnet.native.wasm:wasm-function[20797]:0x42e6c7
@http://localhost:50621/AppBundle/_framework/dotnet.native.wasm:wasm-function[20720]:0x42b128
@http://localhost:50621/AppBundle/_framework/dotnet.native.wasm:wasm-function[20722]:0x42b1f5
@http://localhost:50621/AppBundle/_framework/dotnet.native.wasm:wasm-function[20723]:0x42b22b
@http://localhost:50621/AppBundle/_framework/dotnet.native.wasm:wasm-function[20407]:0x3fc3e8
@http://localhost:50621/AppBundle/_framework/dotnet.native.wasm:wasm-function[20475]:0x40bcaa
@http://localhost:50621/AppBundle/_framework/dotnet.native.wasm:wasm-function[20482]:0x40bf3a
@http://localhost:50621/AppBundle/_framework/dotnet.native.wasm:wasm-function[16516]:0x3304c5
@http://localhost:50621/AppBundle/_framework/dotnet.native.wasm:wasm-function[533]:0x1ffbc
@http://localhost:50621/AppBundle/_framework/dotnet.native.wasm:wasm-function[13621]:0x2a7441
@http://localhost:50621/AppBundle/_framework/dotnet.native.wasm:wasm-function[13637]:0x2a9960
@http://localhost:50621/AppBundle/_framework/dotnet.native.wasm:wasm-function[13662]:0x2ab344
tick@http://localhost:50621/AppBundle/_framework/dotnet.native.js:8:166166
[logging.ts:119:20](https://raw.githubusercontent.com/dotnet/runtime/eddf880ac57b7f2c79a77592e3e6d24d1d02f112/src/mono/wasm/runtime/logging.ts)
    Ul logging.ts:119
    <anonymous> dotnet.native.wasm:5190228
    <anonymous> dotnet.native.wasm:4384455
    <anonymous> dotnet.native.wasm:4370728
    <anonymous> dotnet.native.wasm:4370933
    <anonymous> dotnet.native.wasm:4370987
    <anonymous> dotnet.native.wasm:4178920
    <anonymous> dotnet.native.wasm:4242602
    <anonymous> dotnet.native.wasm:4243258
    <anonymous> dotnet.native.wasm:3343557
    <anonymous> dotnet.native.wasm:131004
    <anonymous> dotnet.native.wasm:2782273
    <anonymous> dotnet.native.wasm:2791776
    <anonymous> dotnet.native.wasm:2798404
    tick dotnet.native.js:8

Regression?

Yes, it worked in .NET 6 and .NET 7

Known Workarounds

Unknown for now

Configuration

WebGL, happens when built on Linux and Windows
Issue is in both Chrome and Firefox, latest versions

Other information

In .NET 7, a snippet that referenced the function pointer existed to stop it from being trimmed, I tried this again but additionally on glClearColor_t() which is getting trimmed:

Marshal.GetDelegateForFunctionPointer(new nint(1), typeof(glClearColor_t));

and I also tried adding the dynamic dependency to my trampoline class:

[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(TrampolineFuncs))]

Neither of these had any success

The previous .NET 7 regression issue is here: #76930

@ghost ghost added the untriaged New issue has not been triaged by the area owner label Feb 3, 2024
@dotnet-issue-labeler dotnet-issue-labeler bot added the needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners label Feb 3, 2024
@AshleighAdams AshleighAdams changed the title .NET 8 WebAssembly AOT not generating trampoline functions correctly .NET 8 WebAssembly AOT not generating trampoline functions Feb 3, 2024
@filipnavara filipnavara added arch-wasm WebAssembly architecture area-Interop-mono and removed needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners labels Feb 3, 2024
@ghost
Copy link

ghost commented Feb 3, 2024

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

Issue Details

Description

When building trampoline functions to call into native code, delegates marked the the UnmanagedFunctionPointer attribute in .NET 6, and .NET 7 (tho not upon initial release) are taken into account.

Since .NET 8, natively calling into these methods once again causes mono_wasm_get_interp_to_native_trampoline() to fail, and the application to crash.

Reproduction Steps

A minimal WebGL sample that encounters the bug is located here: AshleighAdams/dotnet-webgl-sample#6

Note, that you must AOT build the sample:

$ dotnet publish --configuration Release -p:OutputPath="$(pwd)/build" && (cd build/AppBundle/ && dotnet serve -o)

Internally, the sample is calling into emscripten's GL via Silk.NET, and in the project the following delegate can be found to get AOT to trampoline the function:

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void glClearColor_t(float red, float green, float blue, float alpha);

Expected behavior

Expect .NET to trampoline the call into native code correctly

Actual behavior

Crashes with an exception:

ht@http://localhost:50621/AppBundle/_framework/dotnet.runtime.js:3:12765
Ul<@http://localhost:50621/AppBundle/_framework/dotnet.runtime.js:3:175673
@http://localhost:50621/AppBundle/_framework/dotnet.native.wasm:wasm-function[23542]:0x4f3254
@http://localhost:50621/AppBundle/_framework/dotnet.native.wasm:wasm-function[20797]:0x42e6c7
@http://localhost:50621/AppBundle/_framework/dotnet.native.wasm:wasm-function[20720]:0x42b128
@http://localhost:50621/AppBundle/_framework/dotnet.native.wasm:wasm-function[20722]:0x42b1f5
@http://localhost:50621/AppBundle/_framework/dotnet.native.wasm:wasm-function[20723]:0x42b22b
@http://localhost:50621/AppBundle/_framework/dotnet.native.wasm:wasm-function[20407]:0x3fc3e8
@http://localhost:50621/AppBundle/_framework/dotnet.native.wasm:wasm-function[20475]:0x40bcaa
@http://localhost:50621/AppBundle/_framework/dotnet.native.wasm:wasm-function[20482]:0x40bf3a
@http://localhost:50621/AppBundle/_framework/dotnet.native.wasm:wasm-function[16516]:0x3304c5
@http://localhost:50621/AppBundle/_framework/dotnet.native.wasm:wasm-function[533]:0x1ffbc
@http://localhost:50621/AppBundle/_framework/dotnet.native.wasm:wasm-function[13621]:0x2a7441
@http://localhost:50621/AppBundle/_framework/dotnet.native.wasm:wasm-function[13637]:0x2a9960
@http://localhost:50621/AppBundle/_framework/dotnet.native.wasm:wasm-function[13662]:0x2ab344
tick@http://localhost:50621/AppBundle/_framework/dotnet.native.js:8:166166
[logging.ts:119:20](https://raw.githubusercontent.com/dotnet/runtime/eddf880ac57b7f2c79a77592e3e6d24d1d02f112/src/mono/wasm/runtime/logging.ts)
    Ul logging.ts:119
    <anonymous> dotnet.native.wasm:5190228
    <anonymous> dotnet.native.wasm:4384455
    <anonymous> dotnet.native.wasm:4370728
    <anonymous> dotnet.native.wasm:4370933
    <anonymous> dotnet.native.wasm:4370987
    <anonymous> dotnet.native.wasm:4178920
    <anonymous> dotnet.native.wasm:4242602
    <anonymous> dotnet.native.wasm:4243258
    <anonymous> dotnet.native.wasm:3343557
    <anonymous> dotnet.native.wasm:131004
    <anonymous> dotnet.native.wasm:2782273
    <anonymous> dotnet.native.wasm:2791776
    <anonymous> dotnet.native.wasm:2798404
    tick dotnet.native.js:8

Regression?

Yes, it worked in .NET 6 and .NET 7

Known Workarounds

Unknown for now

Configuration

WebGL, happens when built on Linux and Windows
Issue is in both Chrome and Firefox, latest versions

Other information

In .NET 7, a snippet that referenced the function pointer existed to stop it from being trimmed, I tried this again but additionally on glClearColor_t() which is getting trimmed:

Marshal.GetDelegateForFunctionPointer(new nint(1), typeof(glClearColor_t));

and I also tried adding the dynamic dependency to my trampoline class:

[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(TrampolineFuncs))]

Neither of these had any success

The previous .NET 7 regression issue is here: #76930

Author: AshleighAdams
Assignees: -
Labels:

arch-wasm, untriaged, area-Interop-mono

Milestone: -

@lewing lewing added this to the 9.0.0 milestone Feb 5, 2024
@ghost ghost removed the untriaged New issue has not been triaged by the area owner label Feb 5, 2024
@lewing
Copy link
Member

lewing commented Feb 5, 2024

cc @vargaz @kg @steveisok

@kg
Copy link
Member

kg commented Feb 5, 2024

Are there any warnings or related messages in the build log?

@AshleighAdams
Copy link
Author

@lewing
Copy link
Member

lewing commented Jul 29, 2024

@kg what is the status of this one?

@kg
Copy link
Member

kg commented Jul 29, 2024

@kg what is the status of this one?

I didn't have an opportunity to get to the bottom of it

@AshleighAdams
Copy link
Author

This is fixed in .NET 9 preview 6

Is there anything we can do to help prevent this from regressing a third time? I know this isn't an "officially" supported part of wasm yet, but nonetheless I think it is still very important

@kg
Copy link
Member

kg commented Jul 31, 2024

We could add a simple regression test for it. I added a small suite of P/Invoke tests to our test suite while doing my p/invoke work during .NET 9. It's not obvious to me why the glClearColor call from the original report wouldn't have gotten a trampoline, though - someone who knows our AOT infrastructure better might be able to guess.

@lewing lewing modified the milestones: 9.0.0, 10.0.0 Aug 15, 2024
@agocke agocke added this to AppModel Sep 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
arch-wasm WebAssembly architecture area-Interop-mono
Projects
Archived in project
Development

No branches or pull requests

5 participants