Browse Source

fix calculation of sequence points for breakpoints in pdb files

pull/520/merge
Siegfried Pammer 11 years ago
parent
commit
e152b747dd
  1. 2
      src/AddIns/Debugger/Debugger.Core/Breakpoint.cs
  2. 58
      src/AddIns/Debugger/Debugger.Core/PdbSymbolSource.cs

2
src/AddIns/Debugger/Debugger.Core/Breakpoint.cs

@ -84,7 +84,7 @@ namespace Debugger @@ -84,7 +84,7 @@ namespace Debugger
public void SetBreakpoint(Module module)
{
foreach(var symbolSource in module.Process.Debugger.SymbolSources) {
foreach (var symbolSource in module.Process.Debugger.SymbolSources) {
foreach (var seq in symbolSource.GetSequencePoints(module, this.FileName, this.Line, this.Column)) {
ICorDebugFunction corFunction = module.CorModule.GetFunctionFromToken(seq.MethodDefToken);
ICorDebugFunctionBreakpoint corBreakpoint = corFunction.GetILCode().CreateBreakpoint((uint)seq.ILOffset);

58
src/AddIns/Debugger/Debugger.Core/PdbSymbolSource.cs

@ -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();

Loading…
Cancel
Save