Skip to content

Commit 7acfd74

Browse files
fixed way of choosing best sequence point in CorDebuggerSession
1 parent bbdfe2a commit 7acfd74

File tree

1 file changed

+71
-34
lines changed

1 file changed

+71
-34
lines changed

Mono.Debugging.Win32/CorDebuggerSession.cs

Lines changed: 71 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1044,55 +1044,92 @@ protected override BreakEventInfo OnInsertBreakEvent (BreakEvent be)
10441044
binfo.SetStatus (BreakEventStatus.Invalid, string.Format("Invalid line {0}", bp.Line));
10451045
return binfo;
10461046
}
1047-
ISymbolMethod met = null;
1047+
ISymbolMethod[] methods = null;
10481048
if (doc.ModuleInfo.Reader is ISymbolReader2) {
1049-
var methods = ((ISymbolReader2)doc.ModuleInfo.Reader).GetMethodsFromDocumentPosition (doc.Document, line, 0);
1050-
if (methods != null && methods.Any ()) {
1051-
if (methods.Count () == 1) {
1052-
met = methods [0];
1053-
} else {
1054-
int deepest = -1;
1055-
foreach (var method in methods) {
1056-
var firstSequence = method.GetSequencePoints ().FirstOrDefault ((sp) => sp.StartLine != 0xfeefee);
1057-
if (firstSequence != null && firstSequence.StartLine >= deepest) {
1058-
deepest = firstSequence.StartLine;
1059-
met = method;
1060-
}
1061-
}
1062-
}
1063-
}
1049+
methods = ((ISymbolReader2)doc.ModuleInfo.Reader).GetMethodsFromDocumentPosition (doc.Document, line, 0);
10641050
}
1065-
if (met == null) {
1066-
met = doc.ModuleInfo.Reader.GetMethodFromDocumentPosition (doc.Document, line, 0);
1051+
if (methods == null || methods.Length == 0) {
1052+
var met = doc.ModuleInfo.Reader.GetMethodFromDocumentPosition (doc.Document, line, 0);
1053+
if (met != null)
1054+
methods = new ISymbolMethod[] {met};
10671055
}
1068-
if (met == null) {
1056+
1057+
if (methods == null || methods.Length == 0) {
10691058
binfo.SetStatus (BreakEventStatus.Invalid, "Unable to resolve method at position");
10701059
return binfo;
10711060
}
10721061

1073-
int offset = -1;
1074-
int firstSpInLine = -1;
1075-
foreach (SequencePoint sp in met.GetSequencePoints ()) {
1076-
if (sp.IsInside (doc.Document.URL, line, bp.Column)) {
1077-
offset = sp.Offset;
1078-
break;
1079-
} else if (firstSpInLine == -1
1080-
&& sp.StartLine == line
1081-
&& sp.Document.URL.Equals (doc.Document.URL, StringComparison.OrdinalIgnoreCase)) {
1082-
firstSpInLine = sp.Offset;
1062+
ISymbolMethod bestMethod = null;
1063+
ISymbolMethod bestLeftSideMethod = null;
1064+
ISymbolMethod bestRightSideMethod = null;
1065+
1066+
SequencePoint bestSp = null;
1067+
SequencePoint bestLeftSideSp = null;
1068+
SequencePoint bestRightSideSp = null;
1069+
1070+
foreach (var met in methods) {
1071+
foreach (SequencePoint sp in met.GetSequencePoints ()) {
1072+
if (sp.IsInside (doc.Document.URL, line, bp.Column)) { //breakpoint is inside current sequence point
1073+
if (bestSp == null || bestSp.IsInside (doc.Document.URL, sp.StartLine, sp.StartColumn)) { //and sp is inside of current candidate
1074+
bestSp = sp;
1075+
bestMethod = met;
1076+
break;
1077+
}
1078+
} else if (sp.StartLine == line
1079+
&& sp.Document.URL.Equals (doc.Document.URL, StringComparison.OrdinalIgnoreCase)
1080+
&& sp.StartColumn <= bp.Column) { //breakpoint is on the same line and on the right side of sp
1081+
if (bestLeftSideSp == null
1082+
|| bestLeftSideSp.EndColumn < sp.EndColumn) {
1083+
bestLeftSideSp = sp;
1084+
bestLeftSideMethod = met;
1085+
}
1086+
} else if (sp.StartLine >= line
1087+
&& sp.Document.URL.Equals (doc.Document.URL, StringComparison.OrdinalIgnoreCase)) { //sp is after bp
1088+
if (bestRightSideSp == null
1089+
|| bestRightSideSp.StartLine > sp.StartLine
1090+
|| (bestRightSideSp.StartLine == sp.StartLine && bestRightSideSp.StartColumn > sp.StartColumn)) { //and current candidate is on the right side of it
1091+
bestRightSideSp = sp;
1092+
bestRightSideMethod = met;
1093+
}
1094+
}
10831095
}
10841096
}
1085-
if (offset == -1) {//No exact match? Use first match in that line
1086-
offset = firstSpInLine;
1097+
1098+
SequencePoint bestSameLineSp;
1099+
ISymbolMethod bestSameLineMethod;
1100+
1101+
if (bestRightSideSp != null
1102+
&& (bestLeftSideSp == null
1103+
|| bestRightSideSp.StartLine > line)) {
1104+
bestSameLineSp = bestRightSideSp;
1105+
bestSameLineMethod = bestRightSideMethod;
1106+
}
1107+
else {
1108+
bestSameLineSp = bestLeftSideSp;
1109+
bestSameLineMethod = bestLeftSideMethod;
10871110
}
1088-
if (offset == -1) {
1111+
1112+
if (bestSameLineSp != null) {
1113+
if (bestSp == null) {
1114+
bestSp = bestSameLineSp;
1115+
bestMethod = bestSameLineMethod;
1116+
}
1117+
else {
1118+
if (bp.Line != bestSp.StartLine || bestSp.StartColumn != bp.Column) {
1119+
bestSp = bestSameLineSp;
1120+
bestMethod = bestSameLineMethod;
1121+
}
1122+
}
1123+
}
1124+
1125+
if (bestSp == null || bestMethod == null) {
10891126
binfo.SetStatus (BreakEventStatus.Invalid, "Unable to calculate an offset in IL code");
10901127
return binfo;
10911128
}
10921129

1093-
CorFunction func = doc.ModuleInfo.Module.GetFunctionFromToken (met.Token.GetToken ());
1130+
CorFunction func = doc.ModuleInfo.Module.GetFunctionFromToken (bestMethod.Token.GetToken ());
10941131
try {
1095-
CorFunctionBreakpoint corBp = func.ILCode.CreateBreakpoint (offset);
1132+
CorFunctionBreakpoint corBp = func.ILCode.CreateBreakpoint (bestSp.Offset);
10961133
breakpoints[corBp] = binfo;
10971134
binfo.Handle = corBp;
10981135
corBp.Activate (bp.Enabled);

0 commit comments

Comments
 (0)