예제 #1
0
        /// <summary>
        /// Called when receiving a report about a method
        /// </summary>
        /// <param name="methodName"></param>
        /// <param name="methodSig"></param>
        /// <param name="bodySize"></param>
        /// <param name="flags"></param>
        /// <param name="implFlags"></param>
        /// <param name="symbolFileId"></param>
        /// <param name="methodDef"></param>
        public void EnterMethod(string methodName, string methodSig, int bodySize, uint flags, uint implFlags, int symbolFileId, int methodDef)
        {
            currentTypedef.Methods.Add(currentMethod = new MethodEntry
            {
                Type      = currentTypedef,
                Name      = methodName,
                Signature = methodSig,
                BodySize  = bodySize,
                MethodDef = methodDef,
                Flags     = (MethodAttributes)flags,
                ImplFlags = (MethodImplAttributes)implFlags
            });

            if (_symbolReader != null)
            {
                var           token = new SymbolToken(methodDef);
                ISymbolMethod method;
                try
                {
                    method = _symbolReader.GetMethod(token);
                    var count = method.SequencePointCount;

                    int[]             offsets = new int[count];
                    int[]             sls     = new int[count];
                    int[]             scs     = new int[count];
                    int[]             els     = new int[count];
                    int[]             ecs     = new int[count];
                    ISymbolDocument[] docs    = new ISymbolDocument[count];

                    method.GetSequencePoints(offsets, docs, sls, scs, els, ecs);

                    for (int i = 0; i < count; i++)
                    {
                        MethodBlock block = new MethodBlock();
                        block.Offset = offsets[i];
                        var fileId = GetFileIdentifier(docs[i].URL);
                        if (fileId > 0 && sls[i] != 0xFEEFEE)
                        {
                            block.Start = new Position {
                                Column = scs[i], Line = sls[i]
                            };
                            block.End = new Position {
                                Column = ecs[i], Line = els[i]
                            };
                            block.File = fileId;
                        }
                        currentMethod.Blocks.Add(block);
                    }

                    docs = null;
                }
                catch (Exception ex)
                {
                }
                finally
                {
                    method = null;
                }
            }
        }
        // Write the sequence points for the given method
        // Sequence points are the map between IL offsets and source lines.
        // A single method could span multiple files (use C#'s #line directive to see for yourself).
        private SequencePoint[] ReadSequencePoints(ISymbolMethod method)
        {
            int count = method.SequencePointCount;

            // Get the sequence points from the symbol store.
            // We could cache these arrays and reuse them.
            int[]             offsets     = new int[count];
            ISymbolDocument[] docs        = new ISymbolDocument[count];
            int[]             startColumn = new int[count];
            int[]             endColumn   = new int[count];
            int[]             startRow    = new int[count];
            int[]             endRow      = new int[count];
            method.GetSequencePoints(offsets, docs, startRow, startColumn, endRow, endColumn);

            // Store them into the list
            var sequencePoints = new List <SequencePoint>(count);

            for (int i = 0; i < count; i++)
            {
                var sp = new SequencePoint(offsets[i], docs[i].URL, startRow[i], endRow[i], startColumn[i], endColumn[i]);
                sequencePoints.Add(sp);
            }

            return(sequencePoints.OrderBy(sp => sp.SourcePath).ThenBy(sp => sp.StartLine).ToArray());
        }
예제 #3
0
            /// <summary>
            /// Returns the name of the file for the given method using the given symbol reader
            /// </summary>
            /// <param name="reader">The reader to use</param>
            /// <param name="methodBase">The method to lookup</param>
            /// <returns>The file containing the method or null.</returns>
            private static string GetFileForMethod(ISymbolReader reader, MethodBase methodBase)
            {
                int token = methodBase.MetadataToken;

                ISymbolMethod methodSymbol = reader == null ? null : reader.GetMethod(new SymbolToken(token));

                if (methodSymbol != null)
                {
                    int count = methodSymbol.SequencePointCount;

                    // Get the sequence points from the symbol store.
                    // We could cache these arrays and reuse them.
                    int[]             offsets     = new int[count];
                    ISymbolDocument[] docs        = new ISymbolDocument[count];
                    int[]             startColumn = new int[count];
                    int[]             endColumn   = new int[count];
                    int[]             startRow    = new int[count];
                    int[]             endRow      = new int[count];
                    methodSymbol.GetSequencePoints(offsets, docs, startRow, startColumn, endRow, endColumn);

                    foreach (ISymbolDocument doc in docs)
                    {
                        string file = doc.URL.ToString();
                        return(file);
                    }
                }
                return(null);
            }
예제 #4
0
        void AddSequencePoints(CilBody body, ISymbolMethod method)
        {
            int numSeqs    = method.SequencePointCount;
            var offsets    = new int[numSeqs];
            var documents  = new ISymbolDocument[numSeqs];
            var lines      = new int[numSeqs];
            var columns    = new int[numSeqs];
            var endLines   = new int[numSeqs];
            var endColumns = new int[numSeqs];

            method.GetSequencePoints(offsets, documents, lines, columns, endLines, endColumns);

            int instrIndex = 0;

            for (int i = 0; i < numSeqs; i++)
            {
                var instr = GetInstruction(body.Instructions, offsets[i], ref instrIndex);
                if (instr == null)
                {
                    continue;
                }
                var seqPoint = new SequencePoint()
                {
                    Document    = Add_NoLock(new PdbDocument(documents[i])),
                    StartLine   = lines[i],
                    StartColumn = columns[i],
                    EndLine     = endLines[i],
                    EndColumn   = endColumns[i],
                };
                instr.SequencePoint = seqPoint;
            }
        }
예제 #5
0
        //private string[] GetCombinedSource(IEnumerable<SequencePoint> points) {
        //    var lines = new List<string>();
        //    foreach (var point in points) {
        //        var contentLines = documentCache.Get(point.Document, () => File.ReadAllLines(point.Document.URL));
        //        var start = point.Start.Row - 1;
        //        var end = point.End.Row - 1;

        //        if (start >= contentLines.Length || end >= contentLines.Length)
        //            continue;

        //        for (var i = start; i <= end; i++) {
        //            var line = contentLines[i];

        //            if (i == start)
        //                line = line.Substring(point.Start.Column - 1);
        //            else if (i == end)
        //                line = line.Substring(0, point.End.Column - 1);

        //            lines.Add(line);
        //        }
        //    }

        //    return lines.ToArray();
        //}

        private IEnumerable <SequencePoint> GetSequencePoints(ISymbolMethod method)
        {
            var count = method.SequencePointCount;

            var offsets      = new int[count];
            var docs         = new ISymbolDocument[count];
            var startColumns = new int[count];
            var endColumns   = new int[count];
            var startRows    = new int[count];
            var endRows      = new int[count];

            method.GetSequencePoints(offsets, docs, startRows, startColumns, endRows, endColumns);

            for (int i = 0; i < count; i++)
            {
                if (startRows[i] == SequencePointHiddenLine || endRows[i] == SequencePointHiddenLine)
                {
                    continue;
                }

                yield return(new SequencePoint {
                    Document = this.GetOrLoadContent(docs[i]),
                    Start = new SourcePosition(startRows[i], startColumns[i]),
                    End = new SourcePosition(endRows[i], endColumns[i])
                });
            }
        }
예제 #6
0
        public ISymbolMethod GetMethodFromDocumentPosition(ISymbolDocument document, int line, int column)
        {
            ISymUnmanagedMethod unmanagedMethod;

            unmanagedReader.GetMethodFromDocumentPosition(((SymbolDocument)document).InternalDocument, line, column, out unmanagedMethod);
            return(new SymbolMethod(unmanagedMethod));
        }
예제 #7
0
        public int GetDocumentVersion(ISymbolDocument document, out bool isCurrent)
        {
            int version;

            unmanagedReader.GetDocumentVersion(((SymbolDocument)document).InternalDocument, out version, out isCurrent);
            return(version);
        }
예제 #8
0
		public void GetSequencePoints(int[] offsets, ISymbolDocument[] documents, int[] lines, int[] columns, int[] endLines, int[] endColumns) {
			// Any array can be null, and the documentation says we must verify the sizes.

			int arySize = -1;
			if (offsets != null)		arySize = offsets.Length;
			else if (documents != null)	arySize = documents.Length;
			else if (lines != null)		arySize = lines.Length;
			else if (columns != null)	arySize = columns.Length;
			else if (endLines != null)	arySize = endLines.Length;
			else if (endColumns != null)arySize = endColumns.Length;

			if (offsets    != null && offsets.Length    != arySize) throw new ArgumentException("Invalid array length: offsets");
			if (documents  != null && documents.Length  != arySize) throw new ArgumentException("Invalid array length: documents");
			if (lines      != null && lines.Length      != arySize) throw new ArgumentException("Invalid array length: lines");
			if (columns    != null && columns.Length    != arySize) throw new ArgumentException("Invalid array length: columns");
			if (endLines   != null && endLines.Length   != arySize) throw new ArgumentException("Invalid array length: endLines");
			if (endColumns != null && endColumns.Length != arySize) throw new ArgumentException("Invalid array length: endColumns");

			if (arySize <= 0)
				return;

			var unDocs = documents == null ? null : new ISymUnmanagedDocument[documents.Length];
			uint size;
			method.GetSequencePoints((uint)arySize, out size, offsets, unDocs, lines, columns, endLines, endColumns);

			if (unDocs != null) {
				for (int i = 0; i < unDocs.Length; i++)
					documents[i] = unDocs[i] == null ? null : new SymbolDocument(unDocs[i]);
			}
		}
예제 #9
0
        //�Public�Methods�(1)�

        /// <summary>
        /// Gets the method source from PDB.
        /// </summary>
        /// <param name="methodInfo">The method info.</param>
        /// <returns></returns>
        public PDBMethodSourceData GetMethodSourceFromPDB(MethodInfo methodInfo)
        {
            ISymbolMethod met = _symbolReader.GetMethod(new SymbolToken(methodInfo.MetadataToken));

            int count = met.SequencePointCount;

            ISymbolDocument[] docs       = new ISymbolDocument[count];
            int[]             offsets    = new int[count];
            int[]             lines      = new int[count];
            int[]             columns    = new int[count];
            int[]             endlines   = new int[count];
            int[]             endcolumns = new int[count];

            met.GetSequencePoints(offsets, docs, lines, columns, endlines, endcolumns);

            return(new PDBMethodSourceData()
            {
                symbolDocs = docs,
                sourceCodeLines = lines,
                ilOpcodeOffsets = offsets,
                souceCodeColumns = columns,
                sourceCodeEndColumns = endcolumns,
                sourceCodeEndLines = endlines
            });
        }
예제 #10
0
        public static IEnumerable <SequencePoint> GetSequencePoints(this ISymbolMethod met)
        {
            int sc = met.SequencePointCount;

            int[]             offsets    = new int[sc];
            int[]             lines      = new int[sc];
            int[]             endLines   = new int[sc];
            int[]             columns    = new int[sc];
            int[]             endColumns = new int[sc];
            ISymbolDocument[] docs       = new ISymbolDocument[sc];
            met.GetSequencePoints(offsets, docs, lines, columns, endLines, endColumns);

            for (int n = 0; n < sc; n++)
            {
                if (columns[n] == 0)
                {
                    continue;
                }
                SequencePoint sp = new SequencePoint();
                sp.Document = docs[n];
                sp.Line     = lines[n];
                sp.Offset   = offsets[n];
                yield return(sp);
            }
        }
예제 #11
0
		void ISymbolMethod.GetSequencePoints(int[] offsets, ISymbolDocument[] documents, int[] lines, int[] columns,
			int[] endLines, int[] endColumns) {
			int count = Lines == null ? 0 : Lines.Count;
			if (offsets != null && offsets.Length != count)
				throw new ArgumentException("Invalid array length: offsets");
			if (documents != null && documents.Length != count)
				throw new ArgumentException("Invalid array length: documents");
			if (lines != null && lines.Length != count)
				throw new ArgumentException("Invalid array length: lines");
			if (columns != null && columns.Length != count)
				throw new ArgumentException("Invalid array length: columns");
			if (endLines != null && endLines.Length != count)
				throw new ArgumentException("Invalid array length: endLines");
			if (endColumns != null && endColumns.Length != count)
				throw new ArgumentException("Invalid array length: endColumns");

			if (count <= 0)
				return;

			int i = 0;
			foreach (var line in Lines) {
				offsets[i] = (int)line.Offset;
				documents[i] = line.Document;
				lines[i] = (int)line.LineBegin;
				columns[i] = (int)line.ColumnBegin;
				endLines[i] = (int)line.LineEnd;
				endColumns[i] = (int)line.ColumnEnd;
				i++;
			}
		}
예제 #12
0
        // note: sadly it's not possible to cache all the [count] allocations and reuse them.
        // a NRE is throw if the size of the arrays does not match SequencePointCount :(
        void ReadSequencePoints(ISymbolMethod method, IDictionary instructions)
        {
            int count = method.SequencePointCount;

            int []             offsets     = new int [count];
            ISymbolDocument [] docs        = new ISymbolDocument [count];
            int []             startColumn = new int [count];
            int []             endColumn   = new int [count];
            int []             startRow    = new int [count];
            int []             endRow      = new int [count];
            method.GetSequencePoints(offsets, docs, startRow, startColumn, endRow, endColumn);

            for (int i = 0; i < offsets.Length; i++)
            {
                Cil.Instruction instr = (Cil.Instruction)instructions [offsets [i]];

                Cil.SequencePoint sp = new Cil.SequencePoint(GetDocument(docs [i]));
                sp.StartLine   = startRow [i];
                sp.StartColumn = startColumn [i];
                sp.EndLine     = endRow [i];
                sp.EndColumn   = endColumn [i];

                instr.SequencePoint = sp;
            }
        }
예제 #13
0
        public MethodDebugInfo(MethodBody body, ISymbolMethod pdb)
        {
            Body = body;

            // todo. support multiple locals sharing the same local slot
            // (but having different Start::End offsets, of course)
            // so far we just silently ignore them taking into account only the first one
            var locals = pdb.RootScope.Flatten(ss => ss.GetChildren()).SelectMany(ss => ss.GetLocals());

            LocalNames = locals.Select(lv => new { Index = lv.AddressField1, Name = lv.Name })
                         .Distinct().ToDictionary(lv => lv.Index, lv => lv.Name).ToReadOnly();

            var count      = pdb.SequencePointCount;
            var offsets    = new int[count];
            var documents  = new ISymbolDocument[count];
            var lines      = new int[count];
            var columns    = new int[count];
            var endLines   = new int[count];
            var endColumns = new int[count];

            pdb.GetSequencePoints(offsets, documents, lines, columns, endLines, endColumns);

            SequencePoints = 0.UpTo(count - 1).Select(i =>
                                                      new SequencePoint(offsets[i], documents[i], lines[i], columns[i], endLines[i], endColumns[i])
                                                      ).ToReadOnly();
        }
예제 #14
0
        public SequencePoint[] Generate(ISymbolMethod method)
        {
            var sequencePoints = new List<SequencePoint>();
            var sp_count = method.SequencePointCount;
            var spOffsets = new int[sp_count]; // Array.CreateInstance(int, sp_count)
            var spDocs = new ISymbolDocument[sp_count]; // Array.CreateInstance(ISymbolDocument, sp_count)
            var spStartLines = new int[sp_count]; // Array.CreateInstance(int, sp_count)
            var spEndLines = new int[sp_count]; // Array.CreateInstance(int, sp_count)
            var spStartCol = new int[sp_count]; // Array.CreateInstance(int, sp_count)
            var spEndCol = new int[sp_count]; // Array.CreateInstance(int, sp_count)

            method.GetSequencePoints(spOffsets, spDocs, spStartLines, spStartCol, spEndLines, spEndCol);

            for (int i = 0; i < sp_count; i++) // (var i in range(sp_count))
            {
                if (spStartLines[i] != 0xfeefee) // if spStartLines[i] != 0xfeefee:
                {
                    sequencePoints.Add(new SequencePoint(spOffsets[i],
                                                         spDocs[i],
                                                         spStartLines[i],
                                                         spStartCol[i],
                                                         spEndLines[i],
                                                         spEndCol[i]));
                }
            }
            return sequencePoints.ToArray();
        }
예제 #15
0
        static void Main(string[] args)
        {
            Assembly      ass       = Assembly.GetExecutingAssembly();
            ISymbolReader symreader = SymUtil.GetSymbolReaderForFile(ass.Location, null);

            MethodInfo    m   = ass.GetType("PdbTest.TestClass").GetMethod("GetStringRepresentation");
            ISymbolMethod met = symreader.GetMethod(new SymbolToken(m.MetadataToken));

            int count = met.SequencePointCount;

            ISymbolDocument[] docs       = new ISymbolDocument[count];
            int[]             offsets    = new int[count];
            int[]             lines      = new int[count];
            int[]             columns    = new int[count];
            int[]             endlines   = new int[count];
            int[]             endcolumns = new int[count];

            met.GetSequencePoints(offsets, docs, lines, columns, endlines, endcolumns);

            StreamReader reader = new StreamReader(docs[0].URL);

            string[] linesOfCode = reader.ReadToEnd().Split('n');
            reader.Close();

            Console.WriteLine("The content of method PdbTest.TestClass.GetStringRepresentation");
            for (int i = lines[0]; i < endlines[count - 1] - 1; i++)
            {
                Console.WriteLine(linesOfCode[i]);
            }
        }
예제 #16
0
 public int GetOffset(
     ISymbolDocument document,
     int line,
     int column)
 {
     throw new NotImplementedException("No QUT.SymbolMethod.GetOffset");
 }
예제 #17
0
        public int GetOffset(ISymbolDocument document, int line, int column)
        {
            int retVal;

            unmanagedMethod.GetOffset(((SymbolDocument)document).InternalDocument, line, column, out retVal);
            return(retVal);
        }
예제 #18
0
        //////////////////////////////////////////////////////////////////////////////////
        //
        //  Initialization & locals
        //
        //////////////////////////////////////////////////////////////////////////////////

        private void EnsureIsUpToDate()
        {
            Debug.Assert(m_module != null);
            Debug.Assert(m_module.EditsCounter >= CorFunction.Version - 1);             // version cannot be greater then # of edits; versions are 1 based

            if (m_isInitialized)
            {
                return;                 // no need to do any refresh
            }
            // perform refresh
            m_isInitialized = true;
            m_haveSymbols   = m_module.SymReader != null;
            if (m_haveSymbols)
            {
                ISymbolMethod sm = null;
                sm = m_module.SymReader.GetMethod(new SymbolToken((int)m_function.Token), CorFunction.Version);
                if (sm == null)
                {
                    m_haveSymbols = false;
                    return;
                }

                m_symMethod      = sm;
                m_SPcount        = m_symMethod.SequencePointCount;
                m_SPoffsets      = new int[m_SPcount];
                m_SPdocuments    = new ISymbolDocument[m_SPcount];
                m_SPstartLines   = new int[m_SPcount];
                m_SPendLines     = new int[m_SPcount];
                m_SPstartColumns = new int[m_SPcount];
                m_SPendColumns   = new int[m_SPcount];

                m_symMethod.GetSequencePoints(m_SPoffsets, m_SPdocuments, m_SPstartLines, m_SPstartColumns, m_SPendLines, m_SPendColumns);
            }
        }
예제 #19
0
		public int GetOffset(ISymbolDocument document, int line, int column) {
			var symDoc = document as SymbolDocument;
			if (symDoc == null)
				throw new ArgumentException("document is not a non-null SymbolDocument instance");
			uint result;
			method.GetOffset(symDoc.SymUnmanagedDocument, (uint)line, (uint)column, out result);
			return (int)result;
		}
예제 #20
0
        /// <summary>
        /// Gets the method that contains a specified position of the document
        /// </summary>
        /// <param name="document">The document object</param>
        /// <param name="line">Source line number</param>
        /// <param name="column">Source column number</param>
        /// <returns>The chosen method</returns>
        public ISymbolMethod GetMethodFromDocumentPosition(ISymbolDocument doc, int line, int column)
        {
            ISymUnmanagedMethod unMeth;

            private_reader.GetMethodFromDocumentPosition(
                ((SymbolDocument)doc).WrappedDoc, line, column, out unMeth);
            return(new SymbolMethod(unMeth));
        }
예제 #21
0
        public int GetDocumentVersion(ISymbolDocument document,
                                      out Boolean isCurrent)
        {
            int version = 0;

            m_reader.GetDocumentVersion(((SymbolDocument)document).InternalDocument, out version, out isCurrent);
            return(version);
        }
예제 #22
0
		// Constructor.
		public SequencePoint(int offset, ISymbolDocument document,
							 int line, int column)
				{
					this.offset = offset;
					this.document = document;
					this.line = line;
					this.column = column;
				}
예제 #23
0
 // Constructor.
 public SequencePoint(int offset, ISymbolDocument document,
                      int line, int column)
 {
     this.offset   = offset;
     this.document = document;
     this.line     = line;
     this.column   = column;
 }
예제 #24
0
        public int[] GetRanges(ISymbolDocument document, int line, int column)
        {
            int cRanges;

            unmanagedMethod.GetRanges(((SymbolDocument)document).InternalDocument, line, column, 0, out cRanges, null);
            int[] ranges = new int[cRanges];
            unmanagedMethod.GetRanges(((SymbolDocument)document).InternalDocument, line, column, cRanges, out cRanges, ranges);
            return(ranges);
        }
예제 #25
0
        internal SourceDocument(string[] lines, string location, ISymbolDocument symbols)
        {
            this.Lines   = lines;
            this.Content = string.Join(Environment.NewLine, lines);

            this.Location = location;

            this.Symbols = symbols;
        }
예제 #26
0
 public SequencePoint(int offset, ISymbolDocument document, int lineStart, int lineStartColumn, int lineEnd, int lineEndColumn)
 {
     Offset = offset;
     Document = document;
     LineStart = lineStart;
     LineStartColumn = lineStartColumn;
     LineEnd = lineEnd;
     LineEndColumn = lineEndColumn;
 }
예제 #27
0
        internal SourceDocument(string[] lines, string location, ISymbolDocument symbols)
        {
            this.Lines = lines;
            this.Content = string.Join(Environment.NewLine, lines);

            this.Location = location;

            this.Symbols = symbols;
        }
예제 #28
0
 public SequencePoint(int offset, ISymbolDocument document, int startLine, int startColumn, int endLine,
                      int endColumn)
 {
     this.offset = offset;
     this.document = document;
     this.startLine = startLine;
     this.startColumn = startColumn;
     this.endLine = endLine;
     this.endColumn = endColumn;
 }
예제 #29
0
		/// <summary>
		/// Constructor
		/// </summary>
		/// <param name="symDoc">A <see cref="ISymbolDocument"/> instance</param>
		public PdbDocument(ISymbolDocument symDoc) {
			if (symDoc == null)
				throw new ArgumentNullException("symDoc");
			this.Url = symDoc.URL;
			this.Language = symDoc.Language;
			this.LanguageVendor = symDoc.LanguageVendor;
			this.DocumentType = symDoc.DocumentType;
			this.CheckSumAlgorithmId = symDoc.CheckSumAlgorithmId;
			this.CheckSum = symDoc.GetCheckSum();
		}
예제 #30
0
        private SourceDocument GetOrLoadContent(ISymbolDocument symbols)
        {
            var location = symbols.URL;
            if (!File.Exists(location))
                return null;

            return documentCache.Get(
                location, () => new SourceDocument(File.ReadAllLines(location), location, symbols)
            );
        }
예제 #31
0
		public ISymbolDocument[] GetDocuments() {
			uint numDocs;
			reader.GetDocuments(0, out numDocs, null);
			var unDocs = new ISymUnmanagedDocument[numDocs];
			reader.GetDocuments((uint)unDocs.Length, out numDocs, unDocs);
			var docs = new ISymbolDocument[numDocs];
			for (uint i = 0; i < numDocs; i++)
				docs[i] = new SymbolDocument(unDocs[i]);
			return docs;
		}
예제 #32
0
		public int[] GetRanges(ISymbolDocument document, int line, int column) {
			var symDoc = document as SymbolDocument;
			if (symDoc == null)
				throw new ArgumentException("document is not a non-null SymbolDocument instance");
			uint arySize;
			method.GetRanges(symDoc.SymUnmanagedDocument, (uint)line, (uint)column, 0, out arySize, null);
			var ary = new int[arySize];
			method.GetRanges(symDoc.SymUnmanagedDocument, (uint)line, (uint)column, (uint)ary.Length, out arySize, ary);
			return ary;
		}
예제 #33
0
        ISymbolDocument[] ISymbolReader.GetDocuments()
        {
            var docs = new ISymbolDocument[documents.Count];
            int i    = 0;

            foreach (var doc in documents.Values)
            {
                docs[i++] = doc;
            }
            return(docs);
        }
예제 #34
0
		public ISymbolMethod GetMethodFromDocumentPosition(ISymbolDocument document, int line, int column) {
			var symDoc = document as SymbolDocument;
			if (symDoc == null)
				throw new ArgumentException("document is not a non-null SymbolDocument instance");
			ISymUnmanagedMethod unMethod;
			int hr = reader.GetMethodFromDocumentPosition(symDoc.SymUnmanagedDocument, (uint)line, (uint)column, out unMethod);
			if (hr == E_FAIL)
				return null;
			Marshal.ThrowExceptionForHR(hr);
			return unMethod == null ? null : new SymbolMethod(unMethod);
		}
예제 #35
0
 public ISymbolDocument[] GetDocuments()
 {
     uint numDocs;
     reader.GetDocuments(0, out numDocs, null);
     var unDocs = new ISymUnmanagedDocument[numDocs];
     reader.GetDocuments((uint)unDocs.Length, out numDocs, unDocs);
     var docs = new ISymbolDocument[numDocs];
     for (uint i = 0; i < numDocs; i++)
         docs[i] = new SymbolDocument(unDocs[i]);
     return docs;
 }
예제 #36
0
 public ISymbolMethod GetMethodFromDocumentPosition(ISymbolDocument document, int line, int column)
 {
     var symDoc = document as SymbolDocument;
     if (symDoc == null)
         throw new ArgumentException("document is not a non-null SymbolDocument instance");
     ISymUnmanagedMethod unMethod;
     int hr = reader.GetMethodFromDocumentPosition(symDoc.SymUnmanagedDocument, (uint)line, (uint)column, out unMethod);
     if (hr == E_FAIL)
         return null;
     Marshal.ThrowExceptionForHR(hr);
     return unMethod == null ? null : new SymbolMethod(unMethod);
 }
예제 #37
0
        public static void GetLocalVariables(Assembly asm, MethodInfo m)
        {
            // Assembly asm = Assembly.GetExecutingAssembly();
            ISymbolReader symreader = SymUtil.GetSymbolReaderForFile(asm.Location, null);

            if (symreader == null)
            {
                Console.WriteLine(" ERROR: no symreader was created. Aborting GetLocalVariables...");
                return;
            }
            ISymbolMethod symMethod = symreader.GetMethod(new SymbolToken(m.MetadataToken));

            int sequencePointCount = symMethod.SequencePointCount;

            ISymbolDocument[] docs       = new ISymbolDocument[sequencePointCount];
            int[]             offsets    = new int[sequencePointCount];
            int[]             lines      = new int[sequencePointCount];
            int[]             columns    = new int[sequencePointCount];
            int[]             endlines   = new int[sequencePointCount];
            int[]             endcolumns = new int[sequencePointCount];

            symMethod.GetSequencePoints(offsets, docs, lines, columns, endlines, endcolumns);

            Console.WriteLine();
            Console.WriteLine("The source code for method: " + m.Name + "; found in " + docs[0].URL);
            Console.WriteLine(new String('*', 60));

            // although there's an array of docs, they seem to all have the same value (?) so we'll only use the first one
            StreamReader reader = new StreamReader(docs[0].URL); // URL is typically a fully path-qualified filename

            string[] linesOfCode = reader.ReadToEnd().Split('\r');

            string PrintableLineNumber = "0000";

            Console.WriteLine(linesOfCode[lines[0] - 2].Replace('\n', ' ')); // the preceding line (assumes declaration is only one line long, and found on immediately precediting line!


            // foreach (int LineNumber in lines) // print the source code (comments omitted)
            for (int LineNumber = lines[0]; LineNumber < lines[sequencePointCount - 1] + 1; LineNumber++) // print the source code (including comments)
            {
                PrintableLineNumber = new String(' ', 4 - LineNumber.ToString().Length)                   // padding
                                      + LineNumber.ToString();
                Console.WriteLine(PrintableLineNumber + ": " + linesOfCode[LineNumber - 1].Replace('\n', ' '));
            }
            // Console.WriteLine(linesOfCode[lines[sequencePointCount -1] + 1].Replace('\n', ' ')); // the trailing line
            //Console.WriteLine(linesOfCode);
            reader.Close();

            Console.WriteLine(new String('*', 60));
            Console.WriteLine();
            linesOfCode = null;
        }
예제 #38
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="symDoc">A <see cref="ISymbolDocument"/> instance</param>
 public PdbDocument(ISymbolDocument symDoc)
 {
     if (symDoc == null)
     {
         throw new ArgumentNullException("symDoc");
     }
     this.Url                 = symDoc.URL;
     this.Language            = symDoc.Language;
     this.LanguageVendor      = symDoc.LanguageVendor;
     this.DocumentType        = symDoc.DocumentType;
     this.CheckSumAlgorithmId = symDoc.CheckSumAlgorithmId;
     this.CheckSum            = symDoc.GetCheckSum();
 }
예제 #39
0
        public int GetOffset(ISymbolDocument document, int line, int column)
        {
            var symDoc = document as SymbolDocument;

            if (symDoc == null)
            {
                throw new ArgumentException("document is not a non-null SymbolDocument instance");
            }
            uint result;

            method.GetOffset(symDoc.SymUnmanagedDocument, (uint)line, (uint)column, out result);
            return((int)result);
        }
예제 #40
0
        private SourceDocument GetOrLoadContent(ISymbolDocument symbols)
        {
            var location = symbols.URL;

            if (!File.Exists(location))
            {
                return(null);
            }

            return(documentCache.Get(
                       location, () => new SourceDocument(File.ReadAllLines(location), location, symbols)
                       ));
        }
예제 #41
0
        private bool attemptSetBreakpoint(ISymbolReader reader, ISymbolDocument doc, CorModule module)
        {
            if (!doc.URL.Equals(_breakpoint.File))
                return false;

            var line = doc.FindClosestLine(_breakpoint.Line);
            var method = reader.GetMethodFromDocumentPosition(doc, line, _breakpoint.Column);
            var function = module.GetFunctionFromToken(method.Token.GetToken());

            var wasSet = attemptToSetBreakpointThroughSequencePoints(doc, line, method, function);
            if (!wasSet)
                setBreakpointThroughFunction(function);
            return true;
        }
예제 #42
0
        internal int GetIPFromPosition(ISymbolDocument document, int lineNumber)
        {
            EnsureIsUpToDate();

            for (int i = 0; i < m_SPcount; i++)
            {
                if (document.URL.Equals(m_SPdocuments[i].URL) &&
                    lineNumber == m_SPstartLines[i])
                {
                    return(m_SPoffsets[i]);
                }
            }
            return(-1);
        }
        public ISymbolMethod GetMethodFromDocumentPosition(ISymbolDocument document, int line, int column)
        {
            var symDocument = document as SymbolDocument;

            if (symDocument == null)
            {
                throw new InvalidOperationException();
            }

            ISymUnmanagedMethod unmanagedMethod;

            HRESULT.ThrowOnFailure(_unmanaged.GetMethodFromDocumentPosition(symDocument.Unmanaged, line, column, out unmanagedMethod));

            return(new SymbolMethod(unmanagedMethod));
        }
예제 #44
0
        public int GetOffset(ISymbolDocument document, int line, int column)
        {
            var symDocument = document as SymbolDocument;

            if (symDocument == null)
            {
                throw new InvalidOperationException();
            }

            int value;

            HRESULT.ThrowOnFailure(_unmanaged.GetOffset(symDocument.Unmanaged, line, column, out value));

            return(value);
        }
예제 #45
0
 private bool attemptToSetBreakpointThroughSequencePoints(ISymbolDocument doc, int line, ISymbolMethod method, CorFunction function)
 {
     bool found = false;
     foreach (var sp in getSequencePoints(method))
     {
         if (sp.Document.URL.Equals(doc.URL) && sp.LineStart.Equals(line))
         {
             var bp = function.ILCode.CreateBreakpoint(sp.Offset);
             bp.Activate(true);
             found = true;
             break;
         }
     }
     return found;
 }
예제 #46
0
        public static SequencePoint[] GetSequencePoints(this ISymbolMethod method)
        {
            var offsets = new int[method.SequencePointCount];
            var documents = new ISymbolDocument[method.SequencePointCount];
            var lines = new int[method.SequencePointCount];
            var columns = new int[method.SequencePointCount];
            var endLines = new int[method.SequencePointCount];
            var endColumns = new int[method.SequencePointCount];

            var sequencePoints = new SequencePoint[method.SequencePointCount];

            method.GetSequencePoints(offsets, documents, lines, columns, endLines, endColumns);

            for (int i = 0; i < method.SequencePointCount; i++)
            {
                var location = new SourceLocation(documents[i].URL, lines[i], columns[i], endLines[i], endColumns[i]);

                sequencePoints[i] = new SequencePoint(offsets[i], location);
            }
            return sequencePoints;
        }
예제 #47
0
        //private string[] GetCombinedSource(IEnumerable<SequencePoint> points) {
        //    var lines = new List<string>();
        //    foreach (var point in points) {
        //        var contentLines = documentCache.Get(point.Document, () => File.ReadAllLines(point.Document.URL));
        //        var start = point.Start.Row - 1;
        //        var end = point.End.Row - 1;
        //        if (start >= contentLines.Length || end >= contentLines.Length)
        //            continue;
        //        for (var i = start; i <= end; i++) {
        //            var line = contentLines[i];
        //            if (i == start)
        //                line = line.Substring(point.Start.Column - 1);
        //            else if (i == end)
        //                line = line.Substring(0, point.End.Column - 1);
        //            lines.Add(line);
        //        }
        //    }
        //    return lines.ToArray();
        //}
        private IEnumerable<SequencePoint> GetSequencePoints(ISymbolMethod method)
        {
            var count = method.SequencePointCount;

            var offsets = new int[count];
            var docs = new ISymbolDocument[count];
            var startColumns = new int[count];
            var endColumns = new int[count];
            var startRows = new int[count];
            var endRows = new int[count];

            method.GetSequencePoints(offsets, docs, startRows, startColumns, endRows, endColumns);

            for (int i = 0; i < count; i++) {
                if (startRows[i] == SequencePointHiddenLine || endRows[i] == SequencePointHiddenLine)
                    continue;

                yield return new SequencePoint {
                    Document = this.GetOrLoadContent(docs[i]),
                    Start = new SourcePosition(startRows[i], startColumns[i]),
                    End = new SourcePosition(endRows[i], endColumns[i])
                };
            }
        }
예제 #48
0
        public MethodDebugInfo(MethodBody body, ISymbolMethod pdb)
        {
            Body = body;

            // todo. support multiple locals sharing the same local slot 
            // (but having different Start::End offsets, of course)
            // so far we just silently ignore them taking into account only the first one
            var locals = pdb.RootScope.Flatten(ss => ss.GetChildren()).SelectMany(ss => ss.GetLocals());
            LocalNames = locals.Select(lv => new {Index = lv.AddressField1, Name = lv.Name})
                .Distinct().ToDictionary(lv => lv.Index, lv => lv.Name).ToReadOnly();

            var count = pdb.SequencePointCount;
            var offsets = new int[count];
            var documents = new ISymbolDocument[count];
            var lines = new int[count];
            var columns = new int[count];
            var endLines = new int[count];
            var endColumns = new int[count];
            pdb.GetSequencePoints(offsets, documents, lines, columns, endLines, endColumns);

            SequencePoints = 0.UpTo(count - 1).Select(i => 
                new SequencePoint(offsets[i], documents[i], lines[i], columns[i], endLines[i], endColumns[i])
            ).ToReadOnly();
        }
 public int GetOffset(ISymbolDocument document,
                      int line,
                      int column)
 {
     int retVal = 0;
     m_unmanagedMethod.GetOffset(((SymbolDocument) document).InternalDocument, line, column, out retVal);
     return retVal;
 }
예제 #50
0
        // parent - main containing window that this source window lives inside of.
        // function - function for which we're building virtual source around.
        // Get the IL from the given frame.
        // Called on UI thread.
        internal VirtualSourceViewerForm(MainForm parent, MDbgFunction function)
        {
            m_function = function;
            Debug.Assert(function != null);

            // Now actually right in text. do this first so that we can get the current font.
            BeginInit(parent);

            // Get fonts
            FontCache cache;
            {
                Font fontCurrent = this.richText.Font;
                Font emphasis = new Font(
                                   fontCurrent.FontFamily,
                                   fontCurrent.Size,
                                   FontStyle.Bold
                                );

                cache = new FontCache(emphasis);
            }

            // Underlying writer to the window.
            RawWriter rawWriter = new RawWriter(cache);

            // Il2Native mapping can be used to find out what IL offsets we can actually stop on.
            Il2NativeIterator il2nativeIterator = null;

            // Actual IL disassembly in string form.
            ILDasmIterator ilDasm = null;

            // Iterator through sequence points and source files.
            SequencePointIterator seqIterator = null;

            string fullName = "?";
            int token = 0;

            ulong nativeStartAddress = 0;
            CorDebugJITCompilerFlags codeFlags = CorDebugJITCompilerFlags.CORDEBUG_JIT_DEFAULT;

            // Make cross-thread call to worker thread to collect raw information.
            // This needs to access MDbg and so can't be done on our UI thread.
            parent.ExecuteOnWorkerThreadIfStoppedAndBlock(delegate(MDbgProcess proc)
            {
                Debug.Assert(proc != null);
                Debug.Assert(!proc.IsRunning);
                Debug.Assert(function.Module.Process == proc);

                // Get some properties about this function to display.
                token = function.CorFunction.Token;
                nativeStartAddress = function.CorFunction.NativeCode.Address;
                codeFlags = function.CorFunction.NativeCode.CompilerFlags;

                CorCode ilCode = function.CorFunction.ILCode;
                Debug.Assert(true == ilCode.IsIL);
                byte[] code = ilCode.GetCode();
                fullName = function.FullName;

                // This does the real disassembly work.
                string[] lines = null; // strings of IL.
                ILDisassembler.Disassemble(code, function.Module.Importer, out lines, out m_il2RowMapping);

                ilDasm = new ILDasmIterator(rawWriter, m_il2RowMapping, lines);

                IL2NativeMap[] il2nativeMapping = function.CorFunction.NativeCode.GetILToNativeMapping();
                il2nativeIterator = new Il2NativeIterator(rawWriter, il2nativeMapping, code);

                // Get sequence points
                ISymbolMethod symMethod = function.SymMethod;

                // Sequence point information
                int[] seqIlOffsets = null;
                string[] seqPaths = null;
                int[] seqStartLines = null, seqEndLines = null, seqStartColumns = null, seqEndColumns = null;
                int seqCount = 0;

                if (symMethod != null)
                {
                    seqCount = symMethod.SequencePointCount;
                    seqIlOffsets = new int[seqCount];
                    ISymbolDocument[] seqDocuments = new ISymbolDocument[seqCount];
                    seqPaths = new string[seqCount];
                    seqStartLines = new int[seqCount];
                    seqEndLines = new int[seqCount];
                    seqStartColumns = new int[seqCount];
                    seqEndColumns = new int[seqCount];

                    symMethod.GetSequencePoints(seqIlOffsets, seqDocuments, seqStartLines, seqStartColumns, seqEndLines, seqEndColumns);

                    for (int i = 0; i < seqCount; i++)
                    {
                        seqPaths[i] = seqDocuments[i].URL;
                    }
                }
                seqIterator = new SequencePointIterator(rawWriter, parent, seqIlOffsets, seqPaths, seqStartLines, seqStartColumns, seqEndLines, seqEndColumns);
            }
            ); // end worker call

            // We assume sequence points are sorted by IL offset. We assert that in the iterators below.
            // Now we need to go through and stitch the IL + Source together.
            // This also works even if we have no source (since that's just the degenerate case of 0 sequence points)

            // Print out header information
            Debug.Assert(token != 0);
            rawWriter.WriteLine(String.Format(CultureInfo.InvariantCulture,
                "> Function name:{0} (token={1:x})", fullName, token));
            rawWriter.WriteLine(String.Format(CultureInfo.InvariantCulture,
                "> Native Code Address =0x{0:x}, flags={1}", nativeStartAddress, codeFlags));

            // Walk through the IL in order and write out interleaved IL and Sequence Points.
            while (!seqIterator.IsDone)
            {
                // Add IL snippets that occur before this sequence point.
                WriteIlAndNative(ilDasm, il2nativeIterator, seqIterator.IlOffset);

                seqIterator.WriteSource();
                seqIterator.Next();
            }
            // Write the IL that's after the last sequence point
            WriteIlAndNative(ilDasm, il2nativeIterator, ilDasm.IlLength);

            // Set the text.
            InitLines(null, rawWriter.Lines, rawWriter.FormatList);

            EndInit(fullName);
        }
예제 #51
0
	public virtual int GetOffset
				(ISymbolDocument document, int line, int column)
			{
				// Load the sequence point information.
				LoadSequencePoints();

				// Search for an applicable block, based on the line number.
				int index;
				SequencePoint seq1;
				SequencePoint seq2;
				for(index = 0; index < sequencePoints.Count; ++index)
				{
					seq1 = (SequencePoint)(sequencePoints[index]);
					if(line >= seq1.line)
					{
						if(index < sequencePoints.Count - 1)
						{
							seq2 = (SequencePoint)(sequencePoints[index + 1]);
							if(line < seq2.line)
							{
								if(document == null || seq1.document == null ||
								   document.URL == seq1.document.URL)
								{
									return seq1.offset;
								}
							}
						}
						else
						{
							if(document == null || seq1.document == null ||
							   document.URL == seq1.document.URL)
							{
								return seq1.offset;
							}
						}
					}
				}

				// Could not find the offset, so assume offset zero.
				return 0;
			}
예제 #52
0
	public virtual bool GetSourceStartEnd
					(ISymbolDocument[] docs, int[] lines, int[] columns)
			{
				throw new NotSupportedException();
			}
예제 #53
0
	public virtual void GetSequencePoints
					(int[] offsets, ISymbolDocument[] documents, 
					 int[] lines, int[] columns, int[] endLines, 
					 int[] endColumns)
			{
				int index;
				LoadSequencePoints();
				for(index = 0; index < sequencePoints.Count; ++index)
				{
					if(offsets != null && index < offsets.Length)
					{
						offsets[index] =
							((SequencePoint)(sequencePoints[index])).offset;
					}
					if(documents != null && index < documents.Length)
					{
						documents[index] =
							((SequencePoint)(sequencePoints[index])).document;
					}
					if(lines != null && index < lines.Length)
					{
						lines[index] = 
							((SequencePoint)(sequencePoints[index])).line;
					}
					if(columns != null && index < columns.Length)
					{
						columns[index] =
							((SequencePoint)(sequencePoints[index])).column;
					}
					if(endLines != null && index < endLines.Length)
					{
						// This information is not available.
						endLines[index] = 0;
					}
					if(endColumns != null && index < endColumns.Length)
					{
						// This information is not available.
						endColumns[index] = 0;
					}
				}
			}
예제 #54
0
	public virtual int[] GetRanges
				(ISymbolDocument document, int line, int column)
			{
				// Not used in this implementation.
				return new int [0];
			}
예제 #55
0
		public static IEnumerable<SequencePoint> GetSequencePoints (this ISymbolMethod met)
		{
			int sc = met.SequencePointCount;
			int[] offsets = new int[sc];
			int[] lines = new int[sc];
			int[] endLines = new int[sc];
			int[] columns = new int[sc];
			int[] endColumns = new int[sc];
			ISymbolDocument[] docs = new ISymbolDocument[sc];
			met.GetSequencePoints (offsets, docs, lines, columns, endLines, endColumns);

			for (int n = 0; n < sc; n++) {
				if (columns[n] == 0)
					continue;
				SequencePoint sp = new SequencePoint ();
				sp.Document = docs[n];
				sp.Line = lines[n];
				sp.Offset = offsets[n];
				yield return sp;
			}
		}
예제 #56
0
        internal int GetIPFromPosition(ISymbolDocument document, int lineNumber)
        {
            EnsureIsUpToDate();

            for (int i = 0; i < m_SPcount; i++)
            {
                if (document.URL.Equals(m_SPdocuments[i].URL) &&
                    lineNumber == m_SPstartLines[i])
                    return m_SPoffsets[i];
            }
            return -1;
        }
예제 #57
0
        // Write the sequence points for the given method
        // Sequence points are the map between IL offsets and source lines.
        // A single method could span multiple files (use C#'s #line directive to see for yourself).
        private List<SequencePoint> ReadSequencePoints(ISymbolMethod method)
        {
            int count = method.SequencePointCount;

            // Get the sequence points from the symbol store.
            // We could cache these arrays and reuse them.
            int[] offsets = new int[count];
            ISymbolDocument[] docs = new ISymbolDocument[count];
            int[] startColumn = new int[count];
            int[] endColumn = new int[count];
            int[] startRow = new int[count];
            int[] endRow = new int[count];
            method.GetSequencePoints(offsets, docs, startRow, startColumn, endRow, endColumn);

            // Store them into the list
            List<SequencePoint> sequencePoints = new List<SequencePoint>(count);
            for (int i = 0; i < count; i++)
            {
                SequencePoint sp = new SequencePoint();
                sp.ilOffset = offsets[i];

                // If it's a special 0xFeeFee sequence point (eg, "hidden"),
                // place an attribute on it to make it very easy for tools to recognize.
                // See http://blogs.msdn.com/jmstall/archive/2005/06/19/FeeFee_SequencePoints.aspx
                if (startRow[i] == 0xFeeFee)
                {
                    sp.hidden = true;
                }

                sp.sourceId = this.m_fileMapping[docs[i].URL];
                sp.startRow = startRow[i];
                sp.startColumn = startColumn[i];
                sp.endRow = endRow[i];
                sp.endColumn = endColumn[i];

                sequencePoints.Add(sp);
            }

            return sequencePoints;
        }
        public void GetSequencePoints(int[] offsets,
                                      ISymbolDocument[] documents,
                                      int[] lines,
                                      int[] columns,
                                      int[] endLines,
                                      int[] endColumns)
        {
            int spCount = 0;
            if (offsets != null)
                spCount = offsets.Length;
            else if (documents != null)
                spCount = documents.Length;
            else if (lines != null)
                spCount = lines.Length;
            else if (columns != null)
                spCount = columns.Length;
            else if (endLines != null)
                spCount = endLines.Length;
            else if (endColumns != null)
                spCount = endColumns.Length;

            // Don't do anything if they're not really asking for anything.
            if (spCount == 0)
                return;

            // Make sure all arrays are the same length.
            if ((offsets != null) && (spCount != offsets.Length))
                throw new ArgumentException();

            if ((lines != null) && (spCount != lines.Length))
                throw new ArgumentException();

            if ((columns != null) && (spCount != columns.Length))
                throw new ArgumentException();

            if ((endLines != null) && (spCount != endLines.Length))
                throw new ArgumentException();

            if ((endColumns != null) && (spCount != endColumns.Length))
                throw new ArgumentException();

            var unmanagedDocuments = new ISymUnmanagedDocument[documents.Length];
            int cPoints = 0;
            uint i;
            m_unmanagedMethod.GetSequencePoints(documents.Length, out cPoints,
                                                offsets, unmanagedDocuments,
                                                lines, columns,
                                                endLines, endColumns);

            // Create the SymbolDocument form the IntPtr's
            for (i = 0; i < documents.Length; i++)
            {
                documents[i] = new SymbolDocument(unmanagedDocuments[i]);
            }

            return;
        }
        public bool GetSourceStartEnd(ISymbolDocument[] docs,
                                      int[] lines,
                                      int[] columns)
        {
            uint i;
            bool pRetVal = false;
            int spCount = 0;
            if (docs != null)
                spCount = docs.Length;
            else if (lines != null)
                spCount = lines.Length;
            else if (columns != null)
                spCount = columns.Length;

            // If we don't have at least 2 entries then return an error
            if (spCount < 2)
                throw new ArgumentException();

            // Make sure all arrays are the same length.
            if ((docs != null) && (spCount != docs.Length))
                throw new ArgumentException();

            if ((lines != null) && (spCount != lines.Length))
                throw new ArgumentException();

            if ((columns != null) && (spCount != columns.Length))
                throw new ArgumentException();

            var unmanagedDocuments = new ISymUnmanagedDocument[docs.Length];
            m_unmanagedMethod.GetSourceStartEnd(unmanagedDocuments, lines, columns, out pRetVal);
            if (pRetVal)
            {
                for (i = 0; i < docs.Length; i++)
                {
                    docs[i] = new SymbolDocument(unmanagedDocuments[i]);
                }
            }
            return pRetVal;
        }
 public int[] GetRanges(ISymbolDocument document,
                        int line,
                        int column)
 {
     int cRanges = 0;
     m_unmanagedMethod.GetRanges(((SymbolDocument) document).InternalDocument, line, column, 0, out cRanges, null);
     var Ranges = new int[cRanges];
     m_unmanagedMethod.GetRanges(((SymbolDocument) document).InternalDocument, line, column, cRanges, out cRanges,
                                 Ranges);
     return Ranges;
 }