public void GetMethodInfo(SerializedDnToken key, out Parameter[] parameters, out Local[] locals, out IILVariable[] decLocals) { parameters = null; locals = null; decLocals = null; foreach (var tab in fileTabManager.VisibleFirstTabs) { if (parameters != null && decLocals != null) break; var uiContext = tab.UIContext as ITextEditorUIContext; var cm = uiContext.TryGetCodeMappings(); if (cm == null) continue; var mapping = cm.TryGetMapping(key); if (mapping == null) continue; var method = mapping.Method; if (mapping.LocalVariables != null && method.Body != null) { locals = method.Body.Variables.ToArray(); decLocals = new IILVariable[method.Body.Variables.Count]; foreach (var v in mapping.LocalVariables) { if (v.GeneratedByDecompiler) continue; if (v.OriginalVariable == null) continue; if ((uint)v.OriginalVariable.Index >= decLocals.Length) continue; decLocals[v.OriginalVariable.Index] = v; } } parameters = method.Parameters.ToArray(); } }
public void Toggle(ITextEditorUIContext uiContext, int line, int column = 0) { var bps = uiContext.GetCodeMappings().Find(line, column); var ilbps = GetILCodeBreakpoints(uiContext, bps); if (ilbps.Count > 0) { if (IsEnabled(ilbps)) { foreach (var ilbp in ilbps) { Remove(ilbp); } } else { foreach (var bpm in ilbps) { bpm.IsEnabled = true; } } } else if (bps.Count > 0) { foreach (var bp in bps) { var md = bp.Mapping.Method; var serMod = serializedDnModuleCreator.Create(md.Module); var key = new SerializedDnToken(serMod, md.MDToken); Add(new ILCodeBreakpoint(key, bp.ILRange.From)); } uiContext.ScrollAndMoveCaretTo(bps[0].StartPosition.Line, bps[0].StartPosition.Column); } }
public static bool GoToIL(IFileTabManager fileTabManager, IDnSpyFile file, uint token, uint ilOffset, bool newTab) { if (file == null) return false; var method = file.ModuleDef.ResolveToken(token) as MethodDef; if (method == null) return false; var serMod = SerializedDnModuleCreator.Create(fileTabManager.FileTreeView, method.Module); var key = new SerializedDnToken(serMod, method.MDToken); bool found = fileTabManager.FileTreeView.FindNode(method.Module) != null; if (found) { fileTabManager.FollowReference(method, newTab, true, e => { Debug.Assert(e.Tab.UIContext is ITextEditorUIContext); if (e.Success && !e.HasMovedCaret) { MoveCaretTo(e.Tab.UIContext as ITextEditorUIContext, key, ilOffset); e.HasMovedCaret = true; } }); return true; } Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() => { fileTabManager.FollowReference(method, newTab, true, e => { Debug.Assert(e.Tab.UIContext is ITextEditorUIContext); if (e.Success && !e.HasMovedCaret) { MoveCaretTo(e.Tab.UIContext as ITextEditorUIContext, key, ilOffset); e.HasMovedCaret = true; } }); })); return true; }
string GetMethodAsString(SerializedDnToken key) { var file = moduleLoader.Value.LoadModule(key.Module, true, true); var method = file == null ? null : file.ModuleDef.ResolveToken(key.Token) as MethodDef; return(method == null ? null : method.ToString()); }
void LoadInternal() { var section = settingsManager.GetOrCreateSection(SETTINGS_GUID); breakpointManager.Clear(); foreach (var bpx in section.SectionsWithName("Breakpoint")) { uint? token = bpx.Attribute <uint?>("Token"); string asmFullName = bpx.Attribute <string>("AssemblyFullName"); string moduleName = bpx.Attribute <string>("ModuleName"); bool? isDynamic = bpx.Attribute <bool?>("IsDynamic"); bool? isInMemory = bpx.Attribute <bool?>("IsInMemory"); bool moduleNameOnly = bpx.Attribute <bool?>("ModuleNameOnly") ?? false; uint? ilOffset = bpx.Attribute <uint?>("ILOffset"); bool? isEnabled = bpx.Attribute <bool?>("IsEnabled"); if (token == null) { continue; } if (isDynamic == null || isInMemory == null) { continue; } if (string.IsNullOrEmpty(asmFullName) && !moduleNameOnly) { continue; } if (string.IsNullOrEmpty(moduleName)) { continue; } if (ilOffset == null) { continue; } if (isEnabled == null) { continue; } var snModule = SerializedDnModule.Create(asmFullName, moduleName, isDynamic.Value, isInMemory.Value, moduleNameOnly); var key = new SerializedDnToken(snModule, token.Value); if (!isInMemory.Value && !isDynamic.Value) { var s = bpx.Attribute <string>("Method"); if (s == null || s != GetMethodAsString(key)) { continue; } } var bp = new ILCodeBreakpoint(key, ilOffset.Value, isEnabled.Value); breakpointManager.Add(bp); } }
public void GetMethodInfo(SerializedDnToken key, out Parameter[] parameters, out Local[] locals, out IILVariable[] decLocals) { parameters = null; locals = null; decLocals = null; foreach (var tab in fileTabManager.VisibleFirstTabs) { if (parameters != null && decLocals != null) { break; } var uiContext = tab.UIContext as ITextEditorUIContext; var cm = uiContext.TryGetCodeMappings(); if (cm == null) { continue; } var mapping = cm.TryGetMapping(key); if (mapping == null) { continue; } var method = mapping.Method; if (mapping.LocalVariables != null && method.Body != null) { locals = method.Body.Variables.ToArray(); decLocals = new IILVariable[method.Body.Variables.Count]; foreach (var v in mapping.LocalVariables) { if (v.GeneratedByDecompiler) { continue; } if (v.OriginalVariable == null) { continue; } if ((uint)v.OriginalVariable.Index >= decLocals.Length) { continue; } decLocals[v.OriginalVariable.Index] = v; } } parameters = method.Parameters.ToArray(); } }
public static bool MoveCaretTo(ITextEditorUIContext uiContext, SerializedDnToken key, uint ilOffset) { if (uiContext == null) return false; CodeMappings cm; if (!VerifyAndGetCurrentDebuggedMethod(uiContext, key, out cm)) return false; TextPosition location, endLocation; if (!cm.TryGetMapping(key).GetInstructionByTokenAndOffset(ilOffset, out location, out endLocation)) return false; uiContext.ScrollAndMoveCaretTo(location.Line, location.Column); return true; }
public CodeMappings(IList<MemberMapping> mappings, ISerializedDnModuleCreator serializedDnModuleCreator) { this.dict = new Dictionary<SerializedDnToken, MemberMapping>(mappings.Count); var serDict = new Dictionary<ModuleDef, SerializedDnModule>(); foreach (var m in mappings) { var module = m.Method.Module; if (module == null) continue; SerializedDnModule serMod; if (!serDict.TryGetValue(module, out serMod)) { serMod = serializedDnModuleCreator.Create(module); serDict.Add(module, serMod); } var key = new SerializedDnToken(serMod, m.Method.MDToken); MemberMapping oldMm; if (this.dict.TryGetValue(key, out oldMm)) { if (m.MemberCodeMappings.Count < oldMm.MemberCodeMappings.Count) continue; } this.dict[key] = m; } }
public MemberMapping TryGetMapping(SerializedDnToken key) { MemberMapping mm; dict.TryGetValue(key, out mm); return mm; }
void LoadInternal() { var section = settingsManager.GetOrCreateSection(SETTINGS_GUID); breakpointManager.Clear(); foreach (var bpx in section.SectionsWithName("Breakpoint")) { uint? token = bpx.Attribute<uint?>("Token"); string asmFullName = bpx.Attribute<string>("AssemblyFullName"); string moduleName = bpx.Attribute<string>("ModuleName"); bool? isDynamic = bpx.Attribute<bool?>("IsDynamic"); bool? isInMemory = bpx.Attribute<bool?>("IsInMemory"); uint? ilOffset = bpx.Attribute<uint?>("ILOffset"); bool? isEnabled = bpx.Attribute<bool?>("IsEnabled"); if (token == null) continue; if (isDynamic == null || isInMemory == null) continue; if (string.IsNullOrEmpty(asmFullName)) continue; if (string.IsNullOrEmpty(moduleName)) continue; if (ilOffset == null) continue; if (isEnabled == null) continue; var snModule = SerializedDnModule.Create(asmFullName, moduleName, isDynamic.Value, isInMemory.Value); var key = new SerializedDnToken(snModule, token.Value); if (!isInMemory.Value && !isDynamic.Value) { var s = bpx.Attribute<string>("Method"); if (s == null || s != GetMethodAsString(key)) continue; } var bp = new ILCodeBreakpoint(key, ilOffset.Value, isEnabled.Value); breakpointManager.Add(bp); } }
/// <summary> /// Should be called each time the IL offset has been updated /// </summary> bool UpdateStackFrameLines(ITextEditorUIContext uiContext, bool moveCaret = false) { if (uiContext == null) { return(false); } Remove(uiContext); bool movedCaret = false; var cm = uiContext.TryGetCodeMappings(); bool updateReturnStatements = cm != null && theDebugger.ProcessState == DebuggerProcessState.Paused; if (updateReturnStatements) { int frameNo = -1; bool tooManyFrames; foreach (var frame in GetFrames(MAX_STACKFRAME_LINES, out tooManyFrames)) { frameNo++; if (!frame.IsILFrame) { continue; } var ip = frame.ILFrameIP; if (!ip.IsExact && !ip.IsApproximate && !ip.IsProlog && !ip.IsEpilog) { continue; } uint token = frame.Token; if (token == 0) { continue; } var serAsm = frame.SerializedDnModule; if (serAsm == null) { continue; } StackFrameLineType type; if (frameNo == 0) { type = StackFrameLineType.CurrentStatement; } else { type = currentState.FrameNumber == frameNo ? StackFrameLineType.SelectedReturnStatement : StackFrameLineType.ReturnStatement; } var key = new SerializedDnToken(serAsm.Value, token); uint offset = frame.GetILOffset(moduleLoader.Value); MethodDef methodDef; TextPosition location, endLocation; var mm = cm.TryGetMapping(key); if (mm != null && mm.GetInstructionByTokenAndOffset(offset, out methodDef, out location, out endLocation)) { var rs = new StackFrameLine(type, uiContext, key, offset); stackFrameLines.Add(rs); textLineObjectManager.Add(rs); if (moveCaret && frameNo == currentState.FrameNumber) { uiContext.ScrollAndMoveCaretTo(location.Line, location.Column); movedCaret = true; } } } } return(movedCaret); }
public static bool VerifyAndGetCurrentDebuggedMethod(ITextEditorUIContext uiContext, SerializedDnToken serToken, out CodeMappings codeMappings) { codeMappings = uiContext.GetCodeMappings(); return codeMappings.TryGetMapping(serToken) != null; }
public StackFrameLine(StackFrameLineType type, ITextEditorUIContext uiContext, SerializedDnToken methodKey, uint ilOffset) : base(methodKey, ilOffset) { this.type = type; this.uiContext = uiContext; }
public MyMarkedTextLine(ILCodeBreakpoint ilbp, SerializedDnToken methodKey, uint ilOffset) : base(methodKey, ilOffset, ilbp) { this.ilbp = ilbp; }
public ILCodeBreakpoint(SerializedDnToken methodKey, uint ilOffset, bool isEnabled = true) : base(isEnabled) { this.myMarkedTextLine = new MyMarkedTextLine(this, methodKey, ilOffset); }
public void Toggle(ITextEditorUIContext uiContext, int line, int column = 0) { var bps = uiContext.GetCodeMappings().Find(line, column); var ilbps = GetILCodeBreakpoints(uiContext, bps); if (ilbps.Count > 0) { if (IsEnabled(ilbps)) { foreach (var ilbp in ilbps) Remove(ilbp); } else { foreach (var bpm in ilbps) bpm.IsEnabled = true; } } else if (bps.Count > 0) { foreach (var bp in bps) { var md = bp.Mapping.Method; var serMod = serializedDnModuleCreator.Create(md.Module); var key = new SerializedDnToken(serMod, md.MDToken); Add(new ILCodeBreakpoint(key, bp.ILRange.From)); } uiContext.ScrollAndMoveCaretTo(bps[0].StartPosition.Line, bps[0].StartPosition.Column); } }
string GetMethodAsString(SerializedDnToken key) { var file = moduleLoader.Value.LoadModule(key.Module, true, true); var method = file == null ? null : file.ModuleDef.ResolveToken(key.Token) as MethodDef; return method == null ? null : method.ToString(); }
/// <summary> /// Should be called each time the IL offset has been updated /// </summary> bool UpdateStackFrameLines(ITextEditorUIContext uiContext, bool moveCaret = false) { if (uiContext == null) return false; Remove(uiContext); bool movedCaret = false; var cm = uiContext.TryGetCodeMappings(); bool updateReturnStatements = cm != null && theDebugger.ProcessState == DebuggerProcessState.Stopped; if (updateReturnStatements) { int frameNo = -1; bool tooManyFrames; foreach (var frame in GetFrames(MAX_STACKFRAME_LINES, out tooManyFrames)) { frameNo++; if (!frame.IsILFrame) continue; var ip = frame.ILFrameIP; if (!ip.IsExact && !ip.IsApproximate && !ip.IsProlog && !ip.IsEpilog) continue; uint token = frame.Token; if (token == 0) continue; var serAsm = frame.SerializedDnModule; if (serAsm == null) continue; StackFrameLineType type; if (frameNo == 0) type = StackFrameLineType.CurrentStatement; else type = currentState.FrameNumber == frameNo ? StackFrameLineType.SelectedReturnStatement : StackFrameLineType.ReturnStatement; var key = new SerializedDnToken(serAsm.Value, token); uint offset = frame.GetILOffset(moduleLoader.Value); MethodDef methodDef; TextPosition location, endLocation; var mm = cm.TryGetMapping(key); if (mm != null && mm.GetInstructionByTokenAndOffset(offset, out methodDef, out location, out endLocation)) { var rs = new StackFrameLine(type, uiContext, key, offset); stackFrameLines.Add(rs); textLineObjectManager.Add(rs); if (moveCaret && frameNo == currentState.FrameNumber) { uiContext.ScrollAndMoveCaretTo(location.Line, location.Column); movedCaret = true; } } } } return movedCaret; }
protected MarkedTextLine(SerializedDnToken methodKey, uint ilOffset, IMarkedTextLine senderObj = null) { this.methodKey = methodKey; this.ilOffset = ilOffset; this.senderObj = senderObj ?? this; }