/// <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="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 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); }