|
|
|
@ -2,7 +2,6 @@
@@ -2,7 +2,6 @@
|
|
|
|
|
// This code is distributed under the BSD license (for details please see \src\AddIns\Debugger\Debugger.AddIn\license.txt)
|
|
|
|
|
|
|
|
|
|
using System; |
|
|
|
|
using System.Collections.Generic; |
|
|
|
|
using System.Diagnostics; |
|
|
|
|
using System.Drawing; |
|
|
|
|
using System.IO; |
|
|
|
@ -583,7 +582,7 @@ namespace ICSharpCode.SharpDevelop.Services
@@ -583,7 +582,7 @@ namespace ICSharpCode.SharpDevelop.Services
|
|
|
|
|
|
|
|
|
|
var stackFrame = !debuggedProcess.IsInExternalCode ? debuggedProcess.SelectedStackFrame : debuggedProcess.SelectedThread.MostRecentStackFrame; |
|
|
|
|
try { |
|
|
|
|
object data = debuggerDecompilerService.GetLocalVariableIndex(stackFrame.MethodInfo.DeclaringType.MetadataToken, |
|
|
|
|
object data = debuggerDecompilerService.GetLocalVariableIndex(stackFrame.MethodInfo.DeclaringType.MetadataToken, |
|
|
|
|
stackFrame.MethodInfo.MetadataToken, |
|
|
|
|
variableName); |
|
|
|
|
// evaluate expression
|
|
|
|
@ -723,7 +722,7 @@ namespace ICSharpCode.SharpDevelop.Services
@@ -723,7 +722,7 @@ namespace ICSharpCode.SharpDevelop.Services
|
|
|
|
|
|
|
|
|
|
// init NDebugger
|
|
|
|
|
debugger = new NDebugger(); |
|
|
|
|
debugger.Options = DebuggingOptions.Instance; |
|
|
|
|
debugger.Options = DebuggingOptions.Instance; |
|
|
|
|
debugger.DebuggerTraceMessage += debugger_TraceMessage; |
|
|
|
|
debugger.Processes.Added += debugger_ProcessStarted; |
|
|
|
|
debugger.Processes.Removed += debugger_ProcessExited; |
|
|
|
@ -755,29 +754,42 @@ namespace ICSharpCode.SharpDevelop.Services
@@ -755,29 +754,42 @@ namespace ICSharpCode.SharpDevelop.Services
|
|
|
|
|
Breakpoint breakpoint = null; |
|
|
|
|
|
|
|
|
|
if (bookmark is DecompiledBreakpointBookmark) { |
|
|
|
|
var dbb = (DecompiledBreakpointBookmark)bookmark; |
|
|
|
|
var memberReference = dbb.MemberReference; |
|
|
|
|
int token = memberReference.MetadataToken.ToInt32(); |
|
|
|
|
|
|
|
|
|
if (!debuggerDecompilerService.CheckMappings(token)) |
|
|
|
|
debuggerDecompilerService.DecompileOnDemand(memberReference as TypeDefinition); |
|
|
|
|
|
|
|
|
|
int[] ilRanges; |
|
|
|
|
int methodToken; |
|
|
|
|
if (debuggerDecompilerService.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(), |
|
|
|
|
methodToken, |
|
|
|
|
dbb.ILFrom, |
|
|
|
|
dbb.IsEnabled); |
|
|
|
|
try { |
|
|
|
|
if (debuggerDecompilerService == null) { |
|
|
|
|
LoggingService.Warn("No IDebuggerDecompilerService found!"); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
var dbb = (DecompiledBreakpointBookmark)bookmark; |
|
|
|
|
MemberReference memberReference = null; |
|
|
|
|
|
|
|
|
|
debugger.Breakpoints.Add(breakpoint); |
|
|
|
|
string assemblyFile, typeName; |
|
|
|
|
if (DecompiledBreakpointBookmark.GetAssemblyAndType(dbb.FileName, out assemblyFile, out typeName)) { |
|
|
|
|
memberReference = dbb.GetMemberReference(debuggerDecompilerService.GetAssemblyResolver(assemblyFile)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int token = memberReference.MetadataToken.ToInt32(); |
|
|
|
|
if (!debuggerDecompilerService.CheckMappings(token)) |
|
|
|
|
debuggerDecompilerService.DecompileOnDemand(memberReference as TypeDefinition); |
|
|
|
|
|
|
|
|
|
int[] ilRanges; |
|
|
|
|
int methodToken; |
|
|
|
|
if (debuggerDecompilerService.GetILAndTokenByLineNumber(token, dbb.LineNumber, out ilRanges, out methodToken)) { |
|
|
|
|
dbb.ILFrom = ilRanges[0]; |
|
|
|
|
dbb.ILTo = ilRanges[1]; |
|
|
|
|
// create BP
|
|
|
|
|
breakpoint = new ILBreakpoint( |
|
|
|
|
debugger, |
|
|
|
|
memberReference.FullName, |
|
|
|
|
dbb.LineNumber, |
|
|
|
|
memberReference.MetadataToken.ToInt32(), |
|
|
|
|
methodToken, |
|
|
|
|
dbb.ILFrom, |
|
|
|
|
dbb.IsEnabled); |
|
|
|
|
|
|
|
|
|
debugger.Breakpoints.Add(breakpoint); |
|
|
|
|
} |
|
|
|
|
} catch (System.Exception ex) { |
|
|
|
|
LoggingService.Error("Error on DecompiledBreakpointBookmark: " + ex.Message); |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
breakpoint = debugger.Breakpoints.Add(bookmark.FileName, null, bookmark.LineNumber, 0, bookmark.IsEnabled); |
|
|
|
@ -1038,56 +1050,49 @@ namespace ICSharpCode.SharpDevelop.Services
@@ -1038,56 +1050,49 @@ namespace ICSharpCode.SharpDevelop.Services
|
|
|
|
|
DebuggerService.JumpToCurrentLine(nextStatement.Filename, nextStatement.StartLine, nextStatement.StartColumn, nextStatement.EndLine, nextStatement.EndColumn); |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
if (debuggerDecompilerService == null) { |
|
|
|
|
LoggingService.Warn("No IDebuggerDecompilerService found!"); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
// use most recent stack frame because we don't have the symbols
|
|
|
|
|
var frame = debuggedProcess.SelectedThread.MostRecentStackFrame; |
|
|
|
|
if (frame == null) |
|
|
|
|
return; |
|
|
|
|
int typeToken = frame.MethodInfo.DeclaringType.MetadataToken; |
|
|
|
|
|
|
|
|
|
// get external data
|
|
|
|
|
int methodToken = frame.MethodInfo.MetadataToken; |
|
|
|
|
int ilOffset = frame.IP; |
|
|
|
|
|
|
|
|
|
int[] ilRanges = null; |
|
|
|
|
int line = -1; |
|
|
|
|
bool isMatch = false; |
|
|
|
|
if (debuggerDecompilerService.GetILAndLineNumber(typeToken, methodToken, ilOffset, out ilRanges, out line, out isMatch)) { |
|
|
|
|
debuggerDecompilerService.DebugStepInformation = null; // we do not need to step into/out
|
|
|
|
|
|
|
|
|
|
// 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, methodToken, ilOffset); |
|
|
|
|
} else { |
|
|
|
|
StepIntoUnknownFrame(frame, methodToken, ilOffset); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
JumpToDecompiledCode(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void StepIntoUnknownFrame(Debugger.StackFrame frame, int token, int ilOffset) |
|
|
|
|
|
|
|
|
|
void JumpToDecompiledCode() |
|
|
|
|
{ |
|
|
|
|
if (debuggerDecompilerService == null) { |
|
|
|
|
LoggingService.Warn("No IDebuggerDecompilerService found!"); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// check for options - if these options are enabled, debugging decompiled code should not continue
|
|
|
|
|
if (debuggedProcess.Options.EnableJustMyCode || debuggedProcess.Options.StepOverNoSymbols) { |
|
|
|
|
LoggingService.Info("Decompiled code debugging is disabled!"); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// use most recent stack frame because we don't have the symbols
|
|
|
|
|
var frame = debuggedProcess.SelectedThread.MostRecentStackFrame; |
|
|
|
|
Debug.Assert(frame != null); |
|
|
|
|
|
|
|
|
|
// get external data
|
|
|
|
|
int typeToken = frame.MethodInfo.DeclaringType.MetadataToken; |
|
|
|
|
int methodToken = frame.MethodInfo.MetadataToken; |
|
|
|
|
int ilOffset = frame.IP; |
|
|
|
|
int[] ilRanges = null; |
|
|
|
|
int line = -1; |
|
|
|
|
bool isMatch = false; |
|
|
|
|
var debugType = (DebugType)frame.MethodInfo.DeclaringType; |
|
|
|
|
string fullName = debugType.FullNameWithoutGenericArguments; |
|
|
|
|
debuggerDecompilerService.DebugStepInformation = Tuple.Create(token, ilOffset); |
|
|
|
|
NavigationService.NavigateTo(debugType.DebugModule.FullPath, debugType.FullNameWithoutGenericArguments, string.Empty); |
|
|
|
|
debuggerDecompilerService.DebugStepInformation = Tuple.Create(methodToken, ilOffset); |
|
|
|
|
|
|
|
|
|
if (debuggerDecompilerService.GetILAndLineNumber(typeToken, methodToken, ilOffset, out ilRanges, out line, out isMatch)) { |
|
|
|
|
// update marker & navigate to line
|
|
|
|
|
NavigationService.NavigateTo(debugType.DebugModule.FullPath, |
|
|
|
|
debugType.FullNameWithoutGenericArguments, |
|
|
|
|
string.Empty, |
|
|
|
|
line); |
|
|
|
|
} else { |
|
|
|
|
// no line => do decompilation
|
|
|
|
|
NavigationService.NavigateTo(debugType.DebugModule.FullPath, |
|
|
|
|
debugType.FullNameWithoutGenericArguments, |
|
|
|
|
string.Empty); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
StopAttachedProcessDialogResult ShowStopAttachedProcessDialog() |
|
|
|
|