Skip to content

WebAssembly fails to generate trampoline for delegates decorated with UnmanagedFunctionPointer #76930

Closed
@AshleighAdams

Description

@AshleighAdams

Description

I'm updating a project from dotnet 6 to dotnet 7, which uses WebGL, and WaveEngine/Evergine's OpenGL bindings, these bindings declare functions that can be called dynamically thru a pointer like so:

[UnmanagedFunctionPointer(CallConv)]
private delegate void glClearDepth_t(double depth);
private static glClearDepth_t p_glClearDepth;
public static void glClearDepth(double depth) => p_glClearDepth(depth);

(https://github.com/EvergineTeam/OpenGL.NET/blob/master/OpenGLGen/Evergine.Bindings.OpenGL/GL.cs#L97-L100)

Invoking this function from BlazorWebassembly results in the following error being raised:

image

Reproduction Steps

On either net7 rc.1 or rc.2,

The dotnet7 branch over here has a minimal sample that triggers the bug:

https://github.com/AshleighAdams/dotnet-webgl-sample/tree/dotnet7

Expected behavior

Expected the invocation to succeeed and subsequently the canvas cleared

Actual behavior

An error ir raised with just "disabled". The full stacktrace is:

Error: [MONO] /__w/1/s/src/mono/mono/mini/aot-runtime-wasm.c:150 <disabled>
    at xe (dotnet..5wr98gfm9z.js:5:509)
    at Object.je (dotnet..5wr98gfm9z.js:5:792)
    at _mono_wasm_trace_logger (dotnet..5wr98gfm9z.js:10179:67)
    at wasm_trace_logger (03015f66:0x23dc78)
    at eglib_log_adapter (03015f66:0xca8a3)
    at monoeg_g_logstr (03015f66:0x21a88e)
    at monoeg_g_logv_nofree (03015f66:0x21a830)
    at monoeg_g_logv (03015f66:0x21a7d9)
    at monoeg_g_log (03015f66:0x21a8ae)
    at g_log_disabled (03015f66:0x21a8e2)
je	@	dotnet..5wr98gfm9z.js:5
_mono_wasm_trace_logger	@	dotnet..5wr98gfm9z.js:10179
$wasm_trace_logger	@	03015f66:0x23dc78
$eglib_log_adapter	@	03015f66:0xca8a3
$monoeg_g_logstr	@	03015f66:0x21a88e
$monoeg_g_logv_nofree	@	03015f66:0x21a830
$monoeg_g_logv	@	03015f66:0x21a7d9
$monoeg_g_log	@	03015f66:0x21a8ae
$g_log_disabled	@	03015f66:0x21a8e2
$mono_wasm_get_interp_to_native_trampoline	@	03015f66:0x205d69
$ves_pinvoke_method	@	03015f66:0x1c8d9
$interp_exec_method	@	03015f66:0xd467
$interp_runtime_invoke	@	03015f66:0xc1a0
$mono_jit_runtime_invoke	@	03015f66:0x1f4b1a
$do_runtime_invoke	@	03015f66:0x9f546
$mono_runtime_invoke_checked	@	03015f66:0x9f4d3
$mono_runtime_try_invoke_span	@	03015f66:0xa3e03
$mono_runtime_invoke_span_checked	@	03015f66:0xa405d
$ves_icall_InternalInvoke	@	03015f66:0x7859a
$ves_icall_InternalInvoke_raw	@	03015f66:0x7f6e9
$do_icall	@	03015f66:0x1d7db
$do_icall_wrapper	@	03015f66:0x1c73a
$interp_exec_method	@	03015f66:0xd34a
$interp_runtime_invoke	@	03015f66:0xc1a0
$mono_jit_runtime_invoke	@	03015f66:0x1f4b1a
$do_runtime_invoke	@	03015f66:0x9f546
$mono_runtime_try_invoke	@	03015f66:0x9fc8a
$mono_runtime_invoke	@	03015f66:0xa1e25
$mono_wasm_invoke_method_ref	@	03015f66:0x23e048
Module._mono_wasm_invoke_method_ref	@	dotnet..5wr98gfm9z.js:11213
_Microsoft_AspNetCore_Components_WebAssembly__Microsoft_AspNetCore_Components_WebAssembly_Services_DefaultWebAssemblyJSRuntime_InvokeDotNet	@	_Microsoft_AspNetCor…ime_InvokeDotNet:29
invokeDotNetFromJS	@	blazor.webassembly.js:1
g	@	blazor.webassembly.js:1
e.invokeMethod	@	blazor.webassembly.js:1
frame	@	(index):26
requestAnimationFrame (async)		
window.initialize	@	(index):22
invokeJSFromDotNet	@	blazor.webassembly.js:1
Gt	@	blazor.webassembly.js:1
Ii	@	dotnet..5wr98gfm9z.js:5
_mono_wasm_invoke_js_blazor	@	dotnet..5wr98gfm9z.js:10144
$do_icall	@	03015f66:0x1d83a
$do_icall_wrapper	@	03015f66:0x1c73a
$interp_exec_method	@	03015f66:0xd34a
$interp_runtime_invoke	@	03015f66:0xc1a0
$mono_jit_runtime_invoke	@	03015f66:0x1f4b1a
$do_runtime_invoke	@	03015f66:0x9f546
$mono_runtime_try_invoke	@	03015f66:0x9fc8a
$mono_runtime_invoke	@	03015f66:0xa1e25
$mono_wasm_invoke_method_ref	@	03015f66:0x23e048
Module._mono_wasm_invoke_method_ref	@	dotnet..5wr98gfm9z.js:11213
_WasmTest__entrypoint	@	_WasmTest__entrypoint:26
(anonymous)	@	dotnet..5wr98gfm9z.js:5
ji	@	dotnet..5wr98gfm9z.js:5
callEntryPoint	@	blazor.webassembly.js:1
Vt	@	blazor.webassembly.js:1
await in Vt (async)		
(anonymous)	@	blazor.webassembly.js:1
(anonymous)

Regression?

Yes, this is a regression. This worked in .NET 6

Known Workarounds

If you force the trampoline to be generated by adding the following, and if AOTing, add -s ERROR_ON_UNDEFINED_SYMBOLS=0 to EmccFlags, then everything works as expected:

[DllImport("libEGL", EntryPoint = "glClearColor")]
internal static extern void glClearColor_tramp(float red, float green, float blue, float alpha);

Configuration

$ dotnet --info
.NET SDK:
Version: 7.0.100-rc.2.22477.23
Commit: 0a5360315a

Runtime Environment:
OS Name: Windows
OS Version: 10.0.22000
OS Platform: Windows
RID: win10-x64
Base Path: C:\Program Files\dotnet\sdk\7.0.100-rc.2.22477.23\

Host:
Version: 7.0.0-rc.2.22472.3
Architecture: x64
Commit: 550605c

.NET SDKs installed:
5.0.404 [C:\Program Files\dotnet\sdk]
6.0.201 [C:\Program Files\dotnet\sdk]
6.0.401 [C:\Program Files\dotnet\sdk]
7.0.100-preview.6.22352.1 [C:\Program Files\dotnet\sdk]
7.0.100-rc.2.22477.23 [C:\Program Files\dotnet\sdk]

.NET runtimes installed:
Microsoft.AspNetCore.App 3.1.29 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 5.0.13 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 5.0.17 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 6.0.9 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 6.0.10 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 7.0.0-preview.6.22330.3 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 7.0.0-rc.2.22476.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.NETCore.App 3.1.29 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 5.0.13 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 5.0.17 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 6.0.9 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 6.0.10 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 7.0.0-preview.6.22324.4 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 7.0.0-rc.2.22472.3 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.WindowsDesktop.App 3.1.29 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 5.0.13 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 5.0.17 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 6.0.9 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 6.0.10 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 7.0.0-preview.6.22351.3 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 7.0.0-rc.2.22472.13 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

Other architectures found:
arm64 [C:\Program Files\dotnet]
registered at [HKLM\SOFTWARE\dotnet\Setup\InstalledVersions\arm64\InstallLocation]
x86 [C:\Program Files (x86)\dotnet]
registered at [HKLM\SOFTWARE\dotnet\Setup\InstalledVersions\x86\InstallLocation]

Environment variables:
Not set

global.json file:
Not found

Learn more:
https://aka.ms/dotnet/info

Download .NET:
https://aka.ms/dotnet/download

Other information

No response

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions