Browse Source

Prototype of SetIP

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@252 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
David Srbecký 21 years ago
parent
commit
8de9cde42b
  1. 4
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Service/WindowsDebugger.cs
  2. 61
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Breakpoints/Breakpoint.cs
  3. 3
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/DebuggerEvents/PausedReason.cs
  4. 60
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Function.cs
  5. 67
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/SourcecodeSegment.cs
  6. 21
      src/Main/Base/Project/Src/Services/Debugger/DebuggerService.cs

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

@ -266,6 +266,10 @@ namespace ICSharpCode.SharpDevelop.Services
AddBreakpoint(e.BreakpointBookmark); AddBreakpoint(e.BreakpointBookmark);
}; };
DebuggerService.SetIPRequest += delegate (object sender, DebuggerService.SetIPArgs args) {
SourcecodeSegment seg = debugger.CurrentThread.CurrentFunction.SetIP(args.filename, args.line + 1, args.column);
};
RestoreNDebuggerBreakpoints(); RestoreNDebuggerBreakpoints();
isDebuggingCache = false; isDebuggingCache = false;

61
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Breakpoints/Breakpoint.cs

@ -109,74 +109,29 @@ namespace DebuggerLibrary
} }
internal unsafe void SetBreakpoint() internal unsafe bool SetBreakpoint()
{ {
if (hadBeenSet) { if (hadBeenSet) {
return; return true;
} }
Module module = null;
ISymbolReader symReader = null;
ISymbolDocument symDoc = null;
// Try to get doc from seg.moduleFilename
if (sourcecodeSegment.ModuleFilename != null) {
try {
module = debugger.GetModule(sourcecodeSegment.ModuleFilename);
symReader = debugger.GetModule(sourcecodeSegment.ModuleFilename).SymReader;
symDoc = symReader.GetDocument(sourcecodeSegment.SourceFullFilename,Guid.Empty,Guid.Empty,Guid.Empty);
} catch {}
}
// search all modules
if (symDoc == null) {
foreach (Module m in debugger.Modules) {
module = m;
symReader = m.SymReader;
if (symReader == null) {
continue;
}
symDoc = symReader.GetDocument(sourcecodeSegment.SourceFullFilename,Guid.Empty,Guid.Empty,Guid.Empty);
if (symDoc != null) {
break;
}
}
}
if (symDoc == null) {
//throw new Exception("Failed to add breakpoint - (module not loaded? wrong sourceFilename?)");
return;
}
int validStartLine;
validStartLine = symDoc.FindClosestLine(sourcecodeSegment.StartLine);
if (validStartLine != sourcecodeSegment.StartLine) {
sourcecodeSegment.StartLine = validStartLine;
sourcecodeSegment.EndLine = validStartLine;
sourcecodeSegment.StartColumn = 0;
sourcecodeSegment.EndColumn = 0;
}
ISymbolMethod symMethod;
symMethod = symReader.GetMethodFromDocumentPosition(symDoc, sourcecodeSegment.StartLine, sourcecodeSegment.StartColumn);
int corInstructionPtr = symMethod.GetOffset(symDoc, sourcecodeSegment.StartLine, sourcecodeSegment.StartColumn);
ICorDebugFunction corFunction; ICorDebugFunction corFunction;
module.CorModule.GetFunctionFromToken((uint)symMethod.Token.GetToken(), out corFunction); int ilOffset;
if (!sourcecodeSegment.GetFunctionAndOffset(debugger, true, out corFunction, out ilOffset)) {
return false;
}
ICorDebugCode code; ICorDebugCode code;
corFunction.GetILCode(out code); corFunction.GetILCode(out code);
code.CreateBreakpoint((uint)corInstructionPtr, out corBreakpoint); code.CreateBreakpoint((uint)ilOffset, out corBreakpoint);
hadBeenSet = true; hadBeenSet = true;
corBreakpoint.Activate(enabled?1:0); corBreakpoint.Activate(enabled?1:0);
pBreakpoint = Marshal.GetComInterfaceForObject(corBreakpoint, typeof(ICorDebugFunctionBreakpoint)); pBreakpoint = Marshal.GetComInterfaceForObject(corBreakpoint, typeof(ICorDebugFunctionBreakpoint));
OnBreakpointStateChanged(); OnBreakpointStateChanged();
return true;
} }
} }
} }

3
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/DebuggerEvents/PausedReason.cs

@ -18,6 +18,7 @@ namespace DebuggerLibrary
EvalComplete, EvalComplete,
CurrentThreadChanged, CurrentThreadChanged,
CurrentFunctionChanged, CurrentFunctionChanged,
ExceptionIntercepted ExceptionIntercepted,
SetIP
} }
} }

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

@ -185,13 +185,22 @@ namespace DebuggerLibrary
/// <summary> /// <summary>
/// Get the information about the next statement to be executed. /// Get the information about the next statement to be executed.
/// ///
/// Throws NextStatementNotAviableException on error. /// Returns null on error.
/// </summary>
public SourcecodeSegment NextStatement {
get {
return GetSegmentForOffet(corInstructionPtr);
}
}
/// <summary>
/// Returns null on error.
/// ///
/// 'ILStart <= ILOffset <= ILEnd' and this range includes at least /// 'ILStart <= ILOffset <= ILEnd' and this range includes at least
/// the returned area of source code. (May incude some extra compiler generated IL too) /// the returned area of source code. (May incude some extra compiler generated IL too)
/// </summary> /// </summary>
public SourcecodeSegment NextStatement { SourcecodeSegment GetSegmentForOffet(uint offset)
get { {
ISymbolMethod symMethod; ISymbolMethod symMethod;
symMethod = this.symMethod; symMethod = this.symMethod;
@ -218,12 +227,11 @@ namespace DebuggerLibrary
endColumn endColumn
); );
uint corInstructionPtr = this.corInstructionPtr; // cache
SourcecodeSegment retVal = new SourcecodeSegment(); SourcecodeSegment retVal = new SourcecodeSegment();
// Get i for which: offsets[i] <= corInstructionPtr < offsets[i + 1] // Get i for which: offsets[i] <= corInstructionPtr < offsets[i + 1]
for (int i = sequencePointCount - 1; i >= 0; i--) // backwards for (int i = sequencePointCount - 1; i >= 0; i--) // backwards
if (offsets[i] <= corInstructionPtr) if (offsets[i] <= offset)
{ {
// Set inforamtion about current IL range // Set inforamtion about current IL range
ICorDebugCode code; ICorDebugCode code;
@ -231,7 +239,7 @@ namespace DebuggerLibrary
uint codeSize; uint codeSize;
code.GetSize(out codeSize); code.GetSize(out codeSize);
retVal.ILOffset = (int)corInstructionPtr; retVal.ILOffset = (int)offset;
retVal.ILStart = offsets[i]; retVal.ILStart = offsets[i];
retVal.ILEnd = (i + 1 < sequencePointCount) ? offsets[i + 1] : (int)codeSize; retVal.ILEnd = (i + 1 < sequencePointCount) ? offsets[i + 1] : (int)codeSize;
@ -290,6 +298,46 @@ namespace DebuggerLibrary
} }
return null; return null;
} }
public SourcecodeSegment CanSetIP(string filename, int line, int column)
{
return SetIP(true, filename, line, column);
}
public SourcecodeSegment SetIP(string filename, int line, int column)
{
return SetIP(false, filename, line, column);
}
SourcecodeSegment SetIP(bool simulate, string filename, int line, int column)
{
SourcecodeSegment suggestion = new SourcecodeSegment(filename, line, column, column);
ICorDebugFunction corFunction;
int ilOffset;
if (!suggestion.GetFunctionAndOffset(debugger, false, out corFunction, out ilOffset)) {
return null;
} else {
uint token;
corFunction.GetToken(out token);
if (token != methodProps.Token) {
return null;
} else {
try {
if (simulate) {
corILFrame.CanSetIP((uint)ilOffset);
} else {
corILFrame.SetIP((uint)ilOffset);
Thread thread = debugger.CurrentThread;
debugger.OnDebuggingResumed();
thread.CurrentFunction = thread.LastFunctionWithLoadedSymbols;
debugger.OnDebuggingPaused(PausedReason.SetIP);
}
} catch {
return null;
}
return GetSegmentForOffet((uint)ilOffset);
}
}
} }
public VariableCollection GetVariables() public VariableCollection GetVariables()

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

@ -8,6 +8,8 @@
using System; using System;
using System.Diagnostics.SymbolStore; using System.Diagnostics.SymbolStore;
using DebuggerInterop.Core;
namespace DebuggerLibrary namespace DebuggerLibrary
{ {
[Serializable] [Serializable]
@ -149,5 +151,70 @@ namespace DebuggerLibrary
ilEnd = value; ilEnd = value;
} }
} }
// Returns true if found
internal bool GetFunctionAndOffset(NDebugger debugger, bool normailize, out ICorDebugFunction function, out int ilOffset)
{
function = null;
ilOffset = 0;
Module module = null;
ISymbolReader symReader = null;
ISymbolDocument symDoc = null;
// Try to get doc from moduleFilename
if (moduleFilename != null) {
try {
module = debugger.GetModule(ModuleFilename);
symReader = module.SymReader;
symDoc = symReader.GetDocument(SourceFullFilename,Guid.Empty,Guid.Empty,Guid.Empty);
} catch {}
}
// search all modules
if (symDoc == null) {
foreach (Module m in debugger.Modules) {
module = m;
symReader = m.SymReader;
if (symReader == null) {
continue;
}
symDoc = symReader.GetDocument(SourceFullFilename,Guid.Empty,Guid.Empty,Guid.Empty);
if (symDoc != null) {
break;
}
}
}
if (symDoc == null) {
return false; //Not found
}
int validLine;
validLine = symDoc.FindClosestLine(StartLine);
if (validLine != StartLine) {
if (normailize) {
StartLine = validLine;
EndLine = validLine;
StartColumn = 0;
EndColumn = 0;
} else {
return false;
}
}
ISymbolMethod symMethod;
symMethod = symReader.GetMethodFromDocumentPosition(symDoc, StartLine, StartColumn);
ICorDebugFunction corFunction;
module.CorModule.GetFunctionFromToken((uint)symMethod.Token.GetToken(), out corFunction);
function = corFunction;
ilOffset = symMethod.GetOffset(symDoc, StartLine, StartColumn);
return true;
}
} }
} }

21
src/Main/Base/Project/Src/Services/Debugger/DebuggerService.cs

@ -243,6 +243,15 @@ namespace ICSharpCode.Core
static string oldExpression, oldToolTip; static string oldExpression, oldToolTip;
static int oldLine; static int oldLine;
public class SetIPArgs: EventArgs
{
public string filename;
public int line;
public int column;
}
public static event EventHandler<SetIPArgs> SetIPRequest;
/// <summary> /// <summary>
/// This function shows variable values as tooltips /// This function shows variable values as tooltips
/// </summary> /// </summary>
@ -261,6 +270,18 @@ namespace ICSharpCode.Core
Point logicPos = textArea.TextView.GetLogicalPosition(mousepos.X - viewRect.Left, Point logicPos = textArea.TextView.GetLogicalPosition(mousepos.X - viewRect.Left,
mousepos.Y - viewRect.Top); mousepos.Y - viewRect.Top);
if (logicPos.Y >= 0 && logicPos.Y < textArea.Document.TotalNumberOfLines) { if (logicPos.Y >= 0 && logicPos.Y < textArea.Document.TotalNumberOfLines) {
// This is for testing olny - it must be reworked properly
if (Control.ModifierKeys == Keys.Control) {
SetIPArgs a = new SetIPArgs();
a.filename = textArea.MotherTextEditorControl.FileName;
a.line = logicPos.Y;
a.column = logicPos.X;
if (SetIPRequest != null) {
SetIPRequest(null, a);
}
return;
}
IDocument doc = textArea.Document; IDocument doc = textArea.Document;
IExpressionFinder expressionFinder = ParserService.GetExpressionFinder(textArea.MotherTextEditorControl.FileName); IExpressionFinder expressionFinder = ParserService.GetExpressionFinder(textArea.MotherTextEditorControl.FileName);
if (expressionFinder == null) if (expressionFinder == null)

Loading…
Cancel
Save