From 28c6142e642ed6035ce471da22f5243e2ed92f78 Mon Sep 17 00:00:00 2001 From: Martin Calsyn Date: Thu, 20 Sep 2018 15:23:22 -0700 Subject: [PATCH] Fix netmf issue 212 This fixes Issue #212 where VS crashes when hovering over a global var in a vb module. The fix here is to make sure that CorDebugClass responds correctly to calls to CorDebugClass.GetParameterizedType. Originally it should have returned E_NOTIMPL, but it returned OK and a null which is what causes the crash. This function is supposed to return full specified types derived from generic classes and wasn't implemented because netmf doesn't do generics, but it also gets called for classes with no specialization types when trying to create a type enclosure for Vb globals. Now, with this change, it returns a properly specialized type definition. The constructor had to be specialized to accommodate the fact debugger values known the appdomain, and type specializations need an assembly and type domain. --- Framework/CorDebug/CorDebugClass.cs | 2 +- Framework/CorDebug/CorDebugType.cs | 56 ++++++++++++++++++++++++++--- 2 files changed, 52 insertions(+), 6 deletions(-) diff --git a/Framework/CorDebug/CorDebugClass.cs b/Framework/CorDebug/CorDebugClass.cs index a033cb644..08ebd6c88 100644 --- a/Framework/CorDebug/CorDebugClass.cs +++ b/Framework/CorDebug/CorDebugClass.cs @@ -122,7 +122,7 @@ int ICorDebugClass. GetStaticFieldValue (uint fieldDef, ICorDebugFrame pFrame, o int ICorDebugClass2.GetParameterizedType( CorElementType elementType, uint nTypeArgs, ICorDebugType []ppTypeArgs, out ICorDebugType ppType ) { // CorDebugClass.GetParameterizedType is not implemented - ppType = null; + ppType = new CorDebugGenericType(elementType, null, this.Assembly); return Utility.COM_HResults.S_OK; } diff --git a/Framework/CorDebug/CorDebugType.cs b/Framework/CorDebug/CorDebugType.cs index 247c13cd4..657b2aabe 100644 --- a/Framework/CorDebug/CorDebugType.cs +++ b/Framework/CorDebug/CorDebugType.cs @@ -72,12 +72,23 @@ public class CorDebugGenericType : ICorDebugType CorElementType m_elemType; public RuntimeValue m_rtv; public CorDebugAppDomain m_appDomain; + private CorDebugAssembly m_assembly; + // This is used to resolve values into types when we know the appdomain, but not the assembly. public CorDebugGenericType(CorElementType elemType, RuntimeValue rtv, CorDebugAppDomain appDomain) - { + { + m_elemType = elemType; + m_rtv = rtv; + m_appDomain = appDomain; + } + + // This constructor is used exclusively for resovling potentially (but never really) generic classes into fully specified types. + // Generics are not supported by netmf, but we still need to be able to convert classes into fully specified types. + public CorDebugGenericType(CorElementType elemType, RuntimeValue rtv, CorDebugAssembly assembly) + { m_elemType = elemType; m_rtv = rtv; - m_appDomain = appDomain; + m_assembly = assembly; } int ICorDebugType.EnumerateTypeParameters(out ICorDebugTypeEnum ppTyParEnum) @@ -102,7 +113,7 @@ int ICorDebugType.GetRank(out uint pnRank) int ICorDebugType.GetClass(out ICorDebugClass ppClass) { - ppClass = CorDebugValue.ClassFromRuntimeValue(m_rtv, m_appDomain); + ppClass = CorDebugValue.ClassFromRuntimeValue(m_rtv, this.AppDomain); return Utility.COM_HResults.S_OK; } @@ -115,8 +126,12 @@ int ICorDebugType.GetFirstTypeParameter(out ICorDebugType value) int ICorDebugType.GetStaticFieldValue(uint fieldDef, ICorDebugFrame pFrame, out ICorDebugValue ppValue) { - ppValue = null; - return Utility.COM_HResults.E_NOTIMPL; + uint fd = TinyCLR_TypeSystem.ClassMemberIndexFromCLRToken(fieldDef, this.Assembly); + this.Process.SetCurrentAppDomain(this.AppDomain); + RuntimeValue rtv = this.Engine.GetStaticFieldValue(fd); + ppValue = CorDebugValue.CreateValue(rtv, this.AppDomain); + + return Utility.COM_HResults.S_OK; } int ICorDebugType.GetBase(out ICorDebugType pBase) @@ -124,5 +139,36 @@ int ICorDebugType.GetBase(out ICorDebugType pBase) pBase = null; return Utility.COM_HResults.E_NOTIMPL; } + + public CorDebugAssembly Assembly + { + [System.Diagnostics.DebuggerHidden] + get { return m_assembly; } + } + + public Engine Engine + { + [System.Diagnostics.DebuggerHidden] + get { return this.Process?.Engine; } + } + + public CorDebugProcess Process + { + [System.Diagnostics.DebuggerHidden] + get { return this.Assembly?.Process; } + } + + public CorDebugAppDomain AppDomain + { + [System.Diagnostics.DebuggerHidden] + get + { + if (m_appDomain != null) + return m_appDomain; + else + return this.Assembly?.AppDomain; + } + } + } }