Browse Source

Debugger stepping made more stable

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@112 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
David Srbecký 21 years ago
parent
commit
9c5e0db7aa
  1. 7
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Service/WindowsDebugger.cs
  2. 95
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Function.cs
  3. 40
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/SourcecodeSegment.cs

7
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Service/WindowsDebugger.cs

@ -319,12 +319,19 @@ namespace ICSharpCode.SharpDevelop.Services @@ -319,12 +319,19 @@ namespace ICSharpCode.SharpDevelop.Services
public void JumpToCurrentLine()
{
//StatusBarService.SetMessage("Source code not aviable!");
try {
if (selectedFunction == null) {
return;
}
SourcecodeSegment nextStatement = selectedFunction.NextStatement;
DebuggerService.JumpToCurrentLine(nextStatement.SourceFullFilename, nextStatement.StartLine, nextStatement.StartColumn, nextStatement.EndLine, nextStatement.EndColumn);
string stepRanges = "";
foreach (int i in nextStatement.StepRanges) {
stepRanges += i.ToString("X") + " ";
}
//StatusBarService.SetMessage("IL:" + nextStatement.ILOffset.ToString("X") + " StepRange:" + stepRanges + " ");
} catch (NextStatementNotAviableException) {
System.Diagnostics.Debug.Fail("Source code not aviable!");
}

95
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Function.cs

@ -9,6 +9,7 @@ using System.Threading; @@ -9,6 +9,7 @@ using System.Threading;
using DebuggerInterop.Core;
using DebuggerInterop.MetaData;
using System.Collections.Generic;
namespace DebuggerLibrary
@ -146,30 +147,23 @@ namespace DebuggerLibrary @@ -146,30 +147,23 @@ namespace DebuggerLibrary
ICorDebugStepper stepper;
corFrame.CreateStepper(out stepper);
//uint rangeCount;
//symMethod.GetRanges(nextSt.SymbolDocument, nextSt.StartLine, 0, 0, out rangeCount, IntPtr.Zero);
//IntPtr pRanges = Marshal.AllocHGlobal(4*(int)rangeCount);
//symMethod.GetRanges(nextSt.SymbolDocument, nextSt.StartLine, 0, rangeCount, out rangeCount, pRanges);
int[] ranges = symMethod.GetRanges(nextSt.SymbolDocument, nextSt.StartLine, 0);
IntPtr pRanges = Marshal.AllocHGlobal(4*ranges.Length);
for (int i = 0; i < ranges.Length; i++) {
((int*)pRanges.ToPointer())[i] = ranges[i];
}
stepper.StepRange(stepIn?1:0, pRanges, (uint)ranges.Length);
Marshal.FreeHGlobal(pRanges);
fixed (int* ranges = nextSt.StepRanges) {
stepper.StepRange(stepIn?1:0, (IntPtr)ranges, (uint)nextSt.StepRanges.Length / 2);
}
NDebugger.Continue();
}
/// <summary>
/// Get the information about the next statement to be executed.
///
/// Throws NextStatementNotAviableException on error.
///
/// 'ILStart <= ILOffset <= ILEnd' and this range includes at least
/// the returned area of source code. (May incude some extra compiler generated IL too)
/// </summary>
public SourcecodeSegment NextStatement {
get {
SourcecodeSegment retVal = new SourcecodeSegment();
ISymbolMethod symMethod;
try {
symMethod = this.symMethod;
@ -201,23 +195,74 @@ namespace DebuggerLibrary @@ -201,23 +195,74 @@ namespace DebuggerLibrary
);
uint corInstructionPtr = this.corInstructionPtr; // cache
SourcecodeSegment retVal = new SourcecodeSegment();
// Get i for which: offsets[i] <= corInstructionPtr < offsets[i + 1]
for (int i = sequencePointCount - 1; i >= 0; i--) // backwards
if (offsets[i] <= corInstructionPtr)
{
// Set inforamtion about current IL range
ICorDebugCode code;
corFunction.GetILCode(out code);
uint codeSize;
code.GetSize(out codeSize);
retVal.ILOffset = (int)corInstructionPtr;
retVal.ILStart = offsets[i];
retVal.ILEnd = (i + 1 < sequencePointCount) ? offsets[i + 1] : (int)codeSize;
// 0xFeeFee means "code generated by compiler"
if (startLine[i] == 0xFeeFee) throw new NextStatementNotAviableException();
// If we are in generated sequence use to closest real one instead,
// extend the ILStart and ILEnd to include the 'real' sequence
retVal.SymbolDocument = Doc[i];
// Look ahead for 'real' sequence
while (i + 1 < sequencePointCount && startLine[i] == 0xFeeFee) {
i++;
retVal.ILEnd = (i + 1 < sequencePointCount) ? offsets[i + 1] : (int)codeSize;
}
// Look back for 'real' sequence
while (i - 1 >= 0 && startLine[i] == 0xFeeFee) {
i--;
retVal.ILStart = offsets[i];
}
// Wow, there are no 'real' sequences
if (startLine[i] == 0xFeeFee) {
throw new NextStatementNotAviableException();
}
retVal.SourceFullFilename = retVal.SymbolDocument.URL;
retVal.ModuleFilename = module.FullPath;
retVal.StartLine = startLine[i];
retVal.SymbolDocument = Doc[i];
retVal.SourceFullFilename = Doc[i].URL;
retVal.StartLine = startLine[i];
retVal.StartColumn = startColumn[i];
retVal.EndLine = endLine[i];
retVal.EndColumn = endColumn[i];
retVal.EndLine = endLine[i];
retVal.EndColumn = endColumn[i];
List<int> stepRanges = new List<int>();
for (int j = 0; j < sequencePointCount; j++) {
// Step over compiler generated sequences and current statement
// 0xFeeFee means "code generated by compiler"
if (startLine[j] == 0xFeeFee || j == i) {
// Add start offset or remove last end (to connect two ranges into one)
if (stepRanges.Count > 0 && stepRanges[stepRanges.Count - 1] == offsets[j]) {
stepRanges.RemoveAt(stepRanges.Count - 1);
} else {
stepRanges.Add(offsets[j]);
}
// Add end offset | handle last sequence point
if (j + 1 < sequencePointCount) {
stepRanges.Add(offsets[j + 1]);
} else {
stepRanges.Add((int)codeSize);
}
}
}
retVal.StepRanges = stepRanges.ToArray();
return retVal;
}
throw new NextStatementNotAviableException();

40
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/SourcecodeSegment.cs

@ -15,6 +15,10 @@ namespace DebuggerLibrary @@ -15,6 +15,10 @@ namespace DebuggerLibrary
int startColumn;
int endLine;
int endColumn;
int ilOffset;
int ilStart;
int ilEnd;
int[] stepRanges;
ISymbolDocument symUnmanagedDocument;
public string ModuleFilename {
@ -85,5 +89,41 @@ namespace DebuggerLibrary @@ -85,5 +89,41 @@ namespace DebuggerLibrary
symUnmanagedDocument = value;
}
}
public int[] StepRanges {
get {
return stepRanges;
}
set {
stepRanges = value;
}
}
public int ILOffset {
get {
return ilOffset;
}
set {
ilOffset = value;
}
}
public int ILStart {
get {
return ilStart;
}
set {
ilStart = value;
}
}
public int ILEnd {
get {
return ilEnd;
}
set {
ilEnd = value;
}
}
}
}

Loading…
Cancel
Save