[mono][debugger] Remove cast bug (#86789)
authorIlona Tomkowicz <32700855+ilonatommy@users.noreply.github.com>
Fri, 26 May 2023 17:10:03 +0000 (19:10 +0200)
committerGitHub <noreply@github.com>
Fri, 26 May 2023 17:10:03 +0000 (19:10 +0200)
* Fix.

* Test standardization.

src/mono/wasm/debugger/BrowserDebugProxy/DebugStore.cs
src/mono/wasm/debugger/DebuggerTestSuite/MiscTests.cs
src/mono/wasm/debugger/tests/debugger-test/debugger-test.cs

index 2fcac98..c7c47ce 100644 (file)
@@ -389,31 +389,28 @@ namespace Microsoft.WebAssembly.Diagnostics
             this.IsEnCMethod = false;
             this.TypeInfo = type;
             DebuggerAttrInfo = new DebuggerAttributesInfo();
-            foreach (var cattr in methodDef.GetCustomAttributes())
+            foreach (CustomAttributeHandle cattr in methodDef.GetCustomAttributes())
             {
-                var ctorHandle = asmMetadataReader.GetCustomAttribute(cattr).Constructor;
-                if (ctorHandle.Kind == HandleKind.MemberReference)
+                if (!assembly.TryGetCustomAttributeName(cattr, asmMetadataReader, out string name))
+                    continue;
+
+                switch (name)
                 {
-                    var container = asmMetadataReader.GetMemberReference((MemberReferenceHandle)ctorHandle).Parent;
-                    var name = assembly.EnCGetString(asmMetadataReader.GetTypeReference((TypeReferenceHandle)container).Name);
-                    switch (name)
-                    {
-                        case "DebuggerHiddenAttribute":
-                            DebuggerAttrInfo.HasDebuggerHidden = true;
-                            break;
-                        case "DebuggerStepThroughAttribute":
-                            DebuggerAttrInfo.HasStepThrough = true;
-                            break;
-                        case "DebuggerNonUserCodeAttribute":
-                            DebuggerAttrInfo.HasNonUserCode = true;
-                            break;
-                        case "DebuggerStepperBoundaryAttribute":
-                            DebuggerAttrInfo.HasStepperBoundary = true;
-                            break;
-                        case nameof(CompilerGeneratedAttribute):
-                            IsCompilerGenerated = true;
-                            break;
-                    }
+                    case "DebuggerHiddenAttribute":
+                        DebuggerAttrInfo.HasDebuggerHidden = true;
+                        break;
+                    case "DebuggerStepThroughAttribute":
+                        DebuggerAttrInfo.HasStepThrough = true;
+                        break;
+                    case "DebuggerNonUserCodeAttribute":
+                        DebuggerAttrInfo.HasNonUserCode = true;
+                        break;
+                    case "DebuggerStepperBoundaryAttribute":
+                        DebuggerAttrInfo.HasStepperBoundary = true;
+                        break;
+                    case nameof(CompilerGeneratedAttribute):
+                        IsCompilerGenerated = true;
+                        break;
                 }
             }
             if (!hasDebugInformation)
@@ -788,13 +785,10 @@ namespace Microsoft.WebAssembly.Diagnostics
                 }
             }
 
-            foreach (var cattr in type.GetCustomAttributes())
+            foreach (CustomAttributeHandle cattr in type.GetCustomAttributes())
             {
-                var ctorHandle = metadataReader.GetCustomAttribute(cattr).Constructor;
-                if (ctorHandle.Kind != HandleKind.MemberReference)
+                if (!assembly.TryGetCustomAttributeName(cattr, metadataReader, out string attributeName))
                     continue;
-                var container = metadataReader.GetMemberReference((MemberReferenceHandle)ctorHandle).Parent;
-                var attributeName = assembly.EnCGetString(metadataReader.GetTypeReference((TypeReferenceHandle)container).Name);
                 switch (attributeName)
                 {
                     case nameof(CompilerGeneratedAttribute):
@@ -945,6 +939,33 @@ namespace Microsoft.WebAssembly.Diagnostics
             Populate();
         }
 
+        public bool TryGetCustomAttributeName(CustomAttributeHandle customAttribute, MetadataReader metadataReader, out string name)
+        {
+            name = "";
+            EntityHandle ctorHandle = metadataReader.GetCustomAttribute(customAttribute).Constructor;
+            if (ctorHandle.Kind != HandleKind.MemberReference)
+                return false;
+            EntityHandle? container = ctorHandle.Kind switch
+            {
+                HandleKind.MethodDefinition => metadataReader.GetMethodDefinition((MethodDefinitionHandle)ctorHandle).GetDeclaringType(),
+                HandleKind.MemberReference => metadataReader.GetMemberReference((MemberReferenceHandle)ctorHandle).Parent,
+                _ => null,
+            };
+            if (container == null)
+                return false;
+            StringHandle? attributeTypeNameHandle = container.Value.Kind switch
+            {
+                HandleKind.TypeDefinition => metadataReader.GetTypeDefinition((TypeDefinitionHandle)container.Value).Name,
+                HandleKind.TypeReference => metadataReader.GetTypeReference((TypeReferenceHandle)container.Value).Name,
+                HandleKind.TypeSpecification => null, // custom generic attributes, TypeSpecification does not keep the attribute name for them
+                _ => null,
+            };
+            if (attributeTypeNameHandle == null)
+                return false;
+            name = EnCGetString(attributeTypeNameHandle.Value);
+            return true;
+        }
+
         public async Task<int> GetDebugId(MonoSDBHelper sdbAgent, CancellationToken token)
         {
             if (debugId > 0)
@@ -1602,7 +1623,7 @@ namespace Microsoft.WebAssembly.Diagnostics
                 }
                 catch (Exception e)
                 {
-                    logger.LogError($"Failed to load {step.Url} ({e.Message})");
+                    logger.LogError($"Failed to load {step.Url} ({e.Message}) (stack={e.StackTrace})");
                 }
                 if (assembly == null)
                     continue;
index fed9b6a..1cea900 100644 (file)
@@ -1065,6 +1065,12 @@ namespace DebuggerTests
         [InlineData("ClassInheritsFromNonUserCodeClass", 1335, false)]
         [InlineData("ClassInheritsFromNonUserCodeClassThatInheritsFromNormalClass", 1352, true)]
         [InlineData("ClassInheritsFromNonUserCodeClassThatInheritsFromNormalClass", 1352, false)]
+        [InlineData("GenericCustomAttributeDecoratedClassInheritsFromClassWithoutDebugSymbols", 1618, true)]
+        [InlineData("GenericCustomAttributeDecoratedClassInheritsFromClassWithoutDebugSymbols", 1618, false)]
+        [InlineData("GenericCustomAttributeDecoratedClassInheritsFromNonUserCodeClass", 1635, true)]
+        [InlineData("GenericCustomAttributeDecoratedClassInheritsFromNonUserCodeClass", 1635, false)]
+        [InlineData("GenericCustomAttributeDecoratedClassInheritsFromNonUserCodeClassThatInheritsFromNormalClass", 1653, true)]
+        [InlineData("GenericCustomAttributeDecoratedClassInheritsFromNonUserCodeClassThatInheritsFromNormalClass", 1653, false)]
         public async Task InspectThisThatInheritsFromClassNonUserCode(string class_name, int line, bool jmc)
         {
             await SetJustMyCode(jmc);
index 9dca7f3..4a43032 100644 (file)
@@ -1600,3 +1600,59 @@ public class MultiThreadedTest
     }
 }
 
+[AttributeUsage(AttributeTargets.Class)]
+public sealed class CustomAttribute<TInterface> : Attribute
+{
+}
+
+[Custom<GenericCustomAttributeDecoratedClassInheritsFromClassWithoutDebugSymbols>]
+public class GenericCustomAttributeDecoratedClassInheritsFromClassWithoutDebugSymbols : DebuggerTests.ClassWithoutDebugSymbolsToInherit
+{
+    public static void Run()
+    {
+        var myVar = new GenericCustomAttributeDecoratedClassInheritsFromClassWithoutDebugSymbols();
+        myVar.CallMethod();
+    }
+
+    public void CallMethod()
+    {
+        System.Diagnostics.Debugger.Break();
+    }
+    public int myField2;
+    public int myField;
+}
+
+[Custom<GenericCustomAttributeDecoratedClassInheritsFromNonUserCodeClass>]
+public class GenericCustomAttributeDecoratedClassInheritsFromNonUserCodeClass : ClassNonUserCodeToInherit
+{
+    public static void Run()
+    {
+        var myVar = new GenericCustomAttributeDecoratedClassInheritsFromNonUserCodeClass();
+        myVar.CallMethod();
+    }
+
+    public void CallMethod()
+    {
+        System.Diagnostics.Debugger.Break();
+    }
+
+    public int myField2;
+    public int myField;
+}
+
+[Custom<GenericCustomAttributeDecoratedClassInheritsFromNonUserCodeClassThatInheritsFromNormalClass>]
+public class GenericCustomAttributeDecoratedClassInheritsFromNonUserCodeClassThatInheritsFromNormalClass : DebuggerTests.ClassNonUserCodeToInheritThatInheritsFromNormalClass
+{
+    public static void Run()
+    {
+        var myVar = new GenericCustomAttributeDecoratedClassInheritsFromNonUserCodeClassThatInheritsFromNormalClass();
+        myVar.CallMethod();
+    }
+
+    public void CallMethod()
+    {
+        System.Diagnostics.Debugger.Break();
+    }
+
+    public int myField;
+}