|
|
|
@ -48,6 +48,14 @@ namespace Debugger
@@ -48,6 +48,14 @@ namespace Debugger
|
|
|
|
|
this.StartLine, this.StartColumn, |
|
|
|
|
this.EndLine, this.EndColumn); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public bool ContainsLocation(int line, int column = 0) |
|
|
|
|
{ |
|
|
|
|
if (column == 0) |
|
|
|
|
return line >= StartLine && line <= EndLine; |
|
|
|
|
return (StartLine < line || (StartLine == line && StartColumn <= column)) |
|
|
|
|
&& (line < EndLine || (line == EndLine && column <= EndColumn)); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public struct ILRange |
|
|
|
@ -185,14 +193,14 @@ namespace Debugger
@@ -185,14 +193,14 @@ namespace Debugger
|
|
|
|
|
var realSeqPoints = sequencePoints.Where(p => p.StartLine != 0xFEEFEE); |
|
|
|
|
|
|
|
|
|
// Find point for which (ilstart <= iloffset < ilend) or fallback to the next valid sequence point
|
|
|
|
|
var sequencePoint = realSeqPoints.FirstOrDefault(p => p.ILRanges.Any(r => r.From <= iloffset && iloffset < r.To)) ?? |
|
|
|
|
realSeqPoints.FirstOrDefault(p => iloffset <= p.ILOffset); |
|
|
|
|
var sequencePoint = realSeqPoints.FirstOrDefault(p => p.ILRanges.Any(r => r.From <= iloffset && iloffset < r.To)) |
|
|
|
|
?? realSeqPoints.FirstOrDefault(p => iloffset <= p.ILOffset); |
|
|
|
|
|
|
|
|
|
if (sequencePoint != null) { |
|
|
|
|
// VB.NET sometimes produces temporary files which it then deletes
|
|
|
|
|
// (eg 17d14f5c-a337-4978-8281-53493378c1071.vb)
|
|
|
|
|
string name = Path.GetFileName(sequencePoint.Filename); |
|
|
|
|
if (name.Length == 40 && name.EndsWith(".vb")) { |
|
|
|
|
if (name.Length == 40 && name.EndsWith(".vb", StringComparison.OrdinalIgnoreCase)) { |
|
|
|
|
if (name.Substring(0, name.Length - 3).All(c => ('0' <= c && c <= '9') || ('a' <= c && c <= 'f') || ('A' <= c && c <= 'F') || (c == '-'))) { |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
@ -232,19 +240,47 @@ namespace Debugger
@@ -232,19 +240,47 @@ namespace Debugger
|
|
|
|
|
|
|
|
|
|
foreach (ISymUnmanagedMethod symMethod in symMethods) { |
|
|
|
|
var corFunction = module.CorModule.GetFunctionFromToken(symMethod.GetToken()); |
|
|
|
|
int codesize = (int)corFunction.GetILCode().GetSize(); |
|
|
|
|
var seqPoints = symMethod.GetSequencePoints(codesize).Where(s => s.StartLine != 0xFEEFEE); |
|
|
|
|
SequencePoint seqPoint = null; |
|
|
|
|
if (column != 0) { |
|
|
|
|
seqPoint = seqPoints.FirstOrDefault(s => (s.StartLine < line || (s.StartLine == line && s.StartColumn <= column)) && |
|
|
|
|
(line < s.EndLine || (line == s.EndLine && column <= s.EndColumn))); |
|
|
|
|
} |
|
|
|
|
seqPoint = seqPoint ?? seqPoints.FirstOrDefault(s => line <= s.StartLine); |
|
|
|
|
int codeSize = (int)corFunction.GetILCode().GetSize(); |
|
|
|
|
var seqPoints = symMethod.GetSequencePoints(codeSize).Where(s => s.StartLine != 0xFEEFEE).OrderBy(s => s.StartLine).ToArray(); |
|
|
|
|
SequencePoint seqPoint = FindNearestMatchingSequencePoint(seqPoints, line, column); |
|
|
|
|
if (seqPoint != null) |
|
|
|
|
yield return seqPoint; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
SequencePoint FindNearestMatchingSequencePoint(SequencePoint[] seqPoints, int line, int column) |
|
|
|
|
{ |
|
|
|
|
// value is nearest offset in lines;
|
|
|
|
|
// negative numbers: (Start|End)Line is same as line, value is offset in columns
|
|
|
|
|
int nearestOffset = 0; |
|
|
|
|
SequencePoint bestMatch = null; |
|
|
|
|
for (int i = 0; i < seqPoints.Length; i++) { |
|
|
|
|
var s = seqPoints[i]; |
|
|
|
|
if (s.ContainsLocation(line, column)) |
|
|
|
|
return seqPoints[i]; |
|
|
|
|
|
|
|
|
|
if (bestMatch == null) { |
|
|
|
|
bestMatch = s; |
|
|
|
|
nearestOffset = GetOffsetValue(s, line, column); |
|
|
|
|
} else { |
|
|
|
|
int newOffset = GetOffsetValue(s, line, column); |
|
|
|
|
if ((newOffset < 0 && nearestOffset < 0 && newOffset > nearestOffset) || (newOffset < nearestOffset)) { |
|
|
|
|
bestMatch = s; |
|
|
|
|
nearestOffset = newOffset; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return bestMatch; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int GetOffsetValue(SequencePoint s, int line, int column) |
|
|
|
|
{ |
|
|
|
|
if (line == s.StartLine || s.EndLine == line) |
|
|
|
|
return -Math.Min(Math.Abs(s.StartColumn - column), Math.Abs(s.EndColumn - column)); |
|
|
|
|
return Math.Min(Math.Abs(s.StartLine - line), Math.Abs(s.EndLine - line)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public IEnumerable<ILRange> GetIgnoredILRanges(IMethod method) |
|
|
|
|
{ |
|
|
|
|
var symMethod = method.GetSymMethod(); |
|
|
|
|