internal abstract EvaluationContextBase CreateMethodContext(
     DkmClrAppDomain appDomain,
     ImmutableArray <MetadataBlock> metadataBlocks,
     Lazy <ImmutableArray <AssemblyReaders> > lazyAssemblyReaders,
     object symReader,
     Guid moduleVersionId,
     int methodToken,
     int methodVersion,
     uint ilOffset,
     int localSignatureToken,
     bool useReferencedModulesOnly);
예제 #2
0
        private static TypeAndCustomInfo GetTupleFieldTypeAndInfo(
            DkmClrAppDomain appDomain,
            FieldInfo field,
            CustomTypeInfoTypeArgumentMap customTypeInfoMap)
        {
            var declaringTypeDef = field.DeclaringType.GetGenericTypeDefinition();
            var fieldDef         = declaringTypeDef.GetTupleField(field.Name);
            var fieldType        = DkmClrType.Create(appDomain, field.FieldType);
            var fieldTypeInfo    = customTypeInfoMap.SubstituteCustomTypeInfo(fieldDef.FieldType, null);

            return(new TypeAndCustomInfo(fieldType, fieldTypeInfo));
        }
예제 #3
0
        private static DkmClrModuleInstance GetModule(DkmClrAppDomain appDomain, string moduleName)
        {
            var modules = appDomain.GetClrModuleInstances();

            foreach (var module in modules)
            {
                if (string.Equals(module.Name, moduleName, StringComparison.OrdinalIgnoreCase))
                {
                    return(module);
                }
            }
            return(null);
        }
예제 #4
0
        internal static ImmutableArray <MetadataBlock> GetMetadataBlocks(
            this DkmClrRuntimeInstance runtime,
            DkmClrAppDomain appDomain,
            ImmutableArray <MetadataBlock> previousMetadataBlocks
            )
        {
            // Add a dummy data item to the appdomain to add it to the disposal queue when the debugged process is shutting down.
            // This should prevent from attempts to use the Metadata pointer for dead debugged processes.
            if (appDomain.GetDataItem <AppDomainLifetimeDataItem>() == null)
            {
                appDomain.SetDataItem(
                    DkmDataCreationDisposition.CreateNew,
                    new AppDomainLifetimeDataItem()
                    );
            }

            var builder = ArrayBuilder <MetadataBlock> .GetInstance();

            IntPtr ptr;
            uint   size;
            int    index = 0;

            foreach (DkmClrModuleInstance module in runtime.GetModulesInAppDomain(appDomain))
            {
                MetadataBlock block;
                try
                {
                    ptr = module.GetMetaDataBytesPtr(out size);
                    Debug.Assert(size > 0);
                    block = GetMetadataBlock(previousMetadataBlocks, index, ptr, size);
                }
                catch (NotImplementedException e) when(module is DkmClrNcModuleInstance)
                {
                    // DkmClrNcModuleInstance.GetMetaDataBytesPtr not implemented in Dev14.
                    throw new NotImplementedMetadataException(e);
                }
                catch (Exception e) when(DkmExceptionUtilities.IsBadOrMissingMetadataException(e))
                {
                    continue;
                }
                Debug.Assert(block.ModuleVersionId == module.Mvid);
                builder.Add(block);
                index++;
            }
            // Include "intrinsic method" assembly.
            ptr = runtime.GetIntrinsicAssemblyMetaDataBytesPtr(out size);
            builder.Add(GetMetadataBlock(previousMetadataBlocks, index, ptr, size));
            return(builder.ToImmutableAndFree());
        }
예제 #5
0
 internal override EvaluationContextBase CreateTypeContext(
     DkmClrAppDomain appDomain,
     ImmutableArray <MetadataBlock> metadataBlocks,
     Guid moduleVersionId,
     int typeToken,
     bool useReferencedModulesOnly)
 {
     return(CreateTypeContext(
                appDomain,
                ad => ad.GetMetadataContext <CSharpMetadataContext>(),
                metadataBlocks,
                moduleVersionId,
                typeToken,
                GetMakeAssemblyReferencesKind(useReferencedModulesOnly)));
 }
예제 #6
0
        private TResult CompileWithRetry <TResult>(
            DkmClrAppDomain appDomain,
            DkmClrRuntimeInstance runtimeInstance,
            CreateContextDelegate createContext,
            CompileDelegate <TResult> compile,
            out string errorMessage)
        {
            var metadataBlocks = GetMetadataBlocks(appDomain, runtimeInstance);

            return(CompileWithRetry(
                       metadataBlocks,
                       this.DiagnosticFormatter,
                       createContext,
                       compile,
                       (AssemblyIdentity assemblyIdentity, out uint size) => appDomain.GetMetaDataBytesPtr(assemblyIdentity.GetDisplayName(), out size),
                       out errorMessage));
        }
예제 #7
0
 internal static void SetMetadataContext <TAssemblyContext>(this DkmClrAppDomain appDomain, MetadataContext <TAssemblyContext> context, bool report)
     where TAssemblyContext : struct
 {
     if (report)
     {
         var process = appDomain.Process;
         var message = DkmUserMessage.Create(
             process.Connection,
             process,
             DkmUserMessageOutputKind.UnfilteredOutputWindowMessage,
             $"EE: AppDomain {appDomain.Id}, blocks {context.MetadataBlocks.Length}, contexts {context.AssemblyContexts.Count}" + Environment.NewLine,
             MessageBoxFlags.MB_OK,
             0);
         message.Post();
     }
     appDomain.SetDataItem(DkmDataCreationDisposition.CreateAlways, new MetadataContextItem <MetadataContext <TAssemblyContext> >(context));
 }
예제 #8
0
        internal override EvaluationContextBase CreateMethodContext(
            DkmClrAppDomain appDomain,
            ImmutableArray <MetadataBlock> metadataBlocks,
            Lazy <ImmutableArray <AssemblyReaders> > unusedLazyAssemblyReaders,
            object symReader,
            Guid moduleVersionId,
            int methodToken,
            int methodVersion,
            uint ilOffset,
            int localSignatureToken,
            bool useReferencedModulesOnly)
        {
            if (useReferencedModulesOnly)
            {
                // Avoid using the cache for referenced assemblies only
                // since this should be the exceptional case.
                var compilation = metadataBlocks.ToCompilationReferencedModulesOnly(moduleVersionId);
                return(EvaluationContext.CreateMethodContext(
                           compilation,
                           symReader,
                           moduleVersionId,
                           methodToken,
                           methodVersion,
                           ilOffset,
                           localSignatureToken));
            }

            var previous = appDomain.GetMetadataContext <CSharpMetadataContext>();
            var context  = EvaluationContext.CreateMethodContext(
                previous,
                metadataBlocks,
                symReader,
                moduleVersionId,
                methodToken,
                methodVersion,
                ilOffset,
                localSignatureToken);

            if (context != previous.EvaluationContext)
            {
                appDomain.SetMetadataContext(new CSharpMetadataContext(metadataBlocks, context));
            }

            return(context);
        }
예제 #9
0
        internal static Type GetBaseTypeOrNull(
            this Type underlyingType,
            DkmClrAppDomain appDomain,
            out DkmClrType type
            )
        {
            Debug.Assert(
                (underlyingType.BaseType != null) ||
                underlyingType.IsPointer ||
                underlyingType.IsArray,
                "BaseType should only return null if the underlyingType is a pointer or array."
                );

            underlyingType = underlyingType.BaseType;
            type           = (underlyingType != null) ? DkmClrType.Create(appDomain, underlyingType) : null;

            return(underlyingType);
        }
        internal override EvaluationContextBase CreateTypeContext(
            DkmClrAppDomain appDomain,
            ImmutableArray <MetadataBlock> metadataBlocks,
            Guid moduleVersionId,
            int typeToken)
        {
            var previous = appDomain.GetDataItem <CSharpMetadataContext>();
            var context  = EvaluationContext.CreateTypeContext(
                appDomain.GetDataItem <CSharpMetadataContext>(),
                metadataBlocks,
                moduleVersionId,
                typeToken);

            // New type context is not attached to the AppDomain since it is less
            // re-usable than the previous attached method context. (We could hold
            // on to it if we don't have a previous method context but it's unlikely
            // that we evaluated a type-level expression before a method-level.)
            Debug.Assert(previous == null || context != previous.EvaluationContext);

            return(context);
        }
예제 #11
0
        internal static ImmutableArray <MetadataBlock> GetMetadataBlocks(
            this DkmClrRuntimeInstance runtime,
            DkmClrAppDomain appDomain,
            ImmutableArray <MetadataBlock> previousMetadataBlocks)
        {
            var builder = ArrayBuilder <MetadataBlock> .GetInstance();

            IntPtr ptr;
            uint   size;
            int    index = 0;

            foreach (DkmClrModuleInstance module in runtime.GetModulesInAppDomain(appDomain))
            {
                MetadataBlock block;
                try
                {
                    ptr = module.GetMetaDataBytesPtr(out size);
                    Debug.Assert(size > 0);
                    block = GetMetadataBlock(previousMetadataBlocks, index, ptr, size);
                }
                catch (NotImplementedException e) when(module is DkmClrNcModuleInstance)
                {
                    // DkmClrNcModuleInstance.GetMetaDataBytesPtr not implemented in Dev14.
                    throw new NotImplementedMetadataException(e);
                }
                catch (Exception e) when(DkmExceptionUtilities.IsBadOrMissingMetadataException(e))
                {
                    continue;
                }
                Debug.Assert(block.ModuleVersionId == module.Mvid);
                builder.Add(block);
                index++;
            }
            // Include "intrinsic method" assembly.
            ptr = runtime.GetIntrinsicAssemblyMetaDataBytesPtr(out size);
            builder.Add(GetMetadataBlock(previousMetadataBlocks, index, ptr, size));
            return(builder.ToImmutableAndFree());
        }
예제 #12
0
        private static IEnumerable <DkmClrModuleInstance> GetModulesInAppDomain(this DkmProcess process, DkmClrAppDomain appDomain)
        {
            var appDomainId = appDomain.Id;

            return(process.GetRuntimeInstances().
                   OfType <DkmClrRuntimeInstance>().
                   SelectMany(runtime => runtime.GetModuleInstances()).
                   Cast <DkmClrModuleInstance>().
                   Where(module => module.AppDomain.Id == appDomainId));
        }
예제 #13
0
        internal override ImmutableArray <MetadataBlock> GetMetadataBlocks(DkmClrAppDomain appDomain, DkmClrRuntimeInstance runtimeInstance)
        {
            var previous = appDomain.GetMetadataContext <CSharpMetadataContext>();

            return(runtimeInstance.GetMetadataBlocks(appDomain, previous.MetadataBlocks));
        }
예제 #14
0
        internal unsafe static ImmutableArray <MetadataBlock> GetMetadataBlocks(this DkmProcess process, DkmClrAppDomain appDomain)
        {
            var builder = ArrayBuilder <MetadataBlock> .GetInstance();

            foreach (DkmClrModuleInstance module in process.GetModulesInAppDomain(appDomain))
            {
                int            size;
                IntPtr         ptr;
                MetadataReader reader;
                if (module.TryGetMetadataReader(out ptr, out size, out reader))
                {
                    var moduleDef       = reader.GetModuleDefinition();
                    var moduleVersionId = reader.GetGuid(moduleDef.Mvid);
                    var generationId    = reader.GetGuid(moduleDef.GenerationId);
                    Debug.Assert(moduleVersionId == module.Mvid);
                    builder.Add(new MetadataBlock(moduleVersionId, generationId, ptr, size));
                }
            }
            return(builder.ToImmutableAndFree());
        }
예제 #15
0
        internal static MetadataContext <TAssemblyContext> GetMetadataContext <TAssemblyContext>(this DkmClrAppDomain appDomain)
            where TAssemblyContext : struct
        {
            var dataItem = appDomain.GetDataItem <MetadataContextItem <MetadataContext <TAssemblyContext> > >();

            return((dataItem == null) ? default : dataItem.MetadataContext);
        }
예제 #16
0
 internal abstract string GetArrayDisplayString(DkmClrAppDomain appDomain, Type lmrType, ReadOnlyCollection <int> sizes, ReadOnlyCollection <int> lowerBounds, ObjectDisplayOptions options);
예제 #17
0
 internal static void RemoveMetadataContext <TMetadataContext>(this DkmClrAppDomain appDomain)
     where TMetadataContext : struct
 {
     appDomain.RemoveDataItem <MetadataContextItem <TMetadataContext> >();
 }
예제 #18
0
        // Return the set of managed module instances from the AppDomain.
        private static IEnumerable <DkmClrModuleInstance> GetModulesInAppDomain(this DkmClrRuntimeInstance runtime, DkmClrAppDomain appDomain)
        {
            if (appDomain.IsUnloaded)
            {
                return(SpecializedCollections.EmptyEnumerable <DkmClrModuleInstance>());
            }

            var appDomainId = appDomain.Id;

            // GetModuleInstances() may include instances of DkmClrNcContainerModuleInstance
            // which are containers of managed module instances (see GetEmbeddedModules())
            // but not managed modules themselves. Since GetModuleInstances() will include the
            // embedded modules, we can simply ignore DkmClrNcContainerModuleInstances.
            return(runtime.GetModuleInstances().
                   OfType <DkmClrModuleInstance>().
                   Where(module =>
            {
                var moduleAppDomain = module.AppDomain;
                return !moduleAppDomain.IsUnloaded && (moduleAppDomain.Id == appDomainId);
            }));
        }
예제 #19
0
 internal abstract ImmutableArray <MetadataBlock> GetMetadataBlocks(
     DkmClrAppDomain appDomain,
     DkmClrRuntimeInstance runtimeInstance);
예제 #20
0
        private static IEnumerable <DkmClrModuleInstance> GetModulesInAppDomain(this DkmClrRuntimeInstance runtime, DkmClrAppDomain appDomain)
        {
            var appDomainId = appDomain.Id;

            return(runtime.GetModuleInstances().
                   Cast <DkmClrModuleInstance>().
                   Where(module => module.AppDomain.Id == appDomainId));
        }
예제 #21
0
 internal abstract bool RemoveDataItem(DkmClrAppDomain appDomain);
예제 #22
0
 internal abstract EvaluationContextBase CreateTypeContext(
     DkmClrAppDomain appDomain,
     ImmutableArray <MetadataBlock> metadataBlocks,
     Guid moduleVersionId,
     int typeToken);
예제 #23
0
 internal abstract void RemoveDataItem(DkmClrAppDomain appDomain);
예제 #24
0
 internal override void RemoveDataItem(DkmClrAppDomain appDomain)
 {
     appDomain.RemoveMetadataContext <CSharpMetadataContext>();
 }
예제 #25
0
        private static IEnumerable <DkmClrModuleInstance> GetModulesInAppDomain(this DkmClrRuntimeInstance runtime, DkmClrAppDomain appDomain)
        {
            if (appDomain.IsUnloaded)
            {
                return(SpecializedCollections.EmptyEnumerable <DkmClrModuleInstance>());
            }

            var appDomainId = appDomain.Id;

            return(runtime.GetModuleInstances().
                   // Ignore module instances that are not DkmClrModuleInstance.
                   // Specifically, ignore DkmClrNcContainerModuleInstance.
                   // (The embedded DkmClrNcModuleInstance modules will
                   // be included in GetModuleInstances and will be used.)
                   OfType <DkmClrModuleInstance>().
                   Where(module =>
            {
                var moduleAppDomain = module.AppDomain;
                return !moduleAppDomain.IsUnloaded && (moduleAppDomain.Id == appDomainId);
            }));
        }
예제 #26
0
        internal static void AppendTypeMembers(
            this Type type,
            ArrayBuilder <MemberAndDeclarationInfo> includedMembers,
            Predicate <MemberInfo> predicate,
            Type declaredType,
            DkmClrAppDomain appDomain,
            bool includeInherited,
            bool hideNonPublic)
        {
            Debug.Assert(!type.IsInterface);

            var memberLocation         = DeclarationInfo.FromSubTypeOfDeclaredType;
            var previousDeclarationMap = includeInherited ? new Dictionary <string, DeclarationInfo>() : null;

            int inheritanceLevel = 0;

            while (!type.IsObject())
            {
                if (type.Equals(declaredType))
                {
                    Debug.Assert(memberLocation == DeclarationInfo.FromSubTypeOfDeclaredType);
                    memberLocation = DeclarationInfo.FromDeclaredTypeOrBase;
                }

                // Get the state from DebuggerBrowsableAttributes for the members of the current type.
                var browsableState = DkmClrType.Create(appDomain, type).GetDebuggerBrowsableAttributeState();

                // Hide non-public members if hideNonPublic is specified (intended to reflect the
                // DkmInspectionContext's DkmEvaluationFlags), and the type is from an assembly
                // with no symbols.
                var hideNonPublicBehavior = DeclarationInfo.None;
                if (hideNonPublic)
                {
                    var moduleInstance = appDomain.FindClrModuleInstance(type.Module.ModuleVersionId);
                    if (moduleInstance == null || moduleInstance.Module == null)
                    {
                        // Synthetic module or no symbols loaded.
                        hideNonPublicBehavior = DeclarationInfo.HideNonPublic;
                    }
                }

                foreach (var member in type.GetMembers(MemberBindingFlags))
                {
                    if (!predicate(member))
                    {
                        continue;
                    }

                    var memberName = member.Name;
                    // This represents information about the immediately preceding (more derived)
                    // declaration with the same name as the current member.
                    var previousDeclaration   = DeclarationInfo.None;
                    var memberNameAlreadySeen = false;
                    if (includeInherited)
                    {
                        memberNameAlreadySeen = previousDeclarationMap.TryGetValue(memberName, out previousDeclaration);
                        if (memberNameAlreadySeen)
                        {
                            // There was a name conflict, so we'll need to include the declaring
                            // type of the member to disambiguate.
                            previousDeclaration |= DeclarationInfo.IncludeTypeInMemberName;
                        }

                        // Update previous member with name hiding (casting) and declared location information for next time.
                        previousDeclarationMap[memberName] =
                            (previousDeclaration & ~(DeclarationInfo.RequiresExplicitCast |
                                                     DeclarationInfo.FromSubTypeOfDeclaredType)) |
                            member.AccessingBaseMemberWithSameNameRequiresExplicitCast() |
                            memberLocation;
                    }

                    Debug.Assert(memberNameAlreadySeen != (previousDeclaration == DeclarationInfo.None));

                    // Decide whether to include this member in the list of members to display.
                    if (!memberNameAlreadySeen || previousDeclaration.IsSet(DeclarationInfo.RequiresExplicitCast))
                    {
                        DkmClrDebuggerBrowsableAttributeState?browsableStateValue = null;
                        if (browsableState != null)
                        {
                            DkmClrDebuggerBrowsableAttributeState value;
                            if (browsableState.TryGetValue(memberName, out value))
                            {
                                browsableStateValue = value;
                            }
                        }

                        if (memberLocation.IsSet(DeclarationInfo.FromSubTypeOfDeclaredType))
                        {
                            // If the current type is a sub-type of the declared type, then
                            // we always need to insert a cast to access the member
                            previousDeclaration |= DeclarationInfo.RequiresExplicitCast;
                        }
                        else if (previousDeclaration.IsSet(DeclarationInfo.FromSubTypeOfDeclaredType))
                        {
                            // If the immediately preceding member (less derived) was
                            // declared on a sub-type of the declared type, then we'll
                            // ignore the casting bit.  Accessing a member through the
                            // declared type is the same as casting to that type, so
                            // the cast would be redundant.
                            previousDeclaration &= ~DeclarationInfo.RequiresExplicitCast;
                        }

                        previousDeclaration |= hideNonPublicBehavior;

                        includedMembers.Add(new MemberAndDeclarationInfo(member, browsableStateValue, previousDeclaration, inheritanceLevel));
                    }
                }

                if (!includeInherited)
                {
                    break;
                }

                type = type.BaseType;
                inheritanceLevel++;
            }

            includedMembers.Sort(MemberAndDeclarationInfo.Comparer);
        }
예제 #27
0
 internal static void SetMetadataContext <TMetadataContext>(this DkmClrAppDomain appDomain, TMetadataContext context)
     where TMetadataContext : struct
 {
     appDomain.SetDataItem(DkmDataCreationDisposition.CreateAlways, new MetadataContextItem <TMetadataContext>(context));
 }
 internal override bool RemoveDataItem(DkmClrAppDomain appDomain)
 {
     return(appDomain.RemoveDataItem <CSharpMetadataContext>());
 }
예제 #29
0
        internal unsafe static ImmutableArray <MetadataBlock> GetMetadataBlocks(this DkmClrRuntimeInstance runtime, DkmClrAppDomain appDomain)
        {
            var builder = ArrayBuilder <MetadataBlock> .GetInstance();

            IntPtr ptr;
            uint   size;

            foreach (DkmClrModuleInstance module in runtime.GetModulesInAppDomain(appDomain))
            {
                MetadataBlock block;
                try
                {
                    ptr   = module.GetMetaDataBytesPtr(out size);
                    block = GetMetadataBlock(ptr, size);
                }
                catch (Exception e) when(MetadataUtilities.IsBadOrMissingMetadataException(e, module.FullName))
                {
                    continue;
                }
                Debug.Assert(block.ModuleVersionId == module.Mvid);
                builder.Add(block);
            }
            // Include "intrinsic method" assembly.
            ptr = runtime.GetIntrinsicAssemblyMetaDataBytesPtr(out size);
            builder.Add(GetMetadataBlock(ptr, size));
            return(builder.ToImmutableAndFree());
        }
예제 #30
0
        private static IEnumerable <DkmClrModuleInstance> GetModulesInAppDomain(this DkmClrRuntimeInstance runtime, DkmClrAppDomain appDomain)
        {
            if (appDomain.IsUnloaded)
            {
                return(SpecializedCollections.EmptyEnumerable <DkmClrModuleInstance>());
            }

            var appDomainId = appDomain.Id;

            return(runtime.GetModuleInstances().
                   Cast <DkmClrModuleInstance>().
                   Where(module =>
            {
                var moduleAppDomain = module.AppDomain;
                return !moduleAppDomain.IsUnloaded && (moduleAppDomain.Id == appDomainId);
            }));
        }