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] Include dynamic methods in stacktrace #72732

Merged
merged 1 commit into from
Jul 25, 2022

Conversation

BrzVlad
Copy link
Member

@BrzVlad BrzVlad commented Jul 24, 2022

Same as coreclr. Some tests check call path by looking up method names in the stacktrace.

@BrzVlad
Copy link
Member Author

BrzVlad commented Jul 24, 2022

For simple testcase:

using System;
using System.Reflection;
using System.Reflection.Emit;

public class Program {

        public static void Throw ()
        {
                throw new Exception ("TEST");
        }

        public static DynamicMethod CreateDynamicMethod ()
        {
                DynamicMethod dynMethod = new DynamicMethod("my_dynamic_method", null, null);
                ILGenerator gen = dynMethod.GetILGenerator();
                MethodInfo throwMethod = typeof(Program).GetMethod("Throw", new Type [] { });
                gen.EmitWriteLine("Hello");
                gen.Emit(OpCodes.Call, throwMethod);
                gen.Emit(OpCodes.Ret);
                return dynMethod;
        }

        public static void Main (string[] args)
        {
                DynamicMethod dynMethod = CreateDynamicMethod ();
                dynMethod.Invoke(null, null);
        }
}

CoreCLR output

Hello
Unhandled exception. System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.
 ---> System.Exception: TEST
   at Program.Throw() in /home/vbrezae/Xamarin/tests/ilemit/Program.cs:line 9
   at my_dynamic_method()
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
   at System.Reflection.MethodInvoker.Invoke(Object obj, IntPtr* args, BindingFlags invokeAttr)
   --- End of inner exception stack trace ---
   at System.Reflection.MethodInvoker.Invoke(Object obj, IntPtr* args, BindingFlags invokeAttr)
   at System.Reflection.Emit.DynamicMethod.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at Program.Main(String[] args) in /home/vbrezae/Xamarin/tests/ilemit/Program.cs:line 25

Mono output before change

Hello
Unhandled Exception:
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.
 ---> System.Exception: TEST
   at Program.Throw() in /home/vbrezae/Xamarin/tests/ilemit/Program.cs:line 9
   at System.Reflection.MethodInvoker.InterpretedInvoke(Object obj, Span`1 args, BindingFlags invokeAttr) in /home/vbrezae/Xamarin/repos/runtime3/src/mono/System.Private.CoreLib/src/System/Reflection/MethodInvoker.Mono.cs:line 33
   --- End of inner exception stack trace ---
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) in /home/vbrezae/Xamarin/repos/runtime3/src/libraries/System.Private.CoreLib/src/System/Reflection/RuntimeMethodInfo.cs:line 131
   at System.Reflection.Emit.DynamicMethod.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) in /home/vbrezae/Xamarin/repos/runtime3/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/DynamicMethod.cs:line 326
   at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters) in /home/vbrezae/Xamarin/repos/runtime3/src/libraries/System.Private.CoreLib/src/System/Reflection/MethodBase.cs:line 54
   at Program.Main(String[] args) in /home/vbrezae/Xamarin/tests/ilemit/Program.cs:line 26

Mono output after change

Hello
Unhandled Exception:
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.
 ---> System.Exception: TEST
   at Program.Throw() in /home/vbrezae/Xamarin/tests/ilemit/Program.cs:line 9
   at System.Object.my_dynamic_method()
   at System.Reflection.MethodInvoker.InterpretedInvoke(Object obj, Span`1 args, BindingFlags invokeAttr) in /home/vbrezae/Xamarin/repos/runtime3/src/mono/System.Private.CoreLib/src/System/Reflection/MethodInvoker.Mono.cs:line 33
   --- End of inner exception stack trace ---
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) in /home/vbrezae/Xamarin/repos/runtime3/src/libraries/System.Private.CoreLib/src/System/Reflection/RuntimeMethodInfo.cs:line 131
   at System.Reflection.Emit.DynamicMethod.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) in /home/vbrezae/Xamarin/repos/runtime3/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/DynamicMethod.cs:line 326
   at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters) in /home/vbrezae/Xamarin/repos/runtime3/src/libraries/System.Private.CoreLib/src/System/Reflection/MethodBase.cs:line 54
   at Program.Main(String[] args) in /home/vbrezae/Xamarin/tests/ilemit/Program.cs:line 26

@BrzVlad
Copy link
Member Author

BrzVlad commented Jul 24, 2022

@AndyAyersMS On this small test case I noticed some crazy behavior (worth mentioning that I'm building this testcase in Release). If I set DOTNET_JitNoInline=1, then my_dynamic_method no longer shows in the stacktrace. Any idea why this happens ?

EDIT: Never mind, it's probably just a tailcall optimization.

@jkotas
Copy link
Member

jkotas commented Jul 24, 2022

System.Object.my_dynamic_method()

System.Object. in the name does not look right. Can it be omitted?

@BrzVlad
Copy link
Member Author

BrzVlad commented Jul 24, 2022

@jkotas The type is shown correctly if we pass the owner type to DynamicMethod ctor. However, in mono, we seem to make the assumption that all methods have a declaring type (object by default for dynamic methods without owner) and changing this seems fairly challenging and out of the scope of this PR.

@BrzVlad BrzVlad merged commit 9a0b8f3 into dotnet:main Jul 25, 2022
@ghost ghost locked as resolved and limited conversation to collaborators Aug 24, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants