private static void ForEachLocalVariableRecursive(
            ISymUnmanagedScope scope,
            int offset,
            bool isScopeEndInclusive,
            Action<ISymUnmanagedVariable> action)
        {
            Debug.Assert(offset < 0 || scope.IsInScope(offset, isScopeEndInclusive));

            // apply action on locals of the current scope:
            foreach (var local in scope.GetLocals())
            {
                action(local);
            }

            // recurse:
            foreach (var child in scope.GetChildren())
            {
                if (offset < 0 || child.IsInScope(offset, isScopeEndInclusive))
                {
                    ForEachLocalVariableRecursive(child, offset, isScopeEndInclusive, action);
                    if (offset >= 0)
                    {
                        return;
                    }
                }
            }
        }
Beispiel #2
0
        public ISymbolVariable[] GetLocals()
        {
            int count;

            m_target.GetLocals(0, out count, null);
            ISymUnmanagedVariable[] uVariables = new ISymUnmanagedVariable[count];
            m_target.GetLocals(count, out count, uVariables);

            int i;

            ISymbolVariable[] variables = new ISymbolVariable[count];
            for (i = 0; i < count; i++)
            {
                variables[i] = new SymVariable(uVariables[i]);
            }
            return(variables);
        }
        public ISymbolVariable[] GetLocals()
        {
            int size;

            HRESULT.ThrowOnFailure(_unmanaged.GetLocals(0, out size, null));

            var unmanagedVars = new ISymUnmanagedVariable[size];

            HRESULT.ThrowOnFailure(_unmanaged.GetLocals(unmanagedVars.Length, out size, unmanagedVars));

            var variables = new ISymbolVariable[size];

            for (int i = 0; i < size; i++)
            {
                variables[i] = new SymbolVariable(unmanagedVars[i]);
            }

            return(variables);
        }
Beispiel #4
0
        private List <DebugLocalVariableInfo> GetLocalVariablesInScope(ISymUnmanagedScope symScope)
        {
            List <DebugLocalVariableInfo> vars = new List <DebugLocalVariableInfo>();

            foreach (ISymUnmanagedVariable symVar in symScope.GetLocals())
            {
                ISymUnmanagedVariable symVarCopy = symVar;
                int                       start;
                SignatureReader           sigReader  = new SignatureReader(symVar.GetSignature());
                LocalVarSig.LocalVariable locVarSig  = sigReader.ReadLocalVariable(sigReader.Blob, 0, out start);
                DebugType                 locVarType = DebugType.CreateFromSignature(this.DebugModule, locVarSig.Type, declaringType);
                // Compiler generated?
                // NB: Display class does not have the compiler-generated flag
                if ((symVar.GetAttributes() & 1) == 1 || symVar.GetName().StartsWith("CS$"))
                {
                    // Get display class from local variable
                    if (locVarType.IsDisplayClass)
                    {
                        AddCapturedLocalVariables(
                            vars,
                            (int)symScope.GetStartOffset(),
                            (int)symScope.GetEndOffset(),
                            delegate(StackFrame context)
                        {
                            return(GetLocalVariableValue(context, symVarCopy));
                        },
                            locVarType
                            );
                    }
                }
                else
                {
                    DebugLocalVariableInfo locVar = new DebugLocalVariableInfo(
                        symVar.GetName(),
                        (int)symVar.GetAddressField1(),
                        // symVar also has Get*Offset methods, but the are not implemented
                        (int)symScope.GetStartOffset(),
                        (int)symScope.GetEndOffset(),
                        locVarType,
                        delegate(StackFrame context)
                    {
                        return(GetLocalVariableValue(context, symVarCopy));
                    }
                        );
                    vars.Add(locVar);
                }
            }
            foreach (ISymUnmanagedScope childScope in symScope.GetChildren())
            {
                vars.AddRange(GetLocalVariablesInScope(childScope));
            }

            return(vars);
        }
Beispiel #5
0
        private static void ForEachLocalVariableRecursive(
            ISymUnmanagedScope scope,
            int offset,
            ref ISymUnmanagedVariable[] localsBuffer,
            Action <ISymUnmanagedVariable> action)
        {
            Debug.Assert((offset < 0) || scope.IsInScope(offset));

            // apply action on locals of the current scope:

            int localCount;

            scope.GetLocalCount(out localCount);

            if (localCount > 0)
            {
                EnsureBufferSize(ref localsBuffer, localCount);
                scope.GetLocals(localCount, out localCount, localsBuffer);

                for (int i = 0; i < localCount; i++)
                {
                    action(localsBuffer[i]);
                }
            }

            // recurse:

            int childCount;

            scope.GetChildren(0, out childCount, null);

            if (childCount > 0)
            {
                var children = new ISymUnmanagedScope[childCount];
                scope.GetChildren(childCount, out childCount, children);

                foreach (var child in children)
                {
                    if ((offset < 0) || child.IsInScope(offset))
                    {
                        ForEachLocalVariableRecursive(child, offset, ref localsBuffer, action);
                        if (offset >= 0)
                        {
                            return;
                        }
                    }
                }
            }
        }
Beispiel #6
0
 /// <summary>
 /// Get definitions of local variables in scope.
 /// </summary>
 /// <param name="scope">Interface refering to desired scope.</param>
 /// <param name="index">Index pointing to the last read variable.</param>
 /// <param name="definitions">List of definitions, where found variable definition are placed.</param>
 private void getDefinitionsForScope(ISymUnmanagedScope scope, ref int index, List <LocalVarDefinition> definitions)
 {
     ISymUnmanagedVariable[] variables = scope.GetLocals();
     foreach (ISymUnmanagedVariable var in variables)
     {
         LocalVarDefinition def = new LocalVarDefinition();
         def.ilStart   = scope.GetStartOffset();
         def.ilEnd     = scope.GetEndOffset();
         def.name      = var.GetName();
         def.signature = var.GetSignature();
         definitions.Add(def);
         ++index;
     }
     foreach (ISymUnmanagedScope cScope in scope.GetChildren())
     {
         getDefinitionsForScope(cScope, ref index, definitions);
     }
 }
        //
        // Gather the local details in a scope and then recurse to child scopes
        //
        private void ProbeScopeForLocals(List <LocalVariable> variables, ISymUnmanagedScope scope)
        {
            int localCount;

            ThrowExceptionForHR(scope.GetLocalCount(out localCount));

            ISymUnmanagedVariable[] locals = new ISymUnmanagedVariable[localCount];
            ThrowExceptionForHR(scope.GetLocals(localCount, out localCount, locals));

            for (int i = 0; i < localCount; i++)
            {
                var local = locals[i];

                int slot;
                ThrowExceptionForHR(local.GetAddressField1(out slot));

                int nameLength;
                ThrowExceptionForHR(local.GetName(0, out nameLength, null));

                // nameLength includes terminating '\0'
                char[] nameBuffer = new char[nameLength];
                ThrowExceptionForHR(local.GetName(nameLength, out nameLength, nameBuffer));

                int attributes;
                ThrowExceptionForHR(local.GetAttributes(out attributes));

                variables.Add(new LocalVariable()
                {
                    Slot = slot, Name = new String(nameBuffer, 0, nameLength - 1), CompilerGenerated = (attributes & 0x1) != 0
                });
            }

            int childrenCount;

            ThrowExceptionForHR(scope.GetChildren(0, out childrenCount, null));

            ISymUnmanagedScope[] children = new ISymUnmanagedScope[childrenCount];
            ThrowExceptionForHR(scope.GetChildren(childrenCount, out childrenCount, children));

            for (int i = 0; i < childrenCount; i++)
            {
                ProbeScopeForLocals(variables, children[i]);
            }
        }
Beispiel #8
0
        public static ImmutableArray <ISymUnmanagedVariable> GetLocals(this ISymUnmanagedScope scope)
        {
            int numAvailable;

            scope.GetLocalCount(out numAvailable);
            if (numAvailable == 0)
            {
                return(ImmutableArray <ISymUnmanagedVariable> .Empty);
            }

            int numRead;
            var locals = new ISymUnmanagedVariable[numAvailable];

            scope.GetLocals(numAvailable, out numRead, locals);
            if (numRead != numAvailable)
            {
                throw new InvalidOperationException(string.Format("Read only {0} of {1} locals.", numRead, numAvailable));
            }

            return(ImmutableArray.Create(locals));
        }
Beispiel #9
0
        private static ISymUnmanagedVariable[] GetLocalsInternal(ISymUnmanagedScope scope)
        {
            int numAvailable;

            scope.GetLocalCount(out numAvailable);
            if (numAvailable == 0)
            {
                return(null);
            }

            int numRead;
            var locals = new ISymUnmanagedVariable[numAvailable];

            scope.GetLocals(numAvailable, out numRead, locals);
            if (numRead != numAvailable)
            {
                throw new InvalidOperationException(string.Format("Read only {0} of {1} locals.", numRead, numAvailable));
            }

            return(locals);
        }
Beispiel #10
0
        public IEnumerable <ILLocalVariable> GetLocalVariables(IMethod method)
        {
            List <ILLocalVariable> vars = new List <ILLocalVariable>();
            var symMethod = method.GetSymMethod();

            if (symMethod == null)
            {
                return(vars);
            }

            Stack <ISymUnmanagedScope> scopes = new Stack <ISymUnmanagedScope>();

            scopes.Push(symMethod.GetRootScope());
            while (scopes.Count > 0)
            {
                ISymUnmanagedScope scope = scopes.Pop();
                foreach (ISymUnmanagedVariable symVar in scope.GetLocals())
                {
                    int index = (int)symVar.GetAddressField1();
                    vars.Add(new ILLocalVariable()
                    {
                        Index = index,
                        Type  = method.GetLocalVariableType(index),
                        Name  = symVar.GetName(),
                        IsCompilerGenerated = (symVar.GetAttributes() & 1) == 1,
                        // symVar also has Get*Offset methods, but the are not implemented
                        ILRanges = new [] { new ILRange()
                                            {
                                                From = (int)scope.GetStartOffset(), To = (int)scope.GetEndOffset()
                                            } }
                    });
                }
                foreach (ISymUnmanagedScope childScope in scope.GetChildren())
                {
                    scopes.Push(childScope);
                }
            }
            return(vars);
        }
        private static void SerializeScope(
            MetadataBuilder metadataBuilder,
            MetadataModel metadataModel,
            MethodDefinitionHandle methodHandle,
            ImportScopeHandle importScopeHandle,
            ISymUnmanagedScope symScope,
            Dictionary <int, DynamicLocalInfo> dynamicSlots,
            Dictionary <string, DynamicLocalInfo> dynamicNames,
            bool vbSemantics,
            ref LocalVariableHandle lastLocalVariableHandle,
            ref LocalConstantHandle lastLocalConstantHandle)
        {
            // VB Windows PDB encode the range as end-inclusive,
            // all Portable PDBs use end-exclusive encoding.
            int start = symScope.GetStartOffset();
            int end   = symScope.GetEndOffset() + (vbSemantics ? 1 : 0);

            metadataBuilder.AddLocalScope(
                method: methodHandle,
                importScope: importScopeHandle,
                variableList: NextHandle(lastLocalVariableHandle),
                constantList: NextHandle(lastLocalConstantHandle),
                startOffset: start,
                length: end - start);

            foreach (var symLocal in symScope.GetLocals())
            {
                int    slot = symLocal.GetSlot();
                string name = symLocal.GetName();

                lastLocalVariableHandle = metadataBuilder.AddLocalVariable(
                    attributes: (LocalVariableAttributes)symLocal.GetAttributes(),
                    index: slot,
                    name: metadataBuilder.GetOrAddString(name));

                DynamicLocalInfo dynamicInfo;
                if (slot > 0 && dynamicSlots.TryGetValue(slot, out dynamicInfo) ||
                    slot == 0 && dynamicNames.TryGetValue(name, out dynamicInfo))
                {
                    metadataBuilder.AddCustomDebugInformation(
                        parent: lastLocalVariableHandle,
                        kind: metadataBuilder.GetOrAddGuid(PortableCustomDebugInfoKinds.DynamicLocalVariables),
                        value: SerializeDynamicLocalBlob(metadataBuilder, dynamicInfo));
                }
            }

            foreach (var symConstant in symScope.GetConstants())
            {
                string name  = symConstant.GetName();
                object value = symConstant.GetValue();

                lastLocalConstantHandle = metadataBuilder.AddLocalConstant(
                    name: metadataBuilder.GetOrAddString(name),
                    signature: SerializeConstantSignature(metadataBuilder, metadataModel, symConstant.GetSignature(), value));

                DynamicLocalInfo dynamicInfo;
                if (dynamicNames.TryGetValue(name, out dynamicInfo))
                {
                    metadataBuilder.AddCustomDebugInformation(
                        parent: lastLocalConstantHandle,
                        kind: metadataBuilder.GetOrAddGuid(PortableCustomDebugInfoKinds.DynamicLocalVariables),
                        value: SerializeDynamicLocalBlob(metadataBuilder, dynamicInfo));
                }
            }

            int previousChildScopeEnd = start;

            foreach (ISymUnmanagedScope child in symScope.GetChildren())
            {
                int childScopeStart = child.GetStartOffset();
                int childScopeEnd   = child.GetEndOffset();

                // scopes are properly nested:
                if (childScopeStart < previousChildScopeEnd || childScopeEnd > end)
                {
                    // TODO: loc/warning
                    throw new BadImageFormatException($"Invalid scope IL offset range: [{childScopeStart}, {childScopeEnd}), method 0x{MetadataTokens.GetToken(methodHandle):x}.");
                }

                previousChildScopeEnd = childScopeEnd;

                SerializeScope(metadataBuilder, metadataModel, methodHandle, importScopeHandle, child, dynamicSlots, dynamicNames, vbSemantics, ref lastLocalVariableHandle, ref lastLocalConstantHandle);
            }
        }
Beispiel #12
0
        private void WriteLocals(ISymUnmanagedScope scope)
        {
            foreach (ISymUnmanagedVariable l in scope.GetLocals())
            {
                _writer.WriteStartElement("local");
                _writer.WriteAttributeString("name", l.GetName());

                // NOTE: VB emits "fake" locals for resumable locals which are actually backed by fields.
                //       These locals always map to the slot #0 which is just a valid number that is 
                //       not used. Only scoping information is used by EE in this case.
                _writer.WriteAttributeString("il_index", CultureInvariantToString(l.GetSlot()));

                _writer.WriteAttributeString("il_start", AsILOffset(scope.GetStartOffset()));
                _writer.WriteAttributeString("il_end", AsILOffset(scope.GetEndOffset()));
                _writer.WriteAttributeString("attributes", CultureInvariantToString(l.GetAttributes()));
                _writer.WriteEndElement();
            }

            foreach (ISymUnmanagedConstant constant in scope.GetConstants())
            {
                string name = constant.GetName();
                var signature = constant.GetSignature();
                object value = constant.GetValue();

                _writer.WriteStartElement("constant");
                _writer.WriteAttributeString("name", name);

                if (value is int &&
                    (int)value == 0 &&
                    (signature[0] == (byte)ConstantTypeCode.NullReference ||
                     signature[0] == (int)SignatureTypeCode.Object ||
                     signature[0] == (int)SignatureTypeCode.String ||
                     signature[0] == (int)SignatureTypeCode.GenericTypeInstance))
                {
                    // TODO: 0 for enums nested in a generic class, null for reference type
                    // We need to decode the signature and see if the target type is enum.
                    _writer.WriteAttributeString("value", "null");

                    if (signature[0] == (int)SignatureTypeCode.String)
                    {
                        _writer.WriteAttributeString("type", "String");
                    }
                    else if (signature[0] == (int)SignatureTypeCode.Object)
                    {
                        _writer.WriteAttributeString("type", "Object");
                    }
                    else
                    {
                        // TODO:
                        // A null reference, the type is encoded in the signature. 
                        // Ideally we would parse the signature and display the target type name. 
                        // That requires MetadataReader vNext though.
                        _writer.WriteAttributeString("signature", BitConverter.ToString(signature.ToArray()));
                    }
                }
                else if (value == null)
                {
                    // empty string
                    if (signature[0] == (byte)SignatureTypeCode.String)
                    {
                        _writer.WriteAttributeString("value", "");
                        _writer.WriteAttributeString("type", "String");
                    }
                    else
                    {
                        _writer.WriteAttributeString("value", "null");
                        _writer.WriteAttributeString("unknown-signature", BitConverter.ToString(signature.ToArray()));
                    }
                }
                else if (value is decimal)
                {
                    // TODO: check that the signature is a TypeRef
                    _writer.WriteAttributeString("value", ((decimal)value).ToString(CultureInfo.InvariantCulture));
                    _writer.WriteAttributeString("type", value.GetType().Name);
                }
                else if (value is double && signature[0] != (byte)SignatureTypeCode.Double)
                {
                    // TODO: check that the signature is a TypeRef
                    _writer.WriteAttributeString("value", DateTimeUtilities.ToDateTime((double)value).ToString(CultureInfo.InvariantCulture));
                    _writer.WriteAttributeString("type", "DateTime");
                }
                else
                {
                    _writer.WriteAttributeString("value", (value as string)?.Replace("\0", "U+0000") ?? string.Format(CultureInfo.InvariantCulture, "{0}", value));

                    var runtimeType = GetConstantRuntimeType(signature);
                    if (runtimeType == null && 
                        (value is sbyte || value is byte || value is short || value is ushort ||
                         value is int || value is uint || value is long || value is ulong))
                    {
                        // TODO:
                        // Enum.
                        // Ideally we would parse the signature and display the target type name. 
                        // That requires MetadataReader vNext though.
                        _writer.WriteAttributeString("signature", BitConverter.ToString(signature.ToArray()));
                    }
                    else if (runtimeType == value.GetType())
                    {
                        _writer.WriteAttributeString("type", ((SignatureTypeCode)signature[0]).ToString());
                    }
                    else
                    {
                        _writer.WriteAttributeString("runtime-type", value.GetType().Name);
                        _writer.WriteAttributeString("unknown-signature", BitConverter.ToString(signature.ToArray()));
                    }
                }

                _writer.WriteEndElement();
            }
        }
Beispiel #13
0
 /// <summary>
 /// Get definitions of local variables in scope.    
 /// </summary>
 /// <param name="scope">Interface refering to desired scope.</param>
 /// <param name="index">Index pointing to the last read variable.</param>
 /// <param name="definitions">List of definitions, where found variable definition are placed.</param>
 private void getDefinitionsForScope(ISymUnmanagedScope scope, ref int index, List<LocalVarDefinition> definitions)
 {
     ISymUnmanagedVariable[] variables = scope.GetLocals();
     foreach (ISymUnmanagedVariable var in variables) {
         LocalVarDefinition def = new LocalVarDefinition();
         def.ilStart = scope.GetStartOffset();
         def.ilEnd = scope.GetEndOffset();
         def.name = var.GetName();
         def.signature = var.GetSignature();
         definitions.Add(def);
         ++index;
     }
     foreach (ISymUnmanagedScope cScope in scope.GetChildren()) {
         getDefinitionsForScope(cScope, ref index, definitions);
     }
 }
        private void WriteLocals(ISymUnmanagedScope scope)
        {
            foreach (ISymUnmanagedVariable l in scope.GetLocals())
            {
                _writer.WriteStartElement("local");
                _writer.WriteAttributeString("name", l.GetName());

                // NOTE: VB emits "fake" locals for resumable locals which are actually backed by fields.
                //       These locals always map to the slot #0 which is just a valid number that is 
                //       not used. Only scoping information is used by EE in this case.
                _writer.WriteAttributeString("il_index", CultureInvariantToString(l.GetSlot()));

                _writer.WriteAttributeString("il_start", AsILOffset(scope.GetStartOffset()));
                _writer.WriteAttributeString("il_end", AsILOffset(scope.GetEndOffset()));
                _writer.WriteAttributeString("attributes", CultureInvariantToString(l.GetAttributes()));
                _writer.WriteEndElement();
            }

            foreach (ISymUnmanagedConstant constant in scope.GetConstants())
            {
                string name = constant.GetName();
                var signature = constant.GetSignature();
                object value = constant.GetValue();

                _writer.WriteStartElement("constant");
                _writer.WriteAttributeString("name", name);

                if (value is int &&
                    (int)value == 0 &&
                    (signature[0] == (byte)ConstantTypeCode.NullReference ||
                     signature[0] == (int)SignatureTypeCode.Object ||
                     signature[0] == (int)SignatureTypeCode.String ||
                     (signature.Length > 2 && signature[0] == (int)SignatureTypeCode.GenericTypeInstance && signature[1] == (byte)ConstantTypeCode.NullReference)))
                {
                    _writer.WriteAttributeString("value", "null");

                    if (signature[0] == (int)SignatureTypeCode.String)
                    {
                        _writer.WriteAttributeString("type", "String");
                    }
                    else if (signature[0] == (int)SignatureTypeCode.Object)
                    {
                        _writer.WriteAttributeString("type", "Object");
                    }
                    else
                    {
                        _writer.WriteAttributeString("signature", FormatSignature(signature));
                    }
                }
                else if (value == null)
                {
                    // empty string
                    if (signature[0] == (byte)SignatureTypeCode.String)
                    {
                        _writer.WriteAttributeString("value", "");
                        _writer.WriteAttributeString("type", "String");
                    }
                    else
                    {
                        _writer.WriteAttributeString("value", "null");
                        _writer.WriteAttributeString("unknown-signature", BitConverter.ToString(signature.ToArray()));
                    }
                }
                else if (value is decimal)
                {
                    // TODO: check that the signature is a TypeRef
                    _writer.WriteAttributeString("value", ((decimal)value).ToString(CultureInfo.InvariantCulture));
                    _writer.WriteAttributeString("type", value.GetType().Name);
                }
                else if (value is double && signature[0] != (byte)SignatureTypeCode.Double)
                {
                    // TODO: check that the signature is a TypeRef
                    _writer.WriteAttributeString("value", DateTimeUtilities.ToDateTime((double)value).ToString(CultureInfo.InvariantCulture));
                    _writer.WriteAttributeString("type", "DateTime");
                }
                else
                {
                    string str = value as string;
                    if (str != null)
                    {
                        _writer.WriteAttributeString("value", StringUtilities.EscapeNonPrintableCharacters(str));
                    }
                    else
                    {
                        _writer.WriteAttributeString("value", string.Format(CultureInfo.InvariantCulture, "{0}", value));
                    }

                    var runtimeType = GetConstantRuntimeType(signature);
                    if (runtimeType == null &&
                        (value is sbyte || value is byte || value is short || value is ushort ||
                         value is int || value is uint || value is long || value is ulong))
                    {
                        _writer.WriteAttributeString("signature", FormatSignature(signature));
                    }
                    else if (runtimeType == value.GetType())
                    {
                        _writer.WriteAttributeString("type", ((SignatureTypeCode)signature[0]).ToString());
                    }
                    else
                    {
                        _writer.WriteAttributeString("runtime-type", value.GetType().Name);
                        _writer.WriteAttributeString("unknown-signature", BitConverter.ToString(signature.ToArray()));
                    }
                }

                _writer.WriteEndElement();
            }
        }
 private void WriteScopes(ISymUnmanagedScope rootScope)
 {
     // The root scope is always empty. The first scope opened by SymWriter is the child of the root scope.
     if (rootScope.GetNamespaces().IsEmpty && rootScope.GetLocals().IsEmpty && rootScope.GetConstants().IsEmpty)
     {
         foreach (ISymUnmanagedScope child in rootScope.GetScopes())
         {
             WriteScope(child, isRoot: false);
         }
     }
     else
     {
         // This shouldn't be executed for PDBs generated via SymWriter.
         WriteScope(rootScope, isRoot: true);
     }
 }
Beispiel #16
0
            static ICorDebugValue _FindLocal(string name, ICorDebugILFrame ilframe, ISymUnmanagedScope unmScope, uint ip)
            {
                int varcount;
                unmScope.GetLocalCount(out varcount);
                ISymUnmanagedVariable[] vars = new ISymUnmanagedVariable[varcount];
                unmScope.GetLocals(varcount, out varcount, vars);

                for (int iv = 0; iv < varcount; iv++)
                {
                    ISymUnmanagedVariable var = vars[iv];
                    string varname;
                    {
                        int namelen;
                        var.GetName(0, out namelen, null);
                        StringBuilder sbName = new StringBuilder(namelen);
                        var.GetName(sbName.Capacity, out namelen, sbName);
                        namelen--; // Remove nul.
                        sbName.Length = namelen;
                        varname = sbName.ToString();
                    }
                    if (name == varname)
                    {
                        int field1;
                        var.GetAddressField1(out field1);
                        ICorDebugValue pvalue;
                        ilframe.GetLocalVariable((uint)field1, out pvalue);
                        return pvalue;
                    }
                }

                int cChildren;
                unmScope.GetChildren(0, out cChildren, null);
                ISymUnmanagedScope[] children = new ISymUnmanagedScope[cChildren];
                unmScope.GetChildren(children.Length, out cChildren, children);
                for (int ic = 0; ic < cChildren; ic++)
                {
                    ICorDebugValue pvalue = _FindLocal(name, ilframe, children[ic], ip);
                    if (null != pvalue)
                    {
                        return pvalue;
                    }
                }

                return null;
            }
Beispiel #17
0
            static void _PrintLocals(ICorDebugILFrame ilframe, ISymUnmanagedScope unmScope, uint ip, System.IO.TextWriter writer)
            {
                int varcount;
                unmScope.GetLocalCount(out varcount);
                ISymUnmanagedVariable[] vars = new ISymUnmanagedVariable[varcount];
                unmScope.GetLocals(varcount, out varcount, vars);

                for (int iv = 0; iv < varcount; iv++)
                {
                    ISymUnmanagedVariable var = vars[iv];
                    string varname;
                    {
                        int namelen;
                        var.GetName(0, out namelen, null);
                        StringBuilder sbName = new StringBuilder(namelen);
                        var.GetName(sbName.Capacity, out namelen, sbName);
                        namelen--; // Remove nul.
                        sbName.Length = namelen;
                        varname = sbName.ToString();
                    }
                    string valstr;
                    {
                        int field1;
                        var.GetAddressField1(out field1);
                        ICorDebugValue pvalue;
                        ilframe.GetLocalVariable((uint)field1, out pvalue);
                        valstr = ToString(pvalue);
                    }
                    writer.WriteLine("{0}={1}", varname, valstr);
                }

                int cChildren;
                unmScope.GetChildren(0, out cChildren, null);
                ISymUnmanagedScope[] children = new ISymUnmanagedScope[cChildren];
                unmScope.GetChildren(children.Length, out cChildren, children);
                for (int ic = 0; ic < cChildren; ic++)
                {
                    _PrintLocals(ilframe, children[ic], ip, writer);
                }

            }
Beispiel #18
0
        internal void GetLocalSourceNames(ISymUnmanagedScope/*!*/ scope, Hashtable/*!*/ localSourceNames)
        {
            uint numLocals = scope.GetLocalCount();
            IntPtr[] localPtrs = new IntPtr[numLocals];
            scope.GetLocals((uint)localPtrs.Length, out numLocals, localPtrs);

            char[] nameBuffer = new char[100];
            uint nameLen;
            for (int i = 0; i < numLocals; i++)
            {
                ISymUnmanagedVariable local =
                  (ISymUnmanagedVariable)System.Runtime.InteropServices.Marshal.GetTypedObjectForIUnknown(localPtrs[i], typeof(ISymUnmanagedVariable));
                if (local != null)
                {
                    local.GetName((uint)nameBuffer.Length, out nameLen, nameBuffer);
                    int localIndex = (int)local.GetAddressField1();
                    localSourceNames[localIndex] = new String(nameBuffer, 0, (int)nameLen - 1);
                    System.Runtime.InteropServices.Marshal.ReleaseComObject(local);
                }
                System.Runtime.InteropServices.Marshal.Release(localPtrs[i]);
            }

            IntPtr[] subscopes = new IntPtr[100];
            uint numScopes;
            scope.GetChildren((uint)subscopes.Length, out numScopes, subscopes);
            for (int i = 0; i < numScopes; i++)
            {
                ISymUnmanagedScope subscope =
                  (ISymUnmanagedScope)System.Runtime.InteropServices.Marshal.GetTypedObjectForIUnknown(subscopes[i], typeof(ISymUnmanagedScope));
                if (subscope != null)
                {
                    this.GetLocalSourceNames(subscope, localSourceNames);
                    System.Runtime.InteropServices.Marshal.ReleaseComObject(subscope);
                }
                System.Runtime.InteropServices.Marshal.Release(subscopes[i]);
                //TODO: need to figure out how map these scope to blocks and set HasLocals on those blocks
            }
        }
Beispiel #19
0
 List<DebugLocalVariableInfo> GetLocalVariablesInScope(ISymUnmanagedScope symScope)
 {
     List<DebugLocalVariableInfo> vars = new List<DebugLocalVariableInfo>();
     foreach (ISymUnmanagedVariable symVar in symScope.GetLocals()) {
         ISymUnmanagedVariable symVarCopy = symVar;
         var locVarSig = new DebugSignatureReader().ReadTypeSignature(symVar.GetSignature());
         DebugType locVarType = DebugType.CreateFromSignature(this.DebugModule, locVarSig, declaringType);
         // Compiler generated?
         // NB: Display class does not have the compiler-generated flag
         if ((symVar.GetAttributes() & 1) == 1 || symVar.GetName().StartsWith("CS$")) {
             // Get display class from local variable
             if (locVarType.IsDisplayClass) {
                 AddCapturedLocalVariables(
                     vars,
                     (int)symScope.GetStartOffset(),
                     (int)symScope.GetEndOffset(),
                     delegate(StackFrame context) {
                         return GetLocalVariableValue(context, symVarCopy);
                     },
                     locVarType
                 );
             }
         } else {
             DebugLocalVariableInfo locVar = new DebugLocalVariableInfo(
                 symVar.GetName(),
                 (int)symVar.GetAddressField1(),
                 // symVar also has Get*Offset methods, but the are not implemented
                 (int)symScope.GetStartOffset(),
                 (int)symScope.GetEndOffset(),
                 locVarType,
                 delegate(StackFrame context) {
                     return GetLocalVariableValue(context, symVarCopy);
                 }
             );
             vars.Add(locVar);
         }
     }
     foreach(ISymUnmanagedScope childScope in symScope.GetChildren()) {
         vars.AddRange(GetLocalVariablesInScope(childScope));
     }
     return vars;
 }
Beispiel #20
0
 public int GetLocals(int cLocals, out int pcLocals, ISymUnmanagedVariable[] locals)
 {
     return(_scope.GetLocals(cLocals, out pcLocals, locals));
 }
Beispiel #21
0
 public static ISymUnmanagedVariable[] GetAndValidateVariables(ISymUnmanagedScope scope, int expectedCount)
 {
     int count, count2, count3;
     Assert.Equal(HResult.S_OK, scope.GetLocalCount(out count));
     Assert.Equal(expectedCount, count);
     Assert.Equal(HResult.S_OK, scope.GetLocals(0, out count2, null));
     Assert.Equal(expectedCount, count2);
     var variables = new ISymUnmanagedVariable[count];
     Assert.Equal(HResult.S_OK, scope.GetLocals(count, out count3, variables));
     Assert.Equal(count, count3);
     return variables;
 }
        //
        // Gather the local details in a scope and then recurse to child scopes
        //
        private void ProbeScopeForLocals(List<ILLocalVariable> variables, ISymUnmanagedScope scope)
        {
            int localCount;
            ThrowExceptionForHR(scope.GetLocalCount(out localCount));

            ISymUnmanagedVariable[] locals = new ISymUnmanagedVariable[localCount];
            ThrowExceptionForHR(scope.GetLocals(localCount, out localCount, locals));

            for (int i = 0; i < localCount; i++)
            {
                var local = locals[i];

                int slot;
                ThrowExceptionForHR(local.GetAddressField1(out slot));

                int nameLength;
                ThrowExceptionForHR(local.GetName(0, out nameLength, null));

                // nameLength includes terminating '\0'
                char[] nameBuffer = new char[nameLength];
                ThrowExceptionForHR(local.GetName(nameLength, out nameLength, nameBuffer));

                int attributes;
                ThrowExceptionForHR(local.GetAttributes(out attributes));

                variables.Add(new ILLocalVariable() { Slot = slot, Name = new String(nameBuffer, 0, nameLength - 1), CompilerGenerated = (attributes & 0x1) != 0 });
            }

            int childrenCount;
            ThrowExceptionForHR(scope.GetChildren(0, out childrenCount, null));

            ISymUnmanagedScope[] children = new ISymUnmanagedScope[childrenCount];
            ThrowExceptionForHR(scope.GetChildren(childrenCount, out childrenCount, children));

            for (int i = 0; i < childrenCount; i++)
            {
                ProbeScopeForLocals(variables, children[i]);
            }
        }
Beispiel #23
0
        private void WriteLocalsHelper(ISymUnmanagedScope scope, Dictionary <int, ImmutableArray <string> > slotNames, bool includeChildScopes)
        {
            foreach (ISymUnmanagedVariable l in scope.GetLocals())
            {
                writer.WriteStartElement("local");
                {
                    writer.WriteAttributeString("name", l.GetName());

                    // Each local maps to a "IL Index" or "slot" number.
                    // The index is not necessarily unique. Several locals may refer to the same slot.
                    // It just means that the same local is known under different names inside the same or different scopes.
                    // This index is what you pass to ICorDebugILFrame::GetLocalVariable() to get
                    // a specific local variable.
                    // NOTE: VB emits "fake" locals for resumable locals which are actually backed by fields.
                    //       These locals always map to the slot #0 which is just a valid number that is
                    //       not used. Only scoping information is used by EE in this case.
                    int slot = l.GetSlot();
                    writer.WriteAttributeString("il_index", CultureInvariantToString(slot));

                    bool reusingSlot = false;

                    // collect slot names so that we can verify ISymUnmanagedReader APIs
                    if (slotNames != null)
                    {
                        ImmutableArray <string> existingNames;
                        if (slotNames.TryGetValue(slot, out existingNames))
                        {
                            slotNames[slot] = existingNames.Add(l.GetName());
                            reusingSlot     = true;
                        }
                        else
                        {
                            slotNames.Add(slot, ImmutableArray.Create(l.GetName()));
                        }
                    }

                    // Provide scope range
                    writer.WriteAttributeString("il_start", AsILOffset(scope.GetStartOffset()));
                    writer.WriteAttributeString("il_end", AsILOffset(scope.GetEndOffset()));
                    writer.WriteAttributeString("attributes", l.GetAttributes().ToString());

                    if (reusingSlot)
                    {
                        writer.WriteAttributeString("reusingslot", reusingSlot.ToString(CultureInfo.InvariantCulture));
                    }
                }
                writer.WriteEndElement(); // </local>
            }

            foreach (ISymUnmanagedConstant c in scope.GetConstants())
            {
                // Note: We can retrieve constant tokens by saving it into signature blob
                // in our implementation of IMetadataImport.GetSigFromToken.
                writer.WriteStartElement("constant");
                {
                    writer.WriteAttributeString("name", c.GetName());

                    object value    = c.GetValue();
                    string typeName = value.GetType().Name;

                    // certain Unicode characters will give Xml writers fits...in order to avoid this, we'll replace
                    // problematic characters/sequences with their hexadecimal equivalents, like U+0000, etc...
                    var chars = value as string;
                    if (chars != null)
                    {
                        PooledStringBuilder pooled = PooledStringBuilder.GetInstance();
                        var valueWithPlaceholders  = pooled.Builder;
                        foreach (var ch in chars)
                        {
                            // if we end up with more, we can add them here
                            if (0 == (int)ch)
                            {
                                valueWithPlaceholders.AppendFormat("U+{0:X4}", (int)ch);
                            }
                            else
                            {
                                valueWithPlaceholders.Append(ch);
                            }
                        }
                        if (valueWithPlaceholders.Length > chars.Length)
                        {
                            value = valueWithPlaceholders.ToString();
                        }
                        pooled.Free();
                    }

                    writer.WriteAttributeString("value", value.ToString());
                    writer.WriteAttributeString("type", typeName);
                }
                writer.WriteEndElement(); // </constant>
            }

            if (includeChildScopes)
            {
                foreach (ISymUnmanagedScope childScope in scope.GetScopes())
                {
                    WriteLocalsHelper(childScope, slotNames, includeChildScopes);
                }
            }
        }
Beispiel #24
0
        private void WriteLocalsHelper(ISymUnmanagedScope scope, Dictionary<int, ImmutableArray<string>> slotNames, bool includeChildScopes)
        {
            foreach (ISymUnmanagedVariable l in scope.GetLocals())
            {
                writer.WriteStartElement("local");
                {
                    writer.WriteAttributeString("name", l.GetName());

                    // Each local maps to a "IL Index" or "slot" number. 
                    // The index is not necessarily unique. Several locals may refer to the same slot. 
                    // It just means that the same local is known under different names inside the same or different scopes.
                    // This index is what you pass to ICorDebugILFrame::GetLocalVariable() to get
                    // a specific local variable. 
                    // NOTE: VB emits "fake" locals for resumable locals which are actually backed by fields.
                    //       These locals always map to the slot #0 which is just a valid number that is 
                    //       not used. Only scoping information is used by EE in this case.
                    int slot = l.GetSlot();
                    writer.WriteAttributeString("il_index", CultureInvariantToString(slot));

                    bool reusingSlot = false;

                    // collect slot names so that we can verify ISymUnmanagedReader APIs
                    if (slotNames != null)
                    {
                        ImmutableArray<string> existingNames;
                        if (slotNames.TryGetValue(slot, out existingNames))
                        {
                            slotNames[slot] = existingNames.Add(l.GetName());
                            reusingSlot = true;
                        }
                        else
                        {
                            slotNames.Add(slot, ImmutableArray.Create(l.GetName()));
                        }
                    }

                    // Provide scope range
                    writer.WriteAttributeString("il_start", AsILOffset(scope.GetStartOffset()));
                    writer.WriteAttributeString("il_end", AsILOffset(scope.GetEndOffset()));
                    writer.WriteAttributeString("attributes", l.GetAttributes().ToString());

                    if (reusingSlot)
                    {
                        writer.WriteAttributeString("reusingslot", reusingSlot.ToString(CultureInfo.InvariantCulture));
                    }
                }
                writer.WriteEndElement(); // </local>
            }

            foreach (ISymUnmanagedConstant c in scope.GetConstants())
            {
                // Note: We can retrieve constant tokens by saving it into signature blob
                // in our implementation of IMetadataImport.GetSigFromToken.
                writer.WriteStartElement("constant");
                {
                    writer.WriteAttributeString("name", c.GetName());

                    object value = c.GetValue();
                    string typeName = value.GetType().Name;

                    // certain Unicode characters will give Xml writers fits...in order to avoid this, we'll replace
                    // problematic characters/sequences with their hexadecimal equivalents, like U+0000, etc...
                    var chars = value as string;
                    if (chars != null)
                    {
                        PooledStringBuilder pooled = PooledStringBuilder.GetInstance();
                        var valueWithPlaceholders = pooled.Builder;
                        foreach (var ch in chars)
                        {
                            // if we end up with more, we can add them here
                            if (0 == (int)ch)
                            {
                                valueWithPlaceholders.AppendFormat("U+{0:X4}", (int)ch);
                            }
                            else
                            {
                                valueWithPlaceholders.Append(ch);
                            }
                        }
                        if (valueWithPlaceholders.Length > chars.Length)
                        {
                            value = valueWithPlaceholders.ToString();
                        }
                        pooled.Free();
                    }

                    writer.WriteAttributeString("value", value.ToString());
                    writer.WriteAttributeString("type", typeName);
                }
                writer.WriteEndElement(); // </constant>
            }

            if (includeChildScopes)
            {
                foreach (ISymUnmanagedScope childScope in scope.GetScopes())
                {
                    WriteLocalsHelper(childScope, slotNames, includeChildScopes);
                }
            }
        }