Browse Source

Prototype of SetIP

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@252 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
David Srbecký 20 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 @@ -266,6 +266,10 @@ namespace ICSharpCode.SharpDevelop.Services
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();
isDebuggingCache = false;

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

@ -109,74 +109,29 @@ namespace DebuggerLibrary @@ -109,74 +109,29 @@ namespace DebuggerLibrary
}
internal unsafe void SetBreakpoint()
internal unsafe bool SetBreakpoint()
{
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;
module.CorModule.GetFunctionFromToken((uint)symMethod.Token.GetToken(), out corFunction);
int ilOffset;
if (!sourcecodeSegment.GetFunctionAndOffset(debugger, true, out corFunction, out ilOffset)) {
return false;
}
ICorDebugCode code;
corFunction.GetILCode(out code);
code.CreateBreakpoint((uint)corInstructionPtr, out corBreakpoint);
code.CreateBreakpoint((uint)ilOffset, out corBreakpoint);
hadBeenSet = true;
corBreakpoint.Activate(enabled?1:0);
pBreakpoint = Marshal.GetComInterfaceForObject(corBreakpoint, typeof(ICorDebugFunctionBreakpoint));
OnBreakpointStateChanged();
return true;
}
}
}

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

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

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

@ -185,13 +185,22 @@ namespace DebuggerLibrary @@ -185,13 +185,22 @@ namespace DebuggerLibrary
/// <summary>
/// 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
/// the returned area of source code. (May incude some extra compiler generated IL too)
/// </summary>
public SourcecodeSegment NextStatement {
get {
SourcecodeSegment GetSegmentForOffet(uint offset)
{
ISymbolMethod symMethod;
symMethod = this.symMethod;
@ -218,12 +227,11 @@ namespace DebuggerLibrary @@ -218,12 +227,11 @@ namespace DebuggerLibrary
endColumn
);
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)
if (offsets[i] <= offset)
{
// Set inforamtion about current IL range
ICorDebugCode code;
@ -231,7 +239,7 @@ namespace DebuggerLibrary @@ -231,7 +239,7 @@ namespace DebuggerLibrary
uint codeSize;
code.GetSize(out codeSize);
retVal.ILOffset = (int)corInstructionPtr;
retVal.ILOffset = (int)offset;
retVal.ILStart = offsets[i];
retVal.ILEnd = (i + 1 < sequencePointCount) ? offsets[i + 1] : (int)codeSize;
@ -290,6 +298,46 @@ namespace DebuggerLibrary @@ -290,6 +298,46 @@ namespace DebuggerLibrary
}
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()

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

@ -8,6 +8,8 @@ @@ -8,6 +8,8 @@
using System;
using System.Diagnostics.SymbolStore;
using DebuggerInterop.Core;
namespace DebuggerLibrary
{
[Serializable]
@ -149,5 +151,70 @@ namespace DebuggerLibrary @@ -149,5 +151,70 @@ namespace DebuggerLibrary
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 @@ -243,6 +243,15 @@ namespace ICSharpCode.Core
static string oldExpression, oldToolTip;
static int oldLine;
public class SetIPArgs: EventArgs
{
public string filename;
public int line;
public int column;
}
public static event EventHandler<SetIPArgs> SetIPRequest;
/// <summary>
/// This function shows variable values as tooltips
/// </summary>
@ -261,6 +270,18 @@ namespace ICSharpCode.Core @@ -261,6 +270,18 @@ namespace ICSharpCode.Core
Point logicPos = textArea.TextView.GetLogicalPosition(mousepos.X - viewRect.Left,
mousepos.Y - viewRect.Top);
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;
IExpressionFinder expressionFinder = ParserService.GetExpressionFinder(textArea.MotherTextEditorControl.FileName);
if (expressionFinder == null)

Loading…
Cancel
Save