示例#1
0
        private bool TryGetDebuggableMethod(int methodToken, out PortablePdbReader pdbReader, out MethodDebugInformationHandle handle)
        {
            if (!MetadataUtilities.IsMethodToken(methodToken))
            {
                pdbReader = null;
                handle    = default(MethodDebugInformationHandle);
                return(false);
            }

            var methodId = MethodId.FromToken(methodToken);

            if (Version == 1)
            {
                pdbReader = GetReader(version: 1);
                if (pdbReader.TryGetMethodHandle(methodId, out handle))
                {
                    return(pdbReader.HasDebugInfo(handle));
                }
            }
            else
            {
                var methodMap = GetMethodMap();
                if (methodMap.IsValidMethodRowId(methodId.Value))
                {
                    var info = methodMap.GetInfo(methodId);
                    pdbReader = GetReader(info.Version);
                    handle    = info.Handle;
                    return(pdbReader.HasDebugInfo(handle));
                }
            }

            pdbReader = null;
            handle    = default(MethodDebugInformationHandle);
            return(false);
        }
示例#2
0
        private int UpdateSymbolStoreImpl(
            IStream stream,
            string fileName,
            SymUnmanagedLineDelta[] lineDeltas,
            int lineDeltaCount)
        {
            Debug.Assert(stream != null ^ fileName != null);
            Debug.Assert(lineDeltas != null);
            Debug.Assert(lineDeltaCount >= 0);

            lineDeltaCount = Math.Min(lineDeltas.Length, lineDeltaCount);
            var methodMap     = GetMethodMap();
            var documentMap   = GetDocumentMap();
            var methodExtents = GetMethodExtents();

            var lineDeltasByDocument = GroupLineDeltasByDocument(lineDeltas, lineDeltaCount);

            int newVersion = Version + 1;

            var provider = (stream != null) ? CreateProviderFromStream(stream) : CreateProviderFromFile(fileName);

            var pdbReader = new PortablePdbReader(provider, newVersion, documentMap.DocumentCount);

            documentMap.Update(this, pdbReader.MetadataReader, newVersion, out var documentHandleToIdMap);
            methodMap.Update(this, pdbReader.MetadataReader, newVersion, out var methodHandleToIdMap);
            pdbReader.InitializeHandleToIdMaps(documentHandleToIdMap, methodHandleToIdMap);
            methodExtents.Update(pdbReader, lineDeltasByDocument);

            // remove line deltas of methods updated in this generation:
            for (int i = 0; i < methodHandleToIdMap.Length; i++)
            {
                RemoveLineDeltas(methodHandleToIdMap[i]);
            }

            // apply line deltas of methods moved around in this generation:
            for (int i = 0; i < lineDeltaCount; i++)
            {
                UpdateLineDeltas(MethodId.FromToken(lineDeltas[i].MethodToken), new MethodLineDeltas(lineDeltas[i].Delta, ImmutableArray <int> .Empty));
            }

            _pdbReaders.Add(pdbReader);
            pdbReader.SymReader = this;

            return(HResult.S_OK);
        }
示例#3
0
        private Dictionary <DocumentId, List <(MethodId, int)> > GroupLineDeltasByDocument(SymUnmanagedLineDelta[] lineDeltas, int lineDeltaCount)
        {
            var methodMap        = GetMethodMap();
            var deltasByDocument = new Dictionary <DocumentId, List <(MethodId, int)> >();

            for (int i = 0; i < lineDeltaCount; i++)
            {
                int methodToken = lineDeltas[i].MethodToken;
                if (!TryGetDebuggableMethod(methodToken, out var pdbReader, out var handle))
                {
                    continue;
                }

                var methodId = MethodId.FromToken(methodToken);
                var(single, multiple) = MethodExtents.GetMethodBodyDocuments(pdbReader.MetadataReader, handle);
                if (!single.IsNil)
                {
                    AddExtentForDocument(single);
                }
                else
                {
                    // method has debug info:
                    Debug.Assert(multiple != null);

                    foreach (var documentHandle in multiple)
                    {
                        AddExtentForDocument(documentHandle);
                    }
                }

                void AddExtentForDocument(DocumentHandle documentHandle)
                {
                    var documentId = pdbReader.GetDocumentId(documentHandle);

                    if (!deltasByDocument.TryGetValue(documentId, out var extents))
                    {
                        deltasByDocument.Add(documentId, extents = new List <(MethodId, int)>());
                    }

                    extents.Add((methodId, lineDeltas[i].Delta));
                }
            }
示例#4
0
        /// <summary>
        /// Get a particular version of a method with specified token.
        /// </summary>
        public int GetMethodByVersion(
            int methodToken,
            int version,
            [MarshalAs(UnmanagedType.Interface)] out ISymUnmanagedMethod method)
        {
            if (!IsValidVersion(version))
            {
                method = null;
                return(HResult.E_INVALIDARG);
            }

            if (!MetadataUtilities.IsMethodToken(methodToken))
            {
                method = null;
                return(HResult.E_INVALIDARG);
            }

            var pdbReader = GetReader(version);

            if (!pdbReader.TryGetMethodHandle(MethodId.FromToken(methodToken), out var methodDebugHandle))
            {
                method = null;
                return(HResult.E_FAIL);
            }

            var debugInfo = pdbReader.MetadataReader.GetMethodDebugInformation(methodDebugHandle);

            if (debugInfo.SequencePointsBlob.IsNil)
            {
                // no debug info for the method
                method = null;
                return(HResult.E_FAIL);
            }

            method = new SymMethod(pdbReader, methodDebugHandle);
            return(HResult.S_OK);
        }