/// <summary> /// Returns method token and IL offset for given source line number. /// </summary> /// <param name="assemblyFileName">file name of the assembly</param> /// <param name="fileName">source file name</param> /// <param name="lineNumber">source line number</param> /// <param name="methToken">method token return</param> /// <param name="ilOffset">IL offset return</param> public static void ResolveSequencePoint(string assemblyFileName, string fileName, int lineNumber, out int methToken, out int ilOffset) { MetadataReader peReader, pdbReader; methToken = 0; ilOffset = 0; if (!GetReaders(assemblyFileName, out peReader, out pdbReader)) { return; } foreach (MethodDefinitionHandle methodDefHandle in peReader.MethodDefinitions) { MethodDebugInformation methodDebugInfo = pdbReader.GetMethodDebugInformation(methodDefHandle); SequencePointCollection sequencePoints = methodDebugInfo.GetSequencePoints(); foreach (SequencePoint point in sequencePoints) { string sourceName = pdbReader.GetString(pdbReader.GetDocument(point.Document).Name); if (Path.GetFileName(sourceName) == Path.GetFileName(fileName) && point.StartLine == lineNumber) { methToken = MetadataTokens.GetToken(peReader, methodDefHandle); ilOffset = point.Offset; return; } } } }
/// <summary> /// Returns method token and IL offset for given source line number. /// </summary> /// <param name="filePath">source file name and path</param> /// <param name="lineNumber">source line number</param> /// <param name="methodToken">method token return</param> /// <param name="ilOffset">IL offset return</param> /// <returns>true if information is available</returns> public bool ResolveSequencePoint( string filePath, int lineNumber, out int methodToken, out int ilOffset) { methodToken = 0; ilOffset = 0; try { string fileName = SymbolService.GetFileName(filePath); foreach (MethodDebugInformationHandle methodDebugInformationHandle in _reader.MethodDebugInformation) { MethodDebugInformation methodDebugInfo = _reader.GetMethodDebugInformation(methodDebugInformationHandle); SequencePointCollection sequencePoints = methodDebugInfo.GetSequencePoints(); foreach (SequencePoint point in sequencePoints) { string sourceName = _reader.GetString(_reader.GetDocument(point.Document).Name); if (point.StartLine == lineNumber && SymbolService.GetFileName(sourceName) == fileName) { methodToken = MetadataTokens.GetToken(methodDebugInformationHandle.ToDefinitionHandle()); ilOffset = point.Offset; return(true); } } } } catch (Exception ex) { Trace.TraceError($"ResolveSequencePoint: {ex.Message}"); } return(false); }
/// <summary> /// Returns method token and IL offset for given source line number. /// </summary> /// <param name="symbolReaderHandle">symbol reader handle returned by LoadSymbolsForModule</param> /// <param name="filePath">source file name and path</param> /// <param name="lineNumber">source line number</param> /// <param name="methodToken">method token return</param> /// <param name="ilOffset">IL offset return</param> /// <returns> true if information is available</returns> internal static bool ResolveSequencePoint(IntPtr symbolReaderHandle, string filePath, int lineNumber, out int methodToken, out int ilOffset) { Debug.Assert(symbolReaderHandle != IntPtr.Zero); methodToken = 0; ilOffset = 0; GCHandle gch = GCHandle.FromIntPtr(symbolReaderHandle); MetadataReader reader = ((OpenedReader)gch.Target).Reader; try { string fileName = Path.GetFileName(filePath); foreach (MethodDebugInformationHandle methodDebugInformationHandle in reader.MethodDebugInformation) { MethodDebugInformation methodDebugInfo = reader.GetMethodDebugInformation(methodDebugInformationHandle); SequencePointCollection sequencePoints = methodDebugInfo.GetSequencePoints(); foreach (SequencePoint point in sequencePoints) { string sourceName = reader.GetString(reader.GetDocument(point.Document).Name); if (point.StartLine == lineNumber && Path.GetFileName(sourceName) == fileName) { methodToken = MetadataTokens.GetToken(methodDebugInformationHandle.ToDefinitionHandle()); ilOffset = point.Offset; return(true); } } } } catch { } return(false); }
private void AddFunctionSourceLines(Function function, SequencePointCollection points, MetadataReader pdbReader) { var slines = new List <SourceLine>(); function.SourceLines = slines; foreach (var p in points) { try { var sname = pdbReader.GetString(pdbReader.GetDocument(p.Document).Name); var plSourceLine = new SourceLine { InternalId = SourceLine.UndefinedSourceLineId, SourceFileIntId = GetSourceFileId(sname), FunctionIntId = function.InternalId, StartLine = (ulong)p.StartLine, StartColumn = (ulong)p.StartColumn, EndLine = (ulong)p.EndLine, EndColumn = (ulong)p.EndColumn, Offset = (uint)p.Offset, Name = sname }; slines.Add(plSourceLine); } catch (Exception) { // Debug.WriteLine(ex.Message); } } }
public void GetSourceLineInfoWithoutCasAssert(string assemblyPath, IntPtr loadedPeAddress, int loadedPeSize, IntPtr inMemoryPdbAddress, int inMemoryPdbSize, int methodToken, int ilOffset, out string sourceFile, out int sourceLine, out int sourceColumn) { sourceFile = null; sourceLine = 0; sourceColumn = 0; try { MetadataReader reader = TryGetReader(assemblyPath, loadedPeAddress, loadedPeSize, inMemoryPdbAddress, inMemoryPdbSize); if (reader == null) { return; } Handle handle = MetadataTokens.Handle(methodToken); if (handle.Kind != HandleKind.MethodDefinition) { return; } MethodDebugInformationHandle methodDebugHandle = ((MethodDefinitionHandle)handle).ToDebugInformationHandle(); MethodDebugInformation methodInfo = reader.GetMethodDebugInformation(methodDebugHandle); if (!methodInfo.SequencePointsBlob.IsNil) { SequencePointCollection sequencePoints = methodInfo.GetSequencePoints(); SequencePoint?bestPointSoFar = null; foreach (SequencePoint point in sequencePoints) { if (point.Offset > ilOffset) { break; } if (point.StartLine != SequencePoint.HiddenLine) { bestPointSoFar = point; } } if (bestPointSoFar.HasValue) { sourceLine = bestPointSoFar.Value.StartLine; sourceColumn = bestPointSoFar.Value.StartColumn; sourceFile = reader.GetString(reader.GetDocument(bestPointSoFar.Value.Document).Name); } } } catch (BadImageFormatException) { // ignore } catch (IOException) { // ignore } }
private void WriteSequencePoints(List <SequencePoint> spData) { // Construct a mapping from file ID to sequence point data Dictionary <int, SequencePointCollection> dataByFile = new Dictionary <int, SequencePointCollection>(); foreach (int fileRef in m_docWriters.Keys) { dataByFile.Add(fileRef, new SequencePointCollection()); } // Read all the sequence points and group them by fileID // Note that we don't want to assume that all entries for one file will come together, so we can't just // write them out as we go. foreach (SequencePoint sp in spData) { dataByFile[sp.sourceId].Add(sp.ilOffset, sp.startRow, sp.startColumn, sp.endRow, sp.endColumn); } // Now write them all out one document at a time foreach (KeyValuePair <int, ISymbolDocumentWriter> docEntry in m_docWriters) { SequencePointCollection seq = dataByFile[docEntry.Key]; if (seq.ILOffsets.Count > 0) { m_writer.DefineSequencePoints( docEntry.Value, seq.ILOffsets.ToArray(), seq.StartRows.ToArray(), seq.StartColumns.ToArray(), seq.EndRows.ToArray(), seq.EndColumns.ToArray()); } } }
/// <summary> /// Helper method to return source line number and source file name for given IL offset and method token. /// </summary> /// <param name="symbolReaderHandle">symbol reader handle returned by LoadSymbolsForModule</param> /// <param name="methodToken">method token</param> /// <param name="ilOffset">IL offset</param> /// <param name="lineNumber">source line number return</param> /// <param name="fileName">source file name return</param> /// <returns> true if information is available</returns> private static bool GetSourceLineByILOffset(IntPtr symbolReaderHandle, int methodToken, long ilOffset, out int lineNumber, out string fileName) { Debug.Assert(symbolReaderHandle != IntPtr.Zero); lineNumber = 0; fileName = null; GCHandle gch = GCHandle.FromIntPtr(symbolReaderHandle); MetadataReader reader = ((OpenedReader)gch.Target).Reader; try { Handle handle = MetadataTokens.Handle(methodToken); if (handle.Kind != HandleKind.MethodDefinition) { return(false); } MethodDebugInformationHandle methodDebugHandle = ((MethodDefinitionHandle)handle).ToDebugInformationHandle(); if (methodDebugHandle.IsNil) { return(false); } MethodDebugInformation methodDebugInfo = reader.GetMethodDebugInformation(methodDebugHandle); SequencePointCollection sequencePoints = methodDebugInfo.GetSequencePoints(); SequencePoint nearestPoint = sequencePoints.GetEnumerator().Current; foreach (SequencePoint point in sequencePoints) { if (point.Offset < ilOffset) { nearestPoint = point; } else { if (point.Offset == ilOffset) { nearestPoint = point; } if (nearestPoint.StartLine == 0 || nearestPoint.StartLine == SequencePoint.HiddenLine) { return(false); } break; } } lineNumber = nearestPoint.StartLine; fileName = reader.GetString(reader.GetDocument(nearestPoint.Document).Name); return(true); } catch { } return(false); }
/// <summary> /// Helper method to return source line number and source file name for given IL offset and method token. /// </summary> /// <param name="openedReader">symbol reader returned by LoadSymbolsForModule</param> /// <param name="methodToken">method token</param> /// <param name="ilOffset">IL offset</param> /// <param name="lineNumber">source line number return</param> /// <param name="fileName">source file name return</param> /// <returns> true if information is available</returns> private bool GetSourceLineByILOffset( OpenedReader openedReader, int methodToken, long ilOffset, out int lineNumber, out string fileName) { lineNumber = 0; fileName = null; MetadataReader reader = openedReader.Reader; try { Handle handle = MetadataTokens.Handle(methodToken); if (handle.Kind != HandleKind.MethodDefinition) { return(false); } MethodDebugInformationHandle methodDebugHandle = ((MethodDefinitionHandle)handle).ToDebugInformationHandle(); if (methodDebugHandle.IsNil) { return(false); } MethodDebugInformation methodDebugInfo = reader.GetMethodDebugInformation(methodDebugHandle); SequencePointCollection sequencePoints = methodDebugInfo.GetSequencePoints(); SequencePoint?nearestPoint = null; foreach (SequencePoint point in sequencePoints) { if (point.Offset > ilOffset) { break; } if (point.StartLine != 0 && !point.IsHidden) { nearestPoint = point; } } if (nearestPoint.HasValue) { lineNumber = nearestPoint.Value.StartLine; fileName = reader.GetString(reader.GetDocument(nearestPoint.Value.Document).Name); return(true); } } catch (Exception ex) { Trace.TraceError($"GetSourceLineByILOffset: {ex.Message}"); } return(false); }
/// <summary> /// Helper method to return source line number and source file name for given IL offset and method token. /// </summary> /// <param name="assemblyFileName">file name of the assembly</param> /// <param name="methToken">method token</param> /// <param name="ilOffset">IL offset</param> /// <param name="lineNumber">source line number return</param> /// <param name="fileName">source file name return</param> /// <returns> true if information is available</returns> private static bool GetSourceLineByILOffset(string assemblyFileName, int methodToken, long ilOffset, out int lineNumber, out string fileName) { MetadataReader peReader, pdbReader; lineNumber = 0; fileName = null; try { if (!GetReaders(assemblyFileName, out peReader, out pdbReader)) { return(false); } Handle handle = MetadataTokens.Handle(methodToken); if (handle.Kind != HandleKind.MethodDefinition) { return(false); } MethodDebugInformationHandle methodDebugHandle = ((MethodDefinitionHandle)handle).ToDebugInformationHandle(); MethodDebugInformation methodDebugInfo = pdbReader.GetMethodDebugInformation(methodDebugHandle); SequencePointCollection sequencePoints = methodDebugInfo.GetSequencePoints(); SequencePoint nearestPoint = sequencePoints.GetEnumerator().Current; foreach (SequencePoint point in sequencePoints) { if (point.Offset < ilOffset) { nearestPoint = point; } else { if (point.Offset == ilOffset) { nearestPoint = point; } if (nearestPoint.StartLine == 0 || nearestPoint.StartLine == SequencePoint.HiddenLine) { return(false); } lineNumber = nearestPoint.StartLine; fileName = pdbReader.GetString(pdbReader.GetDocument(nearestPoint.Document).Name); return(true); } } return(false); } finally { peReader = null; pdbReader = null; } }
/// <summary> /// Returns the source file and line number information for the method. /// </summary> /// <param name="assembly">managed assembly</param> /// <param name="assemblyPath">file path of the assembly or null</param> /// <param name="loadedPeAddress">loaded PE image address or zero</param> /// <param name="loadedPeSize">loaded PE image size</param> /// <param name="inMemoryPdbAddress">in memory PDB address or zero</param> /// <param name="inMemoryPdbSize">in memory PDB size</param> /// <param name="methodToken">method token</param> /// <param name="ilOffset">il offset of the stack frame</param> /// <param name="sourceFile">source file return</param> /// <param name="sourceLine">line number return</param> /// <param name="sourceColumn">column return</param> internal void GetSourceLineInfo(Assembly assembly, string assemblyPath, IntPtr loadedPeAddress, int loadedPeSize, IntPtr inMemoryPdbAddress, int inMemoryPdbSize, int methodToken, int ilOffset, out string?sourceFile, out int sourceLine, out int sourceColumn) { sourceFile = null; sourceLine = 0; sourceColumn = 0; MetadataReader?reader = TryGetReader(assembly, assemblyPath, loadedPeAddress, loadedPeSize, inMemoryPdbAddress, inMemoryPdbSize); if (reader != null) { Handle handle = MetadataTokens.Handle(methodToken); if (handle.Kind == HandleKind.MethodDefinition) { MethodDebugInformationHandle methodDebugHandle = ((MethodDefinitionHandle)handle).ToDebugInformationHandle(); MethodDebugInformation methodInfo = reader.GetMethodDebugInformation(methodDebugHandle); if (!methodInfo.SequencePointsBlob.IsNil) { SequencePointCollection sequencePoints = methodInfo.GetSequencePoints(); SequencePoint?bestPointSoFar = null; foreach (SequencePoint point in sequencePoints) { if (point.Offset > ilOffset) { break; } if (point.StartLine != SequencePoint.HiddenLine) { bestPointSoFar = point; } } if (bestPointSoFar.HasValue) { sourceLine = bestPointSoFar.Value.StartLine; sourceColumn = bestPointSoFar.Value.StartColumn; sourceFile = reader.GetString(reader.GetDocument(bestPointSoFar.Value.Document).Name); } } } } }
/// <summary> /// Helper method to return source name, line numbers and IL offsets for given method token. /// </summary> /// <param name="assemblyPath">file path of the assembly</param> /// <param name="methodToken">method token</param> /// <param name="points">list of debug information for each sequence point return</param> /// <returns>true if information is available</returns> /// <remarks>used by the gdb JIT support (not SOS). Does not support in-memory PEs or PDBs</remarks> private static bool GetDebugInfoForMethod(string assemblyPath, int methodToken, out List <DebugInfo> points) { points = null; OpenedReader openedReader = GetReader(assemblyPath, isFileLayout: true, peStream: null, pdbStream: null); if (openedReader == null) { return(false); } using (openedReader) { try { Handle handle = MetadataTokens.Handle(methodToken); if (handle.Kind != HandleKind.MethodDefinition) { return(false); } points = new List <DebugInfo>(); MethodDebugInformationHandle methodDebugHandle = ((MethodDefinitionHandle)handle).ToDebugInformationHandle(); MethodDebugInformation methodDebugInfo = openedReader.Reader.GetMethodDebugInformation(methodDebugHandle); SequencePointCollection sequencePoints = methodDebugInfo.GetSequencePoints(); foreach (SequencePoint point in sequencePoints) { if (point.StartLine == 0 || point.StartLine == SequencePoint.HiddenLine) { continue; } DebugInfo debugInfo = new DebugInfo(); debugInfo.lineNumber = point.StartLine; debugInfo.fileName = openedReader.Reader.GetString(openedReader.Reader.GetDocument(point.Document).Name); debugInfo.ilOffset = point.Offset; points.Add(debugInfo); } } catch { return(false); } } return(true); }
/// <summary> /// Helper method to return source name, line numbers and IL offsets for given method token. /// </summary> /// <param name="assemblyFileName">file name of the assembly</param> /// <param name="methToken">method token</param> /// <param name="pints">List of debug information for each sequence point return</param> /// <returns> true if information is available</returns> private static bool GetDebugInfoForMethod(string assemblyFileName, int methodToken, out List <DebugInfo> points) { MetadataReader peReader, pdbReader; points = null; try { if (!GetReaders(assemblyFileName, out peReader, out pdbReader)) { return(false); } Handle handle = MetadataTokens.Handle(methodToken); if (handle.Kind != HandleKind.MethodDefinition) { return(false); } points = new List <DebugInfo>(); MethodDebugInformationHandle methodDebugHandle = ((MethodDefinitionHandle)handle).ToDebugInformationHandle(); MethodDebugInformation methodDebugInfo = pdbReader.GetMethodDebugInformation(methodDebugHandle); SequencePointCollection sequencePoints = methodDebugInfo.GetSequencePoints(); foreach (SequencePoint point in sequencePoints) { if (point.StartLine == 0 || point.StartLine == SequencePoint.HiddenLine) { continue; } DebugInfo debugInfo = new DebugInfo(); debugInfo.lineNumber = point.StartLine; debugInfo.fileName = pdbReader.GetString(pdbReader.GetDocument(point.Document).Name); debugInfo.ilOffset = point.Offset; points.Add(debugInfo); } return(true); } finally { peReader = null; pdbReader = null; } }
/// <summary> /// Returns method token and IL offset for given source line number. /// </summary> /// <param name="symbolReaderHandle">symbol reader handle returned by LoadSymbolsForModule</param> /// <param name="filePath">source file name and path</param> /// <param name="lineNumber">source line number</param> /// <param name="methodToken">method token return</param> /// <param name="ilOffset">IL offset return</param> /// <returns> true if information is available</returns> internal static bool ResolveSequencePoint(IntPtr symbolReaderHandle, [MarshalAs(UnmanagedType.LPWStr)] string filePath, int lineNumber, out int methodToken, out int ilOffset) { Debug.Assert(symbolReaderHandle != IntPtr.Zero); methodToken = 0; ilOffset = 0; GCHandle gch = GCHandle.FromIntPtr(symbolReaderHandle); MetadataReader reader = ((OpenedReader)gch.Target).Reader; try { Func <string, bool> FileNameMatches; bool isWindows = System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(OSPlatform.Windows); FileNameMatches = s => s.Equals(filePath, isWindows ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal); foreach (MethodDebugInformationHandle methodDebugInformationHandle in reader.MethodDebugInformation) { MethodDebugInformation methodDebugInfo = reader.GetMethodDebugInformation(methodDebugInformationHandle); SequencePointCollection sequencePoints = methodDebugInfo.GetSequencePoints(); foreach (SequencePoint point in sequencePoints) { string sourceName = reader.GetString(reader.GetDocument(point.Document).Name); if (point.StartLine == lineNumber && FileNameMatches(sourceName)) { methodToken = MetadataTokens.GetToken(methodDebugInformationHandle.ToDefinitionHandle()); ilOffset = point.Offset; return(true); } } } } catch { } return(false); }
public Method () { m_scopes = new ScopeCollection (this); m_documents = new DocumentCollection (this); m_sequencePoints = new SequencePointCollection (this); }
// https://github.com/dotnet/corefx/blob/9802644d90aa7fe6aba6d621724a307212303d08/src/System.Diagnostics.StackTrace.Symbols/src/System/Diagnostics/StackTrace/Symbols.cs private static void GetSourceLineInfo(MetadataReader reader, int methodToken, int ilOffset, out string sourceFile, out int sourceLine, out int sourceColumn) { sourceFile = null; sourceLine = 0; sourceColumn = 0; if (reader != null) { Handle handle = MetadataTokens.Handle(methodToken); if (handle.Kind == HandleKind.MethodDefinition) { MethodDebugInformationHandle methodDebugHandle = ((MethodDefinitionHandle)handle).ToDebugInformationHandle(); MethodDebugInformation methodInfo = reader.GetMethodDebugInformation(methodDebugHandle); if (!methodInfo.SequencePointsBlob.IsNil) { try { SequencePointCollection sequencePoints = methodInfo.GetSequencePoints(); int sequencePointCount = 0; foreach (SequencePoint sequence in sequencePoints) { sequencePointCount++; } if (sequencePointCount > 0) { int[] offsets = new int[sequencePointCount]; int[] lines = new int[sequencePointCount]; int[] columns = new int[sequencePointCount]; DocumentHandle[] documents = new DocumentHandle[sequencePointCount]; int i = 0; foreach (SequencePoint sequence in sequencePoints) { offsets[i] = sequence.Offset; lines[i] = sequence.StartLine; columns[i] = sequence.StartColumn; documents[i] = sequence.Document; i++; } // Search for the correct IL offset int j; for (j = 0; j < sequencePointCount; j++) { // look for the entry matching the one we're looking for if (offsets[j] >= ilOffset) { // if this offset is > what we're looking for, ajdust the index if (offsets[j] > ilOffset && j > 0) { j--; } break; } } // If we didn't find a match, default to the last sequence point if (j == sequencePointCount) { j--; } while (lines[j] == SequencePoint.HiddenLine && j > 0) { j--; } if (lines[j] != SequencePoint.HiddenLine) { sourceLine = lines[j]; sourceColumn = columns[j]; } var doc = reader.GetDocument(documents[j]); sourceFile = reader.GetString(doc.Name); } } catch { } } } } }
internal static bool GetStepRangesFromIP(IntPtr symbolReaderHandle, int ip, int methodToken, out uint ilStartOffset, out uint ilEndOffset) { Debug.Assert(symbolReaderHandle != IntPtr.Zero); ilStartOffset = 0; ilEndOffset = 0; Debug.Assert(symbolReaderHandle != IntPtr.Zero); GCHandle gch = GCHandle.FromIntPtr(symbolReaderHandle); MetadataReader reader = ((OpenedReader)gch.Target).Reader; try { Handle handle = MetadataTokens.Handle(methodToken); if (handle.Kind != HandleKind.MethodDefinition) { return(false); } MethodDebugInformationHandle methodDebugHandle = ((MethodDefinitionHandle)handle).ToDebugInformationHandle(); if (methodDebugHandle.IsNil) { return(false); } MethodDebugInformation methodDebugInfo = reader.GetMethodDebugInformation(methodDebugHandle); SequencePointCollection sequencePoints = methodDebugInfo.GetSequencePoints(); var list = new List <SequencePoint>(); foreach (SequencePoint p in sequencePoints) { list.Add(p); } var pointsArray = list.ToArray(); for (int i = 1; i < pointsArray.Length; i++) { SequencePoint p = pointsArray[i]; if (p.Offset > ip && p.StartLine != 0 && p.StartLine != SequencePoint.HiddenLine) { ilStartOffset = (uint)pointsArray[0].Offset; for (int j = i - 1; j > 0; j--) { if (pointsArray[j].Offset <= ip) { ilStartOffset = (uint)pointsArray[j].Offset; break; } } ilEndOffset = (uint)p.Offset; return(true); } } // let's handle correctly last step range from last sequence point till // end of the method. if (pointsArray.Length > 0) { ilStartOffset = (uint)pointsArray[0].Offset; for (int j = pointsArray.Length - 1; j > 0; j--) { if (pointsArray[j].Offset <= ip) { ilStartOffset = (uint)pointsArray[j].Offset; break; } } ilEndOffset = ilStartOffset; // Should set this to IL code size in calling code return(true); } } catch { } return(false); }
internal static bool GetSequencePoints(IntPtr symbolReaderHandle, int methodToken, out IntPtr points, out int pointsCount) { Debug.Assert(symbolReaderHandle != IntPtr.Zero); pointsCount = 0; points = IntPtr.Zero; Debug.Assert(symbolReaderHandle != IntPtr.Zero); GCHandle gch = GCHandle.FromIntPtr(symbolReaderHandle); MetadataReader reader = ((OpenedReader)gch.Target).Reader; try { Handle handle = MetadataTokens.Handle(methodToken); if (handle.Kind != HandleKind.MethodDefinition) { return(false); } MethodDebugInformationHandle methodDebugHandle = ((MethodDefinitionHandle)handle).ToDebugInformationHandle(); if (methodDebugHandle.IsNil) { return(false); } MethodDebugInformation methodDebugInfo = reader.GetMethodDebugInformation(methodDebugHandle); SequencePointCollection sequencePoints = methodDebugInfo.GetSequencePoints(); var list = new List <DbgSequencePoint>(); foreach (SequencePoint p in sequencePoints) { list.Add(new DbgSequencePoint() { startLine = p.StartLine, endLine = p.EndLine, startColumn = p.StartColumn, endColumn = p.EndColumn, offset = p.Offset }); } if (list.Count == 0) { return(true); } var structSize = Marshal.SizeOf <DbgSequencePoint>(); IntPtr allPoints = Marshal.AllocCoTaskMem(list.Count * structSize); var currentPtr = allPoints; foreach (var p in list) { Marshal.StructureToPtr(p, currentPtr, false); currentPtr = (IntPtr)(currentPtr.ToInt64() + structSize); } points = allPoints; pointsCount = list.Count; return(true); } catch { } return(false); }
/// <summary> /// Returns source line number and source file name for given IL offset and method token. /// </summary> /// <param name="symbolReaderHandle">symbol reader handle returned by LoadSymbolsForModule</param> /// <param name="methodToken">method token</param> /// <param name="ilOffset">IL offset</param> /// <param name="sequencePoint">sequence point return</param> /// <returns> true if information is available</returns> private static bool GetSequencePointByILOffset(IntPtr symbolReaderHandle, int methodToken, long ilOffset, out DbgSequencePoint sequencePoint) { Debug.Assert(symbolReaderHandle != IntPtr.Zero); sequencePoint.document = IntPtr.Zero; sequencePoint.startLine = 0; sequencePoint.startColumn = 0; sequencePoint.endLine = 0; sequencePoint.endColumn = 0; sequencePoint.offset = 0; try { GCHandle gch = GCHandle.FromIntPtr(symbolReaderHandle); MetadataReader reader = ((OpenedReader)gch.Target).Reader; Handle handle = MetadataTokens.Handle(methodToken); if (handle.Kind != HandleKind.MethodDefinition) { return(false); } MethodDebugInformationHandle methodDebugHandle = ((MethodDefinitionHandle)handle).ToDebugInformationHandle(); if (methodDebugHandle.IsNil) { return(false); } MethodDebugInformation methodDebugInfo = reader.GetMethodDebugInformation(methodDebugHandle); SequencePointCollection sequencePoints = methodDebugInfo.GetSequencePoints(); SequencePoint nearestPoint = sequencePoints.GetEnumerator().Current; bool found = false; foreach (SequencePoint point in sequencePoints) { if (found && point.Offset > ilOffset) { break; } if (!point.IsHidden) { nearestPoint = point; found = true; } } if (!found || nearestPoint.StartLine == 0) { return(false); } var fileName = reader.GetString(reader.GetDocument(nearestPoint.Document).Name); sequencePoint.document = Marshal.StringToBSTR(fileName); sequencePoint.startLine = nearestPoint.StartLine; sequencePoint.startColumn = nearestPoint.StartColumn; sequencePoint.endLine = nearestPoint.EndLine; sequencePoint.endColumn = nearestPoint.EndColumn; sequencePoint.offset = nearestPoint.Offset; fileName = null; return(true); } catch { } return(false); }
public SymbolMethod(SequencePointCollection sequencePoints, SymbolToken token) { _sequencePoints = sequencePoints.ToList(); _token = token; }
public Method() { m_scopes = new ScopeCollection(this); m_documents = new DocumentCollection(this); m_sequencePoints = new SequencePointCollection(this); }