diff --git a/Debugger/ILSpy.Debugger/Services/Debugger/WindowsDebugger.cs b/Debugger/ILSpy.Debugger/Services/Debugger/WindowsDebugger.cs index 4dd3068a0..181a32a7c 100644 --- a/Debugger/ILSpy.Debugger/Services/Debugger/WindowsDebugger.cs +++ b/Debugger/ILSpy.Debugger/Services/Debugger/WindowsDebugger.cs @@ -826,42 +826,51 @@ namespace ILSpy.Debugger.Services if (CodeMappingsStorage.GetSourceCodeFromMetadataTokenAndOffset(token, ilOffset, out type, out line)) { DebuggerService.JumpToCurrentLine(type, line, 0, line, 0); } else { - var debugType = frame.MethodInfo.DeclaringType; - string fullName = debugType.Namespace + "." + debugType.Name; + // is possible that the type is not decompiled yet, so we must do a decompilation on demand + DecompileOnDemand(frame); + } + } + } + + void DecompileOnDemand(StackFrame frame) + { + var debugType = frame.MethodInfo.DeclaringType; + uint token = (uint)frame.MethodInfo.MetadataToken; + int ilOffset = frame.IP; + + string fullName = debugType.Namespace + "." + debugType.Name; + if (DebugData.LoadedAssemblies == null) + Continue(); + else { + // search for type in the current assembly list + TypeReference typeRef = null; + foreach (var assembly in DebugData.LoadedAssemblies) { + foreach (var module in assembly.Modules) { + if (module.TryGetTypeReference(fullName, out typeRef)) { + break; + } + } + if (typeRef != null) + break; + } + if (typeRef != null) { + // decompile on demand + AstBuilder builder = new AstBuilder(new DecompilerContext()); + builder.AddType(typeRef.Resolve()); + builder.GenerateCode(new PlainTextOutput()); - if (DebugData.LoadedAssemblies == null) + // try jump + int line; + TypeDefinition type; + if (CodeMappingsStorage.GetSourceCodeFromMetadataTokenAndOffset(token, ilOffset, out type, out line)) { + DebuggerService.JumpToCurrentLine(type, line, 0, line, 0); + } else { + // continue since we cannot find the debugged type Continue(); - else { - // search for type in the current assembly list - TypeReference typeRef = null; - foreach (var assembly in DebugData.LoadedAssemblies) { - foreach (var module in assembly.Modules) { - if (module.TryGetTypeReference(fullName, out typeRef)) { - break; - } - } - - if (typeRef != null) - break; - } - - if (typeRef != null) { - // decompile on demand - AstBuilder builder = new AstBuilder(new DecompilerContext()); - builder.AddType(typeRef.Resolve()); - builder.GenerateCode(new PlainTextOutput()); - - // jump - if (CodeMappingsStorage.GetSourceCodeFromMetadataTokenAndOffset(token, ilOffset, out type, out line)) { - DebuggerService.JumpToCurrentLine(type, line, 0, line, 0); - } else { - StepOut(); - } - } else { - // continue since we cannot find the debugged type - StepOut(); - } } + } else { + // continue since we cannot find the debugged type + Continue(); } } } diff --git a/ICSharpCode.Decompiler/CodeMappings.cs b/ICSharpCode.Decompiler/CodeMappings.cs index ff74e12f9..366db3c56 100644 --- a/ICSharpCode.Decompiler/CodeMappings.cs +++ b/ICSharpCode.Decompiler/CodeMappings.cs @@ -48,7 +48,9 @@ namespace ICSharpCode.Decompiler var resultList = new List(); // add list for the current source code line - var currentList = MemberMapping.MemberCodeMappings.FindAll(m => m.SourceCodeLine == this.SourceCodeLine); + var currentList = MemberMapping.MemberCodeMappings + .FindAll(m => m.SourceCodeLine == this.SourceCodeLine) + .OrderBy(m => m.ILInstructionOffset.From); foreach (var element in currentList.Distinct(new SourceCodeMappingComparer())) { resultList.Add(element.ILInstructionOffset.From); resultList.Add(element.ILInstructionOffset.To); @@ -166,6 +168,12 @@ namespace ICSharpCode.Decompiler this MethodDefinition member, ConcurrentDictionary> codeMappings) { + if (member == null || !member.HasBody) + return null; + + if (codeMappings == null) + throw new ArgumentNullException("CodeMappings storage must be valid!"); + // create IL/CSharp code mappings - used in debugger MemberMapping currentMemberMapping = null; if (codeMappings.ContainsKey(member.DeclaringType.FullName)) { @@ -198,6 +206,9 @@ namespace ICSharpCode.Decompiler int lineNumber, out uint metadataToken) { + if (codeMappings == null) + throw new ArgumentNullException("CodeMappings storage must be valid!"); + if (!codeMappings.ContainsKey(typeName)) { metadataToken = 0; return null;