Ejemplo n.º 1
0
        private void WriteMethod(MethodDefinitionHandle methodHandle)
        {
            int token = metadataReader.GetToken(methodHandle);

            byte[] cdi = pdbReader.SymbolReader.GetCustomDebugInfo(token, methodVersion: 0);
            ISymUnmanagedMethod method = pdbReader.SymbolReader.GetMethod(token);

            if (cdi == null && method == null)
            {
                // no debug info for the method
                return;
            }

            writer.WriteStartElement("method");
            WriteMethodAttributes(token, isReference: false);

            if (cdi != null)
            {
                WriteCustomDebugInfo(cdi);
            }

            if (method != null)
            {
                WriteSequencePoints(method);

                // TODO (tomat): Ideally this would be done in a separate test helper, not in PdbToXml.
                // verify ISymUnmanagedMethod APIs:
                var expectedSlotNames = new Dictionary <int, ImmutableArray <string> >();
                WriteLocals(method, expectedSlotNames);

                var actualSlotNames = method.GetLocalVariableSlots();

                Debug.Assert(actualSlotNames.Length == (expectedSlotNames.Count == 0 ? 0 : expectedSlotNames.Keys.Max() + 1));

                int i = 0;
                foreach (var slotName in actualSlotNames)
                {
                    if (slotName == null)
                    {
                        Debug.Assert(!expectedSlotNames.ContainsKey(i));
                    }
                    else
                    {
                        Debug.Assert(expectedSlotNames[i].Contains(slotName));
                    }

                    i++;
                }

                ImmutableArray <ISymUnmanagedScope> children = method.GetRootScope().GetScopes();
                if (children.Length != 0)
                {
                    WriteScopes(children[0]);
                }

                WriteAsyncInfo(method);
            }

            writer.WriteEndElement(); // method
        }
Ejemplo n.º 2
0
 // Write all the locals in the given method out to an XML file.
 // Since the symbol store represents the locals in a recursive scope structure, we need to walk a tree.
 // Although the locals are technically a hierarchy (based off nested scopes), it's easiest for clients
 // if we present them as a linear list. We will provide the range for each local's scope so that somebody
 // could reconstruct an approximation of the scope tree. The reconstruction may not be exact.
 // (Note this would still break down if you had an empty scope nested in another scope.
 private void WriteLocals(ISymUnmanagedMethod method, Dictionary <int, ImmutableArray <string> > slotNames)
 {
     writer.WriteStartElement("locals");
     // If there are no locals, then this element will just be empty.
     WriteLocalsHelper(method.GetRootScope(), slotNames, includeChildScopes: true);
     writer.WriteEndElement();
 }
Ejemplo n.º 3
0
        public static ISymUnmanagedScope GetRootScope(this ISymUnmanagedMethod method)
        {
            ISymUnmanagedScope scope;

            method.GetRootScope(out scope);
            return(scope);
        }
Ejemplo n.º 4
0
        public static ISymUnmanagedScope GetRootScope(this ISymUnmanagedMethod method)
        {
            ISymUnmanagedScope scope;
            int hr = method.GetRootScope(out scope);

            ThrowExceptionForHR(hr);
            return(scope);
        }
Ejemplo n.º 5
0
 internal static void GetAllScopes(
     this ISymUnmanagedMethod method,
     ArrayBuilder <ISymUnmanagedScope> allScopes,
     ArrayBuilder <ISymUnmanagedScope> containingScopes,
     int offset,
     bool isScopeEndInclusive)
 {
     GetAllScopes(method.GetRootScope(), allScopes, containingScopes, offset, isScopeEndInclusive);
 }
Ejemplo n.º 6
0
 public int GetRootScope(out ISymUnmanagedScope retVal)
 {
     _method.GetRootScope(out retVal);
     if (retVal != null)
     {
         retVal = new SymScope(_reader, retVal);
     }
     return(SymUnmanagedReaderExtensions.S_OK);
 }
        public static ISymUnmanagedScope GetRootScope(this ISymUnmanagedMethod method)
        {
            if (method == null)
            {
                throw new ArgumentNullException(nameof(method));
            }

            ISymUnmanagedScope scope;

            ThrowExceptionForHR(method.GetRootScope(out scope));
            return(scope);
        }
Ejemplo n.º 8
0
        internal static ImmutableArray <string> GetLocalVariableSlots(this ISymUnmanagedMethod method)
        {
            var builder = ImmutableArray.CreateBuilder <string>();
            ISymUnmanagedScope rootScope = method.GetRootScope();

            ForEachLocalVariableRecursive(rootScope, offset: -1, isScopeEndInclusive: false, action: local =>
            {
                var slot = local.GetSlot();
                while (builder.Count <= slot)
                {
                    builder.Add(null);
                }

                var name      = local.GetName();
                builder[slot] = name;
            });

            return(builder.ToImmutable());
        }
Ejemplo n.º 9
0
        internal static ImmutableArray <string> GetLocalVariableSlots(this ISymUnmanagedMethod method, int offset = -1)
        {
            char[]   nameBuffer = null;
            string[] result     = null;
            int      maxSlot    = -1;

            ISymUnmanagedScope rootScope = method.GetRootScope();

            ISymUnmanagedVariable[] localsBuffer = null;

            ForEachLocalVariableRecursive(rootScope, offset, ref localsBuffer, local =>
            {
                int nameLength;
                local.GetName(0, out nameLength, null);

                if (nameLength > 0)
                {
                    EnsureBufferSize(ref nameBuffer, nameLength);
                    local.GetName(nameLength, out nameLength, nameBuffer);

                    int slot;
                    local.GetAddressField1(out slot);

                    if (maxSlot < slot)
                    {
                        maxSlot = slot;
                    }

                    EnsureBufferSize(ref result, slot + 1);

                    // nameLength is NUL-terminated
                    Debug.Assert(nameBuffer[nameLength - 1] == '\0');
                    result[slot] = new string(nameBuffer, 0, nameLength - 1);
                }
            });

            if (result == null)
            {
                return(ImmutableArray.Create <string>());
            }

            return(ImmutableArray.Create(result, 0, maxSlot + 1));
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Get the (unprocessed) import strings for a given method.
        /// </summary>
        /// <remarks>
        /// Doesn't consider forwarding.
        ///
        /// CONSIDER: Dev12 doesn't just check the root scope - it digs around to find the best
        /// match based on the IL offset and then walks up to the root scope (see PdbUtil::GetScopeFromOffset).
        /// However, it's not clear that this matters, since imports can't be scoped in VB.  This is probably
        /// just based on the way they were extracting locals and constants based on a specific scope.
        /// </remarks>
        internal static ImmutableArray <string> GetImportStrings(this ISymUnmanagedMethod method)
        {
            if (method == null)
            {
                // In rare circumstances (only bad PDBs?) GetMethodByVersion can return null.
                // If there's no debug info for the method, then no import strings are available.
                return(ImmutableArray <string> .Empty);
            }

            ISymUnmanagedScope rootScope = method.GetRootScope();

            if (rootScope == null)
            {
                Debug.Assert(false, "Expected a root scope.");
                return(ImmutableArray <string> .Empty);
            }

            ImmutableArray <ISymUnmanagedScope> childScopes = rootScope.GetScopes();

            if (childScopes.Length == 0)
            {
                // It seems like there should always be at least one child scope, but we've
                // seen PDBs where that is not the case.
                return(ImmutableArray <string> .Empty);
            }

            // As in NamespaceListWrapper::Init, we only consider namespaces in the first
            // child of the root scope.
            ISymUnmanagedScope firstChildScope = childScopes[0];

            ImmutableArray <ISymUnmanagedNamespace> namespaces = firstChildScope.GetNamespaces();

            if (namespaces.Length == 0)
            {
                // It seems like there should always be at least one namespace (i.e. the global
                // namespace), but we've seen PDBs where that is not the case.
                return(ImmutableArray <string> .Empty);
            }

            return(ImmutableArray.CreateRange(namespaces, n => n.GetName()));
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Get the (unprocessed) import strings for a given method.
        /// </summary>
        /// <remarks>
        /// Doesn't consider forwarding.
        /// </remarks>
        private static ImmutableArray <string> GetImportStrings(this ISymUnmanagedMethod method)
        {
            ISymUnmanagedScope rootScope = method.GetRootScope();

            if (rootScope == null)
            {
                Debug.Assert(false, "Expected a root scope.");
                return(ImmutableArray <string> .Empty);
            }

            ImmutableArray <ISymUnmanagedScope> childScopes = rootScope.GetScopes();

            if (childScopes.Length == 0)
            {
                //Debug.Assert(false, "Expected at least one child scope."); // TODO (acasey): Why can't we assume this?
                return(ImmutableArray <string> .Empty);
            }

            // As in NamespaceListWrapper::Init, we only consider namespaces in the first
            // child of the root scope.
            ISymUnmanagedScope firstChildScope = childScopes[0];

            ImmutableArray <ISymUnmanagedNamespace> namespaces = firstChildScope.GetNamespaces();

            if (namespaces.Length == 0)
            {
                //Debug.Assert(false, "Expected at least one namespace (i.e. the global namespace)."); // TODO (acasey): Why can't we assume this?
                return(ImmutableArray <string> .Empty);
            }

            ArrayBuilder <string> importsBuilder = ArrayBuilder <string> .GetInstance(namespaces.Length);

            foreach (ISymUnmanagedNamespace @namespace in namespaces)
            {
                importsBuilder.Add(@namespace.GetName());
            }
            return(importsBuilder.ToImmutableAndFree());
        }
Ejemplo n.º 12
0
 // Write all the locals in the given method out to an XML file.
 // Since the symbol store represents the locals in a recursive scope structure, we need to walk a tree.
 // Although the locals are technically a hierarchy (based off nested scopes), it's easiest for clients
 // if we present them as a linear list. We will provide the range for each local's scope so that somebody
 // could reconstruct an approximation of the scope tree. The reconstruction may not be exact.
 // (Note this would still break down if you had an empty scope nested in another scope.
 private void WriteLocals(ISymUnmanagedMethod method, Dictionary<int, ImmutableArray<string>> slotNames)
 {
     writer.WriteStartElement("locals");
     {
         // If there are no locals, then this element will just be empty.
         WriteLocalsHelper(method.GetRootScope(), slotNames, includeChildScopes: true);
     }
     writer.WriteEndElement();
 }
Ejemplo n.º 13
0
        internal static void GetAllScopes(this ISymUnmanagedMethod method, ArrayBuilder <ISymUnmanagedScope> builder, int offset, bool isScopeEndInclusive)
        {
            ISymUnmanagedScope scope = method.GetRootScope();

            GetAllScopes(scope, builder, offset, isScopeEndInclusive);
        }