Browse Source

decouple the debugger from decompiler; fix race conditions on external debug information; use metadata token instead of type name when selecting the decompiled content.

pull/16/head
Eusebiu Marcu 14 years ago
parent
commit
abdeeb5c20
  1. 4
      src/AddIns/Debugger/Debugger.AddIn/Debugger.AddIn.csproj
  2. 3
      src/AddIns/Debugger/Debugger.AddIn/Pads/LocalVarPad.cs
  3. 2
      src/AddIns/Debugger/Debugger.AddIn/Pads/WatchPad.cs
  4. 165
      src/AddIns/Debugger/Debugger.AddIn/Service/WindowsDebugger.cs
  5. 13
      src/AddIns/Debugger/Debugger.AddIn/TreeModel/ExpressionNode.cs
  6. 103
      src/AddIns/DisplayBindings/ILSpyAddIn/DebuggerDecompilerService.cs
  7. 4
      src/AddIns/DisplayBindings/ILSpyAddIn/ILSpyAddIn.addin
  8. 1
      src/AddIns/DisplayBindings/ILSpyAddIn/ILSpyAddIn.csproj
  9. 78
      src/AddIns/DisplayBindings/ILSpyAddIn/ViewContent/DecompiledViewContent.cs
  10. 5
      src/Main/Base/Project/Src/Services/Debugger/BreakpointBookmark.cs
  11. 18
      src/Main/Base/Project/Src/Services/Debugger/CurrentLineBookmark.cs
  12. 26
      src/Main/Base/Project/Src/Services/Debugger/DebuggerService.cs
  13. 2
      src/Setup/Files.wxs

4
src/AddIns/Debugger/Debugger.AddIn/Debugger.AddIn.csproj

@ -353,10 +353,6 @@ @@ -353,10 +353,6 @@
<Name>ICSharpCode.AvalonEdit</Name>
<Private>False</Private>
</ProjectReference>
<ProjectReference Include="..\..\..\Libraries\ICSharpCode.Decompiler\ICSharpCode.Decompiler.csproj">
<Project>{984CC812-9470-4A13-AFF9-CC44068D666C}</Project>
<Name>ICSharpCode.Decompiler</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\Libraries\Mono.Cecil\Mono.Cecil.csproj">
<Project>{D68133BD-1E63-496E-9EDE-4FBDBF77B486}</Project>
<Name>Mono.Cecil</Name>

3
src/AddIns/Debugger/Debugger.AddIn/Pads/LocalVarPad.cs

@ -57,10 +57,11 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads @@ -57,10 +57,11 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
public override void RefreshPad()
{
if (debuggedProcess == null || debuggedProcess.IsRunning || debuggedProcess.SelectedStackFrame == null) {
if (debuggedProcess == null || debuggedProcess.IsRunning) {
localVarList.WatchItems.Clear();
return;
}
localVarList.WatchItems.Clear();
using(new PrintTimes("Local Variables refresh")) {
try {

2
src/AddIns/Debugger/Debugger.AddIn/Pads/WatchPad.cs

@ -162,7 +162,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads @@ -162,7 +162,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
public override void RefreshPad()
{
if (debuggedProcess == null || debuggedProcess.IsRunning || debuggedProcess.SelectedStackFrame == null)
if (debuggedProcess == null || debuggedProcess.IsRunning)
return;
using(new PrintTimes("Watch Pad refresh")) {

165
src/AddIns/Debugger/Debugger.AddIn/Service/WindowsDebugger.cs

@ -19,8 +19,6 @@ using Debugger.Interop.CorPublish; @@ -19,8 +19,6 @@ using Debugger.Interop.CorPublish;
using Debugger.MetaData;
using ICSharpCode.Core;
using ICSharpCode.Core.WinForms;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.ILAst;
using ICSharpCode.NRefactory;
using ICSharpCode.NRefactory.Ast;
using ICSharpCode.NRefactory.Visitors;
@ -461,38 +459,24 @@ namespace ICSharpCode.SharpDevelop.Services @@ -461,38 +459,24 @@ namespace ICSharpCode.SharpDevelop.Services
}
// Stepping:
SourceCodeMapping GetCurrentCodeMapping(out bool isMatch)
Debugger.StackFrame GetStackFrame()
{
bool isMatch = false;
int line = -1;
int[] ilRange = null;
var frame = debuggedProcess.SelectedThread.MostRecentStackFrame;
int typeToken = frame.MethodInfo.DeclaringType.MetadataToken;
int methodToken = frame.MethodInfo.MetadataToken;
DecompileInformation debugInformation = (DecompileInformation)DebuggerService.ExternalDebugInformation[typeToken];
isMatch = false;
if (debugInformation == null)
return null;
// get the mapped instruction from the current line marker or the next one
if (!debugInformation.CodeMappings.ContainsKey(methodToken))
return null;
var mappings = (List<MemberMapping>)debugInformation.CodeMappings[methodToken];
return mappings.GetInstructionByTokenAndOffset(methodToken, frame.IP, out isMatch);
}
Debugger.StackFrame GetStackFrame()
{
bool isMatch;
Debugger.StackFrame frame = debuggedProcess.SelectedThread.MostRecentStackFrame;
var map = GetCurrentCodeMapping(out isMatch);
if (map == null) {
frame = debuggedProcess.SelectedThread.MostRecentStackFrame;
var decompilerService = GetDecompilerService();
if (!decompilerService.GetILAndLineNumber(typeToken, methodToken, frame.IP, out ilRange, out line, out isMatch)){
frame.SourceCodeLine = 0;
frame.ILRanges = new [] { 0, 1 };
} else {
frame.SourceCodeLine = map.SourceCodeLine;
frame.ILRanges = map.ToArray(isMatch);
frame.SourceCodeLine = line;
frame.ILRanges = ilRange;
}
return frame;
@ -599,10 +583,8 @@ namespace ICSharpCode.SharpDevelop.Services @@ -599,10 +583,8 @@ namespace ICSharpCode.SharpDevelop.Services
var stackFrame = !debuggedProcess.IsInExternalCode ? debuggedProcess.SelectedStackFrame : debuggedProcess.SelectedThread.MostRecentStackFrame;
try {
object data = GetLocalVariableIndex(stackFrame, variableName);
// evaluate expression
return ExpressionEvaluator.Evaluate(variableName, SupportedLanguage.CSharp, stackFrame, data);
return ExpressionEvaluator.Evaluate(variableName, SupportedLanguage.CSharp, stackFrame);
} catch {
throw;
}
@ -768,39 +750,38 @@ namespace ICSharpCode.SharpDevelop.Services @@ -768,39 +750,38 @@ namespace ICSharpCode.SharpDevelop.Services
if (bookmark is DecompiledBreakpointBookmark) {
var dbb = (DecompiledBreakpointBookmark)bookmark;
var memberReference = dbb.MemberReference;
if (!DebuggerService.ExternalDebugInformation.ContainsKey(memberReference.MetadataToken.ToInt32()))
return;
var decompilerService = GetDecompilerService();
int token = memberReference.MetadataToken.ToInt32();
// check if the codemappings exists for bookmark line
DecompileInformation data = (DecompileInformation)DebuggerService.ExternalDebugInformation[memberReference.MetadataToken.ToInt32()];
var storage = data.CodeMappings;
int token = 0;
foreach (var key in storage.Keys) {
var instruction = storage[key].GetInstructionByLineNumber(dbb.LineNumber, out token);
if (instruction == null) {
continue;
}
dbb.ILFrom = instruction.ILInstructionOffset.From;
dbb.ILTo = instruction.ILInstructionOffset.To;
if (!DebuggerService.ExternalDebugInformation.ContainsKey(token))
decompilerService.DecompileOnDemand(memberReference as TypeDefinition);
int[] ilRanges;
int methodToken;
if (decompilerService.GetILAndTokenByLineNumber(token, dbb.LineNumber, out ilRanges, out methodToken)) {
dbb.ILFrom = ilRanges[0];
dbb.ILTo = ilRanges[1];
// create BP
breakpoint = new ILBreakpoint(
debugger,
dbb.MemberReference.FullName,
dbb.LineNumber,
memberReference.MetadataToken.ToInt32(),
instruction.MemberMapping.MetadataToken,
methodToken,
dbb.ILFrom,
dbb.IsEnabled);
debugger.Breakpoints.Add(breakpoint);
break;
}
} else {
breakpoint = debugger.Breakpoints.Add(bookmark.FileName, null, bookmark.LineNumber, 0, bookmark.IsEnabled);
}
if (breakpoint == null) {
LoggingService.Warn(string.Format("unable to create breakpoint: {0}", bookmark.ToString()));
return;
}
MethodInvoker setBookmarkColor = delegate {
if (debugger.Processes.Count == 0) {
bookmark.IsHealthy = true;
@ -969,8 +950,8 @@ namespace ICSharpCode.SharpDevelop.Services @@ -969,8 +950,8 @@ namespace ICSharpCode.SharpDevelop.Services
var currentModuleTypes = e.Module.GetNamesOfDefinedTypes();
foreach (var bookmark in DebuggerService.Breakpoints.OfType<DecompiledBreakpointBookmark>()) {
var breakpoint = debugger.Breakpoints.FirstOrDefault(
b => b is ILBreakpoint && b.Line == bookmark.LineNumber &&
((ILBreakpoint)b).MetadataToken == bookmark.MemberReference.MetadataToken.ToInt32());
b => b is ILBreakpoint && b.Line == bookmark.LineNumber &&
((ILBreakpoint)b).MetadataToken == bookmark.MemberReference.MetadataToken.ToInt32());
if (breakpoint == null)
continue;
// set the breakpoint only if the module contains the type
@ -1058,39 +1039,37 @@ namespace ICSharpCode.SharpDevelop.Services @@ -1058,39 +1039,37 @@ namespace ICSharpCode.SharpDevelop.Services
int typeToken = frame.MethodInfo.DeclaringType.MetadataToken;
// get external data
object data = null;
DebuggerService.ExternalDebugInformation.TryGetValue(typeToken, out data);
DecompileInformation externalData = data as DecompileInformation;
int token = frame.MethodInfo.MetadataToken;
int methodToken = frame.MethodInfo.MetadataToken;
int ilOffset = frame.IP;
int line;
MemberReference memberReference;
if (externalData != null && externalData.CodeMappings.ContainsKey(token)) {
var mappings = externalData.CodeMappings[token];
if (mappings.GetInstructionByTokenAndOffset(token, ilOffset, out memberReference, out line)) {
DebuggerService.DebugStepInformation = null; // we do not need to step into/out
var decompilerService = GetDecompilerService();
int[] ilRanges = null;
int line = -1;
bool isMatch = false;
if (decompilerService.GetILAndLineNumber(typeToken, methodToken, ilOffset, out ilRanges, out line, out isMatch)) {
DebuggerService.DebugStepInformation = null; // we do not need to step into/out
// update marker
var debugType = (DebugType)frame.MethodInfo.DeclaringType;
string fullTypeName = debugType.FullNameWithoutGenericArguments;
string shortTypeName = fullTypeName.Substring(fullTypeName.LastIndexOf('.') + 1);
string title = "[" + shortTypeName + "]";
foreach (var vc in WorkbenchSingleton.Workbench.ViewContentCollection.OfType<AbstractViewContentWithoutFile>()) {
if (string.Equals(vc.TitleName, title, StringComparison.OrdinalIgnoreCase)) {
CurrentLineBookmark.SetPosition(vc, line, 0, line, 0);
vc.WorkbenchWindow.SelectWindow();
return;
}
// update marker
var debugType = (DebugType)frame.MethodInfo.DeclaringType;
foreach (dynamic vc in WorkbenchSingleton.Workbench.ViewContentCollection.OfType<AbstractViewContentWithoutFile>()) {
if (vc == null || vc.MemberReference == null)
continue;
if (vc.MemberReference.MetadataToken.ToInt32() == debugType.MetadataToken) {
CurrentLineBookmark.SetPosition(vc, line, 0, line, 0);
var wbw = vc.WorkbenchWindow as IWorkbenchWindow;
if (wbw != null)
wbw.SelectWindow();
return;
}
// the decompiled content was closed so we have to recreate it
StepIntoUnknownFrame(frame, token, ilOffset);
} else {
StepIntoUnknownFrame(frame, token, ilOffset);
}
// the decompiled content was closed so we have to recreate it
StepIntoUnknownFrame(frame, methodToken, ilOffset);
} else {
StepIntoUnknownFrame(frame, token, ilOffset);
StepIntoUnknownFrame(frame, methodToken, ilOffset);
}
}
}
@ -1102,6 +1081,15 @@ namespace ICSharpCode.SharpDevelop.Services @@ -1102,6 +1081,15 @@ namespace ICSharpCode.SharpDevelop.Services
NavigationService.NavigateTo(debugType.DebugModule.FullPath, debugType.FullNameWithoutGenericArguments, string.Empty);
}
IDebuggerDecompilerService GetDecompilerService()
{
var items = AddInTree.BuildItems<IDebuggerDecompilerService>("/SharpDevelop/Services/DebuggerDecompilerService", null, false);
if (items.Count == 0)
return null;
return items[0];
}
StopAttachedProcessDialogResult ShowStopAttachedProcessDialog()
{
string caption = StringParser.Parse("${res:XML.MainMenu.DebugMenu.Stop}");
@ -1119,32 +1107,5 @@ namespace ICSharpCode.SharpDevelop.Services @@ -1119,32 +1107,5 @@ namespace ICSharpCode.SharpDevelop.Services
.Where(p => e.Item.Name.IndexOf(p.Name) >= 0)
.ForEach(p => e.Item.LoadSymbolsFromDisk(new []{ Path.GetDirectoryName(p.OutputAssemblyFullPath) }));
}
public static object GetLocalVariableIndex(Debugger.StackFrame stackFrame, string variableName)
{
// get the target name
int typeToken = stackFrame.MethodInfo.DeclaringType.MetadataToken;
int methodToken = stackFrame.MethodInfo.MetadataToken;
int index = variableName.IndexOf('.');
string targetName = variableName;
if (index != -1) {
targetName = variableName.Substring(0, index);
}
// get local variable index and store it in UserData property - used in evaluator
object data = null;
IEnumerable<ILVariable> list;
if (DebuggerService.ExternalDebugInformation == null || !DebuggerService.ExternalDebugInformation.ContainsKey(typeToken))
return null;
DecompileInformation externalData = (DecompileInformation)DebuggerService.ExternalDebugInformation[typeToken];
if (externalData.LocalVariables.TryGetValue(methodToken, out list)) {
var variable = list.FirstOrDefault(v => v.Name == targetName);
if (variable != null && variable.OriginalVariable != null) {
data = new[] { variable.OriginalVariable.Index };
}
}
return data;
}
}
}

13
src/AddIns/Debugger/Debugger.AddIn/TreeModel/ExpressionNode.cs

@ -14,8 +14,6 @@ using System.Windows.Forms; @@ -14,8 +14,6 @@ using System.Windows.Forms;
using Debugger.AddIn.Visualizers;
using Debugger.MetaData;
using ICSharpCode.Core;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.ILAst;
using ICSharpCode.NRefactory.Ast;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Debugging;
@ -159,17 +157,8 @@ namespace Debugger.AddIn.TreeModel @@ -159,17 +157,8 @@ namespace Debugger.AddIn.TreeModel
Value val;
try {
var process = WindowsDebugger.DebuggedProcess;
var context = !process.IsInExternalCode ? process.SelectedStackFrame : process.SelectedThread.MostRecentStackFrame;
object data = WindowsDebugger.GetLocalVariableIndex(WindowsDebugger.DebuggedProcess.SelectedThread.MostRecentStackFrame, Name);
if (expression is MemberReferenceExpression) {
var memberExpression = (MemberReferenceExpression)expression;
memberExpression.TargetObject.UserData = data;
} else {
expression.UserData = data;
}
// evaluate expression
val = expression.Evaluate(WindowsDebugger.DebuggedProcess);
val = expression.Evaluate(process);
} catch (GetValueException e) {
error = e;
this.Text = e.Message;

103
src/AddIns/DisplayBindings/ILSpyAddIn/DebuggerDecompilerService.cs

@ -0,0 +1,103 @@ @@ -0,0 +1,103 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Ast;
using ICSharpCode.SharpDevelop.Debugging;
using Mono.Cecil;
namespace ICSharpCode.ILSpyAddIn
{
/// <summary>
/// Description of DebuggerDecompilerService.
/// </summary>
public class DebuggerDecompilerService : IDebuggerDecompilerService
{
private bool CheckMappings(int typeToken)
{
object data = null;
DebuggerService.ExternalDebugInformation.TryGetValue(typeToken, out data);
DecompileInformation information = data as DecompileInformation;
if (information == null)
return false;
if (information.CodeMappings == null)
return false;
return true;
}
public void DecompileOnDemand(TypeDefinition type)
{
if (type == null)
return;
if (CheckMappings(type.MetadataToken.ToInt32()))
return;
try {
DecompilerContext context = new DecompilerContext(type.Module);
AstBuilder astBuilder = new AstBuilder(context);
astBuilder.AddType(type);
astBuilder.GenerateCode(new PlainTextOutput());
int token = type.MetadataToken.ToInt32();
var info = new DecompileInformation {
CodeMappings = astBuilder.CodeMappings,
LocalVariables = astBuilder.LocalVariables,
DecompiledMemberReferences = astBuilder.DecompiledMemberReferences
};
// save the data
DebuggerService.ExternalDebugInformation.AddOrUpdate(token, info, (k, v) => info);
} catch {
return;
}
}
public bool GetILAndTokenByLineNumber(int typeToken, int lineNumber, out int[] ilRanges, out int memberToken)
{
ilRanges = null;
memberToken = -1;
if (!CheckMappings(typeToken))
return false;
var data = (DecompileInformation)DebuggerService.ExternalDebugInformation[typeToken];
var mappings = data.CodeMappings;
foreach (var key in mappings.Keys) {
var list = mappings[key];
var instruction = list.GetInstructionByLineNumber(lineNumber, out memberToken);
if (instruction == null)
continue;
ilRanges = new [] { instruction.ILInstructionOffset.From, instruction.ILInstructionOffset.To };
memberToken = instruction.MemberMapping.MetadataToken;
return true;
}
return false;
}
public bool GetILAndLineNumber(int typeToken, int memberToken, int ilOffset, out int[] ilRange, out int line, out bool isMatch)
{
ilRange = null;
line = -1;
isMatch = false;
if (!CheckMappings(typeToken))
return false;
var data = (DecompileInformation)DebuggerService.ExternalDebugInformation[typeToken];
var mappings = data.CodeMappings;
var map = mappings[memberToken].GetInstructionByTokenAndOffset(memberToken, ilOffset, out isMatch);
if (map != null) {
ilRange = map.ToArray(isMatch);
line = map.SourceCodeLine;
return true;
}
return false;
}
}
}

4
src/AddIns/DisplayBindings/ILSpyAddIn/ILSpyAddIn.addin

@ -16,6 +16,10 @@ @@ -16,6 +16,10 @@
<Class id="ILSpy" class="ICSharpCode.ILSpyAddIn.NavigateToDecompiledEntityService"/>
</Path>
<Path name="/SharpDevelop/Services/DebuggerDecompilerService">
<Class id="DebuggerDecompilerService" class="ICSharpCode.ILSpyAddIn.DebuggerDecompilerService"/>
</Path>
<!-- Text editor context menu: Launch ILSpy command -->
<Path name = "/SharpDevelop/ViewContent/DefaultTextEditor/ClassMemberContextMenu">

1
src/AddIns/DisplayBindings/ILSpyAddIn/ILSpyAddIn.csproj

@ -63,6 +63,7 @@ @@ -63,6 +63,7 @@
<Compile Include="..\..\..\Main\GlobalAssemblyInfo.cs">
<Link>Properties\GlobalAssemblyInfo.cs</Link>
</Compile>
<Compile Include="DebuggerDecompilerService.cs" />
<Compile Include="NavigateToDecompiledEntityService.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="LaunchILSpy\ILSpyController.cs" />

78
src/AddIns/DisplayBindings/ILSpyAddIn/ViewContent/DecompiledViewContent.cs

@ -168,22 +168,17 @@ namespace ICSharpCode.ILSpyAddIn @@ -168,22 +168,17 @@ namespace ICSharpCode.ILSpyAddIn
.PreOrder((AstNode)astBuilder.CompilationUnit, n => n.Children)
.Where(n => n is AttributedNode && n.Annotation<Tuple<int, int>>() != null);
MemberReference = typeDefinition;
int token = MemberReference.MetadataToken.ToInt32();
if (!DebuggerService.ExternalDebugInformation.ContainsKey(token)) {
DebuggerService.ExternalDebugInformation.Add(token, new DecompileInformation {
CodeMappings = astBuilder.CodeMappings,
LocalVariables = astBuilder.LocalVariables,
DecompiledMemberReferences = astBuilder.DecompiledMemberReferences,
AstNodes = nodes
});
} else {
DebuggerService.ExternalDebugInformation[token] = new DecompileInformation {
CodeMappings = astBuilder.CodeMappings,
LocalVariables = astBuilder.LocalVariables,
DecompiledMemberReferences = astBuilder.DecompiledMemberReferences,
AstNodes = nodes
};
}
var info = new DecompileInformation {
CodeMappings = astBuilder.CodeMappings,
LocalVariables = astBuilder.LocalVariables,
DecompiledMemberReferences = astBuilder.DecompiledMemberReferences,
AstNodes = nodes
};
// save the data
DebuggerService.ExternalDebugInformation.AddOrUpdate(token, info, (k, v) => info);
}
void OnDecompilationFinished(StringWriter output)
@ -222,37 +217,42 @@ namespace ICSharpCode.ILSpyAddIn @@ -222,37 +217,42 @@ namespace ICSharpCode.ILSpyAddIn
if (!DebuggerService.IsDebuggerStarted)
return;
if (DebuggerService.DebugStepInformation != null) {
// get debugging information
DecompileInformation debugInformation = (DecompileInformation)DebuggerService.ExternalDebugInformation[MemberReference.MetadataToken.ToInt32()];
int token = DebuggerService.DebugStepInformation.Item1;
int ilOffset = DebuggerService.DebugStepInformation.Item2;
int line;
MemberReference member;
if (debugInformation.CodeMappings == null || !debugInformation.CodeMappings.ContainsKey(token))
return;
debugInformation.CodeMappings[token].GetInstructionByTokenAndOffset(token, ilOffset, out member, out line);
// HACK : if the codemappings are not built
if (line == 0) {
DebuggerService.CurrentDebugger.StepOver();
return;
}
// update bookmark & marker
codeView.UnfoldAndScroll(line);
CurrentLineBookmark.SetPosition(this, line, 0, line, 0);
if (MemberReference == null || MemberReference.MetadataToken == null)
return;
int typeToken = MemberReference.MetadataToken.ToInt32();
if (!DebuggerService.ExternalDebugInformation.ContainsKey(typeToken))
return;
// get debugging information
DecompileInformation debugInformation = (DecompileInformation)DebuggerService.ExternalDebugInformation[typeToken];
int token = DebuggerService.DebugStepInformation.Item1;
int ilOffset = DebuggerService.DebugStepInformation.Item2;
int line;
MemberReference member;
if (debugInformation.CodeMappings == null || !debugInformation.CodeMappings.ContainsKey(token))
return;
debugInformation.CodeMappings[token].GetInstructionByTokenAndOffset(token, ilOffset, out member, out line);
// HACK : if the codemappings are not built
if (line <= 0) {
DebuggerService.CurrentDebugger.StepOver();
return;
}
// update bookmark & marker
codeView.UnfoldAndScroll(line);
CurrentLineBookmark.SetPosition(this, line, 0, line, 0);
}
public void JumpTo(int lineNumber)
{
if (lineNumber <= 0)
return;
{
if (codeView == null)
return;
if (lineNumber <= 0 || lineNumber > codeView.Document.LineCount)
return;
codeView.UnfoldAndScroll(lineNumber);
}
#endregion

5
src/Main/Base/Project/Src/Services/Debugger/BreakpointBookmark.cs

@ -114,5 +114,10 @@ namespace ICSharpCode.SharpDevelop.Debugging @@ -114,5 +114,10 @@ namespace ICSharpCode.SharpDevelop.Debugging
marker.ForegroundColor = Colors.White;
return marker;
}
public override string ToString()
{
return string.Format("{0} @{1}", this.FileName, this.LineNumber);
}
}
}

18
src/Main/Base/Project/Src/Services/Debugger/CurrentLineBookmark.cs

@ -22,34 +22,34 @@ namespace ICSharpCode.SharpDevelop.Debugging @@ -22,34 +22,34 @@ namespace ICSharpCode.SharpDevelop.Debugging
static int endLine;
static int endColumn;
public static void SetPosition(IViewContent viewContent, int makerStartLine, int makerStartColumn, int makerEndLine, int makerEndColumn)
public static void SetPosition(IViewContent viewContent, int markerStartLine, int markerStartColumn, int markerEndLine, int markerEndColumn)
{
ITextEditorProvider tecp = viewContent as ITextEditorProvider;
if (tecp != null) {
SetPosition(tecp.TextEditor.FileName, tecp.TextEditor.Document, makerStartLine, makerStartColumn, makerEndLine, makerEndColumn);
SetPosition(tecp.TextEditor.FileName, tecp.TextEditor.Document, markerStartLine, markerStartColumn, markerEndLine, markerEndColumn);
} else {
lock (syncObject) {
dynamic codeView = viewContent.Control;
var document = codeView.TextEditor.Document as IDocument;
SetPosition(null, document, makerStartLine, makerStartColumn, makerEndLine, makerEndColumn);
SetPosition(codeView.Adapter.FileName, document, markerStartLine, markerStartColumn, markerEndLine, markerEndColumn);
codeView.IconBarManager.Bookmarks.Add(CurrentLineBookmark.instance);
codeView.UnfoldAndScroll(makerStartLine);
codeView.UnfoldAndScroll(markerStartLine);
if (document != null)
CurrentLineBookmark.instance.Document = document;
}
}
}
public static void SetPosition(FileName fileName, IDocument document, int makerStartLine, int makerStartColumn, int makerEndLine, int makerEndColumn)
public static void SetPosition(FileName fileName, IDocument document, int markerStartLine, int markerStartColumn, int markerEndLine, int markerEndColumn)
{
if (document == null)
return;
Remove();
startLine = makerStartLine;
startColumn = makerStartColumn;
endLine = makerEndLine;
endColumn = makerEndColumn;
startLine = markerStartLine;
startColumn = markerStartColumn;
endLine = markerEndLine;
endColumn = markerEndColumn;
if (startLine < 1 || startLine > document.TotalNumberOfLines)
return;

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

@ -2,6 +2,7 @@ @@ -2,6 +2,7 @@
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Text;
@ -35,7 +36,7 @@ namespace ICSharpCode.SharpDevelop.Debugging @@ -35,7 +36,7 @@ namespace ICSharpCode.SharpDevelop.Debugging
BookmarkManager.Added += BookmarkAdded;
BookmarkManager.Removed += BookmarkRemoved;
ExternalDebugInformation = new Dictionary<int, object>();
ExternalDebugInformation = new ConcurrentDictionary<int, object>();
}
static void GetDescriptors()
@ -110,7 +111,7 @@ namespace ICSharpCode.SharpDevelop.Debugging @@ -110,7 +111,7 @@ namespace ICSharpCode.SharpDevelop.Debugging
/// Gets or sets the external debug information.
/// <summary>This constains the code mappings and local variables.</summary>
/// </summary>
public static Dictionary<int, object> ExternalDebugInformation { get; set; }
public static ConcurrentDictionary<int, object> ExternalDebugInformation { get; private set; }
/// <summary>
/// Gets or sets the current token and IL offset. Used for step in/out.
@ -462,4 +463,25 @@ namespace ICSharpCode.SharpDevelop.Debugging @@ -462,4 +463,25 @@ namespace ICSharpCode.SharpDevelop.Debugging
DebuggerService.HandleToolTipRequest(e);
}
}
/// <summary>
/// Interface for common debugger-decompiler mapping operations.
/// </summary>
public interface IDebuggerDecompilerService
{
/// <summary>
/// Decompiles on demand a type.
/// </summary>
void DecompileOnDemand(TypeDefinition type);
/// <summary>
/// Gets the IL from and IL to.
/// </summary>
bool GetILAndTokenByLineNumber(int typeToken, int lineNumber, out int[] ilRanges, out int memberToken);
/// <summary>
/// Gets the ILRange and source code line number.
/// </summary>
bool GetILAndLineNumber(int typeToken, int memberToken, int ilOffset, out int[] ilRange, out int line, out bool isMatch);
}
}

2
src/Setup/Files.wxs

@ -1425,8 +1425,6 @@ @@ -1425,8 +1425,6 @@
<File Source="..\..\AddIns\Debugger\Debugger.AddIn.addin" Id="Debugger.AddIn.addin" Name="Debugger.AddIn.addin" />
<File Source="..\..\AddIns\Debugger\Debugger.AddIn.dll" Id="Debugger.AddIn.dll" Name="Debugger.AddIn.dll" />
<File Source="..\..\AddIns\Debugger\Debugger.Core.dll" Id="Debugger.Core.dll" Name="Debugger.Core.dll" />
<File Source="..\..\AddIns\Debugger\ICSharpCode.NewNRefactory.dll" Id="Debugger.ICSharpCode.NewNRefactory.dll" Name="ICSharpCode.NewNRefactory.dll" />
<File Source="..\..\AddIns\Debugger\ICSharpCode.Decompiler.dll" Id="Debugger.ICSharpCode.Decompiler.dll" Name="ICSharpCode.Decompiler.dll" />
</Component>
</Directory>
<Directory Id="MiscAddInsFolder" Name="Misc">

Loading…
Cancel
Save