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

[mono] invoke delegate method thunk hit asset. #83823

Open
srxqds opened this issue Mar 23, 2023 · 8 comments
Open

[mono] invoke delegate method thunk hit asset. #83823

srxqds opened this issue Mar 23, 2023 · 8 comments

Comments

@srxqds
Copy link
Contributor

srxqds commented Mar 23, 2023

Description

we embed mono, use jit mix with interp, use mono_jit_set_aot_mode(MONO_AOT_MODE_INTERP_ONLY);

we get MonoDelegate invoke method thunk and invoke it, it hit asset at line:

g_assert (sig->hasthis);

Reproduction Steps

// pass delegate from c# to c.
MonoDelegate* InDelegate;
MonoClass* DelegateClass = mono_object_get_class(InDelegate);

MonoMethod* InvokeMethod = mono_get_delegate_invoke(DelegateClass);

void * ThunkMethod = mono_method_get_unmanaged_thunk(InvokeMethod );
typedef bool(STDCALL ThunkWithMonoObjectDeclaration) (MonoObject, float, MonoObject**);
bool result = (ThunkWithMonoObjectDeclaration)ThunkMethod(InDelegate, 1, nullptr); // hit crash

it works well in aot_interp or jit mode.

Expected behavior

work correctly

Actual behavior

crash

Regression?

no

Known Workarounds

No response

Configuration

dotnet7.0.3 mono

Other information

No response

@ghost ghost added the untriaged New issue has not been triaged by the area owner label Mar 23, 2023
@srxqds
Copy link
Contributor Author

srxqds commented Mar 23, 2023

this line should set csig->hasthis if this is delegate invoke method.

if (sig->hasthis) {

and the stacktrace:

coreclr.dll!emit_delegate_invoke_internal_ilgen(_MonoMethodBuilder * mb, _MonoMethodSignature * sig, _MonoMethodSignature * invoke_sig, int static_method_with_first_arg_bound, int callvirt, int closed_over_null, _MonoMethod * method, _MonoMethod * target_method, _MonoClass * target_class, _MonoGenericContext * ctx, _MonoGenericContainer * container) Line 1981
	at F:\netease-gitlab\dotnet\runtime\src\mono\mono\metadata\marshal-lightweight.c(1981)
coreclr.dll!mono_marshal_get_delegate_invoke_internal(_MonoMethod * method, int callvirt, int static_method_with_first_arg_bound, _MonoMethod * target_method) Line 2175
	at F:\netease-gitlab\dotnet\runtime\src\mono\mono\metadata\marshal.c(2175)
coreclr.dll!mono_marshal_get_delegate_invoke(_MonoMethod * method, _MonoDelegate * del) Line 2254
	at F:\netease-gitlab\dotnet\runtime\src\mono\mono\metadata\marshal.c(2254)
coreclr.dll!interp_entry(InterpEntryData * data) Line 2184
	at F:\netease-gitlab\dotnet\runtime\src\mono\mono\mini\interp\interp.c(2184)
coreclr.dll!interp_entry_static_ret_3(void * res, void * arg1, void * arg2, void * arg3, InterpMethod * rmethod) Line 2895
	at F:\netease-gitlab\dotnet\runtime\src\mono\mono\mini\interp\interp.c(2895)

@srxqds
Copy link
Contributor Author

srxqds commented Mar 23, 2023

@lambdageek @vargaz @BrzVlad can you take the time to check this?

@ghost
Copy link

ghost commented Mar 24, 2023

Tagging subscribers to this area: @BrzVlad, @kotlarmilos
See info in area-owners.md if you want to be subscribed.

Issue Details

Description

we embed mono, use jit mix with interp, use mono_jit_set_aot_mode(MONO_AOT_MODE_INTERP_ONLY);

we get MonoDelegate invoke method thunk and invoke it, it hit asset at line:

g_assert (sig->hasthis);

Reproduction Steps

// pass delegate from c# to c.
MonoDelegate* InDelegate;
MonoClass* DelegateClass = mono_object_get_class(InDelegate);

MonoMethod* InvokeMethod = mono_get_delegate_invoke(DelegateClass);

void * ThunkMethod = mono_method_get_unmanaged_thunk(InvokeMethod );
typedef bool(STDCALL ThunkWithMonoObjectDeclaration) (MonoObject, float, MonoObject**);
bool result = (ThunkWithMonoObjectDeclaration)ThunkMethod(InDelegate, 1, nullptr); // hit crash

it works well in aot_interp or jit mode.

Expected behavior

work correctly

Actual behavior

crash

Regression?

no

Known Workarounds

No response

Configuration

dotnet7.0.3 mono

Other information

No response

Author: srxqds
Assignees: -
Labels:

untriaged, area-Codegen-Interpreter-mono

Milestone: -

@srxqds
Copy link
Contributor Author

srxqds commented Mar 27, 2023

any idea about it?

@vargaz
Copy link
Contributor

vargaz commented Mar 27, 2023

It would be better to use normal apis like passing delegates directly to native code, Marshal.GetFunctionPointerForDelegate, [UnmanagedCallersOnly] etc.

@srxqds
Copy link
Contributor Author

srxqds commented Mar 29, 2023

got it, but hope you can take the time to fix this problem, make monovm more and more robust.

@steveisok steveisok removed the untriaged New issue has not been triaged by the area owner label Mar 30, 2023
@marek-safar marek-safar added this to the Future milestone Mar 31, 2023
@srxqds
Copy link
Contributor Author

srxqds commented Dec 4, 2023

internal class DelegateInvokeTests
{
	[MethodImpl(MethodImplOptions.InternalCall)]
	private static extern void InvokeDelegate(IntPtr d6);

	[Test("DelegateInvoke")]
	private static void Entry()
	{
		DelegateInvokeTests instance = new DelegateInvokeTests();
		var a = new Func<int>(instance.DelegateIntVoid);
		InvokeDelegate(Marshal.GetFunctionPointerForDelegate(a));
	}
	
	private int DelegateIntVoid() { return 0; }
}
// add internal call

mono_add_internal_call("DelegateInvokeTests::InvokeDelegate",  &InvokeDelegate);

void InvokeDelegate(void* InDelegate)
{
int (*Delegate)() = (int(*)())InDelegate;
int Result = Delegate();  // when execute this line will cause crash: 0xC0000005
}

I have try the above code in jit mode on win-x64 .net8.0.0 version, it will hit crash.

@vargaz can you help me?

@srxqds
Copy link
Contributor Author

srxqds commented Dec 5, 2023

I found the delegate function pointer signature is:

int (Delegate)(MonoObject) = (int()(MonoObject))InDelegate;

but we don't keep referenece the target in native side, so this solution is useless.

and the Marshal.GetFunctionPointerForDelegate not support multicastdelegate.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants