@ -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 . SourceCodeL ine;
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 . Metadata Token,
method Token,
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 , me thodT oken, 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 ;
}
}
}