private int?GetLineWithPossibleBreakpoint(SourceFileInfo sourceFile, int startLine) { if (sourceFile.PossibleBreakpointLocationsByLine.ContainsKey(startLine)) { return(startLine); } return(sourceFile.PossibleBreakpointLocationsByLine.Keys.FirstOrDefault(l => l >= startLine)); }
private void AddPdb(string moduleName, MetadataReader peMetadataReader, MetadataReader pdbMetadataReader) { // Add all the documents (source files) var tempDocNameToSourceFileMap = new Dictionary <string, SourceFileInfo>(); foreach (var docHandle in pdbMetadataReader.Documents) { var doc = pdbMetadataReader.GetDocument(docHandle); var docRawName = pdbMetadataReader.GetString(doc.Name); var filenameWithForwardSlashes = docRawName.Replace('\\', '/'); var url = $"{DotnetSourceFilePrefix}//{moduleName}/{filenameWithForwardSlashes}"; var sourceFile = new SourceFileInfo { Id = $"{DotnetSourceFilePrefix}{nextSourceFileId++}", AssemblyName = moduleName, FileName = filenameWithForwardSlashes, Url = url, PossibleBreakpointLocationsByLine = new Dictionary <int, List <PossibleBreakpointLocation> >() }; _sourceFiles.Add(sourceFile.Id, sourceFile); tempDocNameToSourceFileMap.Add(docRawName, sourceFile); } // Add all the debug sequence points foreach (var methodDebugInfoHandle in pdbMetadataReader.MethodDebugInformation) { var methodDebugInfo = pdbMetadataReader.GetMethodDebugInformation(methodDebugInfoHandle); var methodDefHandle = methodDebugInfoHandle.ToDefinitionHandle(); var methodDef = peMetadataReader.GetMethodDefinition(methodDefHandle); var document = pdbMetadataReader.GetDocument(methodDebugInfo.Document); string documentName = null; try { documentName = pdbMetadataReader.GetString(document.Name); } catch (Exception) { // If the document name isn't readable, don't process it } if (documentName != null && tempDocNameToSourceFileMap.TryGetValue(documentName, out var sourceFile)) { // Construct the DNA method identifier string var methodDefToken = MetadataTokens.GetToken(methodDefHandle); var methodDebugInfoToken = MetadataTokens.GetToken(methodDefHandle); var declaringType = peMetadataReader.GetTypeDefinition(methodDef.GetDeclaringType()); var namespaceName = peMetadataReader.GetString(declaringType.Namespace); var className = peMetadataReader.GetString(declaringType.Name); var methodName = peMetadataReader.GetString(methodDef.Name); var dnaMethodIdentifier = moduleName + namespaceName + className + methodName; // Add PossibleBreakpointLocation objects to the sourcefile int sequencePointIndex = 0; foreach (var sequencePoint in methodDebugInfo.GetSequencePoints().Where(sp => !sp.IsHidden)) { var possibleBreakpointLocations = sourceFile.PossibleBreakpointLocationsByLine; var lineNumber = sequencePoint.StartLine; if (!possibleBreakpointLocations.TryGetValue(lineNumber, out _)) { possibleBreakpointLocations.Add(lineNumber, new List <PossibleBreakpointLocation>()); } possibleBreakpointLocations[lineNumber].Add(new PossibleBreakpointLocation { DnaMethodIdentifier = dnaMethodIdentifier, SequencePointIndex = sequencePointIndex, SequencePointInfo = sequencePoint, MethodName = methodName, SourceFile = sourceFile, }); sequencePointIndex++; } } } }
public PossibleBreakpointLocation GetClosestBreakpointLocation(SourceFileInfo script, int lineNumber, int columnNumber) { var candidates = GetBreakpointLocations(script.Id, lineNumber); return(candidates.FirstOrDefault(loc => loc.SequencePointInfo.StartLine >= lineNumber && loc.SequencePointInfo.StartColumn >= columnNumber)); }
internal PossibleBreakpointLocation FindBreakpointUsingDnaData(string dnaLocationId, int ilOffset, out SourceFileInfo inSourceFile) { // TODO: Find a more efficient way of looking this up. Might just need to maintain // a lookup from dnaLocationId to sourcefiles foreach (var sourceFile in _sourceFiles.Values) { foreach (var breakpointCollections in sourceFile.PossibleBreakpointLocationsByLine.Values) { foreach (var breakpoint in breakpointCollections) { if (breakpoint.DnaMethodIdentifier == dnaLocationId && breakpoint.SequencePointInfo.Offset == ilOffset) { inSourceFile = sourceFile; return(breakpoint); } } } } inSourceFile = null; return(null); }