public List <O2MDbgVariable> getCurrentFrameVariables(int expandDepth, bool canDoFunceval) { var o2MDbgVariables = new List <O2MDbgVariable>(); try { //MDbgFrame frame = DI.o2MDbg.ActiveProcess.Threads.Active.CurrentFrame; // Debugger variables /*MDbgProcess activeProcess = DI.o2MDbg.ActiveProcess; * foreach (MDbgDebuggerVar dv in activeProcess.DebuggerVars) * { * var v = new MDbgValue(activeProcess, dv.CorValue); * DI.log.debug(dv.Name + "=" + v.GetStringValue(expandDepth, canDoFunceval)); * }*/ if (o2MDbg.ActiveProcess.IsRunning == false) { MDbgFrame frame = DI.o2MDbg.ActiveProcess.Threads.Active.CurrentFrame; MDbgFunction function = frame.Function; var vars = new List <MDbgValue>(); MDbgValue[] vals = function.GetActiveLocalVars(frame); if (vals != null) { vars.AddRange(vals); } vals = function.GetArguments(frame); if (vals != null) { vars.AddRange(vals); } var functionFullName = function.FullName; //var functionAssembly = function.Module.CorModule.Assembly.Name; foreach (MDbgValue mdbgValue in vars) { //var valueAssembly = ""mdbgValue.CorValue.ExactType.Class.Module.Assembly.Name; /*if (mdbgValue.TypeName.IndexOf("System.Web") > -1) * { * CorType cor = mdbgValue.CorValue.ExactType; * var corclas = cor.Class; * //corclas.Module.Assembly.Name * }*/ o2MDbgVariables.Add(new O2MDbgVariable(mdbgValue, functionFullName, "")); } } } catch (Exception ex) { if (false == DI.o2MDbg.AnimateOnStepEvent && ex.Message.IndexOf("zoobie") > -1) { DI.log.ex(ex, "in showFrameVariables"); } } return(o2MDbgVariables); }
// Update list w/ current callstack. Return an array of FramePair representing the callstack. // Run on worker thread. static FramePair[] GetFrameList(MDbgThread thread) { // Populate listbox with frames. MDbgFrame f = thread.BottomFrame; MDbgFrame af = thread.HaveCurrentFrame ? thread.CurrentFrame : null; System.Collections.ArrayList l = new System.Collections.ArrayList(); int i = 0; int depth = 20; bool verboseOutput = true; while (f != null && (depth == 0 || i < depth)) { string line; if (f.IsInfoOnly) { line = string.Format(CultureInfo.InvariantCulture, "[{0}]", f.ToString()); } else { string frameDescription = "<unknown>"; try { // Get IP info. uint ipNative; uint ipIL; CorDebugMappingResult result; f.CorFrame.GetNativeIP(out ipNative); f.CorFrame.GetIP(out ipIL, out result); string frameLocation = String.Format(CultureInfo.InvariantCulture, " N=0x{0:x}, IL=0x{1:x} ({2})", ipNative, ipIL, result.ToString()); // This may actually do a ton of work, including evaluating parameters. frameDescription = f.ToString(verboseOutput ? "v" : null) + frameLocation; } catch (System.Runtime.InteropServices.COMException) { if (f.Function != null) { frameDescription = f.Function.FullName; } } line = string.Format(CultureInfo.InvariantCulture, "{0}{1}. {2}", f.Equals(af) ? "*" : " ", i, frameDescription); ++i; } l.Add(new FramePair(f, line)); f = f.NextUp; } if (f != null && depth != 0) // means we still have some frames to show.... { l.Add(new FramePair(null, string.Format(CultureInfo.InvariantCulture, "displayed only first {0} frames. For more frames use -c switch", depth) )); } return((FramePair[])l.ToArray(typeof(FramePair))); }
// Notify this window that it's entering break mode. // Called on UI thread. protected override void OnBreakWorker() { ClearHighlight(); m_CurrentIpRow = -1; MainForm.ExecuteOnWorkerThreadIfStoppedAndBlock(delegate(MDbgProcess proc) { Debug.Assert(proc != null); Debug.Assert(!proc.IsRunning); MDbgThread t = proc.Threads.Active; MDbgFrame f = t.CurrentFrame; if ((f != null) && (f.Function == m_function)) { uint offsetIl; CorDebugMappingResult result; f.CorFrame.GetIP(out offsetIl, out result); // mapping is 0-based; row is 1-based. m_CurrentIpRow = m_il2RowMapping[offsetIl] + 1; } }); if (m_CurrentIpRow != -1) { HighlightRow(m_CurrentIpRow, MainForm.IsCurrentSourceActive); } }
// Called On UI thread. protected override void RefreshToolWindowInternal() { MDbgFrame frame = null; MDbgValue[] locals = null; MDbgValue[] args = null; MainForm.ExecuteOnWorkerThreadIfStoppedAndBlock(delegate(MDbgProcess proc) { frame = GetCurrentFrame(proc); if (frame == null) { return; } // Add Vars to window. MDbgFunction f = frame.Function; locals = f.GetActiveLocalVars(frame); args = f.GetArguments(frame); if (proc.IsEvalSafe()) { EvalWatch(proc); } }); if (frame == null) { return; } // Reset TreeView t = this.treeView1; t.BeginUpdate(); t.Nodes.Clear(); // Add Vars to window. if (locals != null) { foreach (MDbgValue v in locals) { Util.PrintInternal(MainForm, v, t.Nodes); } } if (args != null) { foreach (MDbgValue v in args) { Util.PrintInternal(MainForm, v, t.Nodes); } } t.EndUpdate(); } // refresh
private static void DumpLocals(MDbgFrame frame) { var locals = frame.Function.GetActiveLocalVars(frame); foreach (var local in locals) { Console.WriteLine("\t" + DumpValue(local)); } }
string FormatCallInfo(MDbgFrame frame) { var args = string.Join(", ", frame.Function.GetArguments(frame).Select(a => a.TypeName.ReplaceClrAliaces() + " " + a.Name).ToArray()); return(string.Format("{0}!{1}({2}) Line {3}", Path.GetFileName(frame.Function.Module.CorModule.Assembly.Name), frame.Function.FullName, args, frame.SourcePosition.StartLine)); }
public static string GetCurrentLocationInSource(MDbgEngine debugger, IShell shell) { if (!debugger.Processes.Active.Threads.HaveActive) { return(""); // we won't try to show current location } MDbgThread thr = debugger.Processes.Active.Threads.Active; MDbgSourcePosition pos = thr.CurrentSourcePosition; if (pos == null) { MDbgFrame f = thr.CurrentFrame; if (f.IsManaged) { CorDebugMappingResult mappingResult; uint ip; f.CorFrame.GetIP(out ip, out mappingResult); string s = "IP: " + ip + " @ " + f.Function.FullName + " - " + mappingResult; return(s); } else { return("<Located in native code.>"); } } else { string fileLoc = shell.FileLocator.GetFileLocation(pos.Path); if (fileLoc == null) { // Using the full path makes debugging output inconsistant during automated test runs. // For testing purposes we'll get rid of them. //CommandBase.WriteOutput("located at line "+pos.Line + " in "+ pos.Path); return("located at line " + pos.Line + " in " + System.IO.Path.GetFileName(pos.Path)); } else { IMDbgSourceFile file = shell.SourceFileMgr.GetSourceFile(fileLoc); string prefixStr = pos.Line.ToString(CultureInfo.InvariantCulture) + ":"; if (pos.Line < 1 || pos.Line > file.Count) { shell.WriteLine("located at line " + pos.Line + " in " + pos.Path); throw new Exception(string.Format("Could not display current location; file {0} doesn't have line {1}.", file.Path, pos.Line)); } Debug.Assert((pos.Line > 0) && (pos.Line <= file.Count)); return(file[pos.Line]); } } }
internal List <O2MDbgVariable> getCurrentFrameVariable(O2MDbgVariable o2MDbgVariable) { var o2MDbgVariables = new List <O2MDbgVariable>(); try { MDbgFrame frame = DI.o2MDbg.ActiveProcess.Threads.Active.CurrentFrame; MDbgValue mbbgValue = DI.o2MDbg.ActiveProcess.ResolveVariable(o2MDbgVariable.fullName, frame); if (mbbgValue != null && mbbgValue.IsComplexType) { try { // add properties var valueType = mbbgValue.TypeName; var valueAssembly = mbbgValue.CorValue.ExactType.Class.Module.Assembly.Name; //var properties2 = DI.reflection.getProperties(DI.reflection.getType(valueAssembly,valueType)); var properties = DI.reflection.getProperties(DI.reflection.getType(valueAssembly, valueType)); foreach (var property in properties) { o2MDbgVariables.Add(new O2MDbgVariable(property, o2MDbgVariable)); } } catch (Exception ex) { DI.log.ex(ex, "in getCurrentFrameVariable , add properties"); } // add values try { foreach (MDbgValue mdbgValue in mbbgValue.GetFields()) { if (mdbgValue != null) { o2MDbgVariables.Add(new O2MDbgVariable(mdbgValue, o2MDbgVariable)); } } } catch (Exception ex) { DI.log.ex(ex, "in getCurrentFrameVariable , add values"); } } } catch (Exception ex) { DI.log.ex(ex, "in getCurrentFrameVariable"); } return(o2MDbgVariables); }
private IEnumerable <MDbgValue> GetActiveLocalVariables() { MDbgFrame frame = shell.Debugger.Processes.Active.Threads.Active.CurrentFrame; MDbgFunction f = frame.Function; var vars = new List <MDbgValue>(); var vals = f.GetActiveLocalVars(frame); if (vals != null) { vars.AddRange(vals); } return(vars); }
private IEnumerable <MDbgValue> GetArguments() { MDbgFrame frame = shell.Debugger.Processes.Active.Threads.Active.CurrentFrame; MDbgFunction f = frame.Function; var vars = new List <MDbgValue>(); var vals = f.GetArguments(frame); if (vals != null) { vars.AddRange(vals.Where(v => v.Name != "this")); } return(vars); }
// Resolve the expression to a value. // Returns "Null" if we can't resolve the arg. // called on UI thread. MDbgValue Resolve(string arg) { MDbgValue var = null; MainForm.ExecuteOnWorkerThreadIfStoppedAndBlock(delegate(MDbgProcess proc) { MDbgFrame frame = GetCurrentFrame(proc); if (frame == null) { return; } var = proc.ResolveVariable(arg, frame); }); return(var); }
public static void WatchTrace(String argString) { PrepareCall(argString); while (true) { if (!Debugger.Processes.HaveActive) { break; } // check call depth if (maxDepth > 0 && depth >= maxDepth) { // if greater than maximum step out of the function Debugger.Processes.Active.StepOut().WaitOne(); } else { // otherwise step one instruction Debugger.Processes.Active.StepInto(false).WaitOne(); } MDbgFrame frame = GetCurrentFrame(); if (frame == null) { break; } String funcName = frame.Function.FullName; if (!String.Equals(funcName, lastFuncName, StringComparison.Ordinal)) { depth = CalculateCallDepth(frame); if (depth < 0) { // it may happen if we are out of our base function // so we need to stop tracing break; } PrintCallStackTrace(funcName, depth); lastFuncName = funcName; } } // let's handle control to the debugger Shell.DisplayCurrentLocation(); }
private static int CalculateCallDepth(MDbgFrame frame) { int depth = 0; while (frame != null) { if (frame.IsManaged) { Debug.Assert(frame.Function != null); if (String.Equals(frame.Function.FullName, startFuncName, StringComparison.Ordinal)) { return(depth); } } frame = frame.NextUp; depth++; } return(-1); }
static MDbgFrame GetFrameByIndex(MDbgThread thread, int index) { MDbgFrame f = thread.BottomFrame; int count = 0; int depth = 20; while (f != null && (depth == 0 || count < depth)) { if (count == index) { return(f); } count++; f = f.NextUp; } return(null); }
// Helpers // Get the current frame for the process // Only called on Worker thread. public static MDbgFrame GetCurrentFrame(MDbgProcess proc) { if (proc == null) { return null; } if (!proc.Threads.HaveActive) { return null; } MDbgThread thread = proc.Threads.Active; if (!thread.HaveCurrentFrame) { return null; } MDbgFrame frame = thread.CurrentFrame; return frame; }
public static void InternalWhereCommand(MDbgThread thread, int depth, bool verboseOutput) { if (thread != null) { CommandBase.WriteOutput("Thread [#:" + MdbgCommands.g_threadNickNames.GetThreadName(thread) + "]"); MDbgFrame af = thread.HaveCurrentFrame ? thread.CurrentFrame : null; MDbgFrame f = thread.BottomFrame; int i = 0; while (f != null && (depth == 0 || i < depth)) { string line; if (f.IsInfoOnly) { if (!CommandBase.ShowInternalFrames) { // in cases when we don't want to show internal frames, we'll skip them f = f.NextUp; continue; } line = String.Format(CultureInfo.InvariantCulture, " {0}", f); } else { string frameDescription = f.ToString(verboseOutput ? "v" : null); line = String.Format(CultureInfo.InvariantCulture, "{0}{1}. {2}", f.Equals(af) ? "*" : " ", i, frameDescription); ++i; } CommandBase.WriteOutput(line); f = f.NextUp; } if (f != null && depth != 0) // means we still have some frames to show.... { CommandBase.WriteOutput(String.Format(CultureInfo.InvariantCulture, "displayed only first {0} frames. For more frames use -c switch", depth)); } } }
// Invoked when we change the selection on the list box. // This will change the current active frame in the debugger and refresh. private void listBoxCallstack_DoubleClicked(object sender, EventArgs e) { object o = this.listBoxCallstack.SelectedItem; FramePair pair = (FramePair)o; MDbgFrame f = pair.m_frame; if (f == null) { return; } MainForm.ExecuteOnWorkerThreadIfStoppedAndBlock(delegate(MDbgProcess proc) { Debug.Assert(proc != null); Debug.Assert(!proc.IsRunning); // Update callstack MDbgThread t = proc.Threads.Active; try { t.CurrentFrame = f; } catch (InvalidOperationException) { // if it throws an invalid op, then that means our frames somehow got out of sync // and we weren't fully refreshed. return; } } // end delegate ); // Need to refresh UI to show update. this.MainForm.ShowCurrentLocation(); this.MainForm.Invalidate(); } // end listBoxCallstack_DoubleClicked
private void RefreshVarData() { _Lines.Clear(); //this.Append(string.Empty.PadRight(Console.WindowWidth, cellHorizontalLine)); this.Append(string.Empty.PadRight(29, cellHorizontalLine) + cellHorizontalJointTop + string.Empty.PadRight(39, cellHorizontalLine) + cellHorizontalJointTop + string.Empty.PadRight(30, cellHorizontalLine)); // get all active variables MDbgFrame frame = _Shell.Debugger.Processes.Active.Threads.Active.CurrentFrame; MDbgFunction f = frame.Function; ArrayList vars = new ArrayList(); MDbgValue[] vals = f.GetArguments(frame); if (vals != null) { vars.AddRange(vals); } vals = f.GetActiveLocalVars(frame); if (vals != null) { vars.AddRange(vals); } foreach (MDbgValue v in vars) { string name = v.Name.PadRight(29, ' ') + cellVerticalLine; string value = v.GetStringValue(0, true).PadRight(39, ' ') + cellVerticalLine; string type = v.TypeName.PadRight(30, ' '); this.Append(name + value + type); } }
void ReportLocals() { var result = ""; try { if (IsInBreakMode) { MDbgFrame frame = GetCurrentFrame(); MDbgFunction f = frame.Function; MDbgValue[] locals = f.GetActiveLocalVars(frame); MDbgValue[] arguments = f.GetArguments(frame); result = "<locals>" + string.Join("", arguments.Concat(locals) .Where(x => !x.Name.Contains("$")) //ignore any internal vars .Select(x => Serialize(x)) .ToArray()) + "</locals>"; } } catch { } MessageQueue.AddNotification(NppCategory.Locals + result); }
string FormatSourcePosition(MDbgFrame frame) { var f = frame; while (f != null && f.SourcePosition == null) { f = f.NextUp; } if (f == null || f.SourcePosition == null) { return(null); } else { return(String.Format("{0}|{1}:{2}|{3}:{4}", f.SourcePosition.Path, f.SourcePosition.StartLine, f.SourcePosition.StartColumn, f.SourcePosition.EndLine, f.SourcePosition.EndColumn)); } }
public static void PrintCmd(string arguments, O2Thread.FuncVoidT1 <string> o2Callback) { const string debuggerVarsOpt = "d"; const string noFuncevalOpt = "nf"; const string expandDepthOpt = "r"; var ap = new ArgParser(arguments, debuggerVarsOpt + ";" + noFuncevalOpt + ";" + expandDepthOpt + ":1"); bool canDoFunceval = !ap.OptionPassed(noFuncevalOpt); int?expandDepth = null; // we use optional here because // different codes bellow has different // default values. if (ap.OptionPassed(expandDepthOpt)) { expandDepth = ap.GetOption(expandDepthOpt).AsInt; if (expandDepth < 0) { throw new MDbgShellException("Depth cannot be negative."); } } MDbgFrame frame = CommandBase.Debugger.Processes.Active.Threads.Active.CurrentFrame; if (ap.OptionPassed(debuggerVarsOpt)) { // let's print all debugger variables MDbgProcess p = CommandBase.Debugger.Processes.Active; foreach (MDbgDebuggerVar dv in p.DebuggerVars) { var v = new MDbgValue(p, dv.CorValue); CommandBase.WriteOutput(dv.Name + "=" + v.GetStringValue(expandDepth == null ? 0 : (int)expandDepth, canDoFunceval)); } } else { if (ap.Count == 0) { // get all active variables MDbgFunction f = frame.Function; var vars = new ArrayList(); MDbgValue[] vals = f.GetActiveLocalVars(frame); if (vals != null) { vars.AddRange(vals); } vals = f.GetArguments(frame); if (vals != null) { vars.AddRange(vals); } foreach (MDbgValue v in vars) { CommandBase.WriteOutput(v.Name + "=" + v.GetStringValue(expandDepth == null ? 0 : (int)expandDepth, canDoFunceval)); } } else { // user requested printing of specific variables for (int j = 0; j < ap.Count; ++j) { MDbgValue var = CommandBase.Debugger.Processes.Active.ResolveVariable(ap.AsString(j), frame); if (var != null) { CommandBase.WriteOutput(ap.AsString(j) + "=" + var.GetStringValue(expandDepth == null ? 1 : (int)expandDepth, canDoFunceval)); } else { throw new MDbgShellException("Variable not found"); } } } } }
private static string DumpArguments(MDbgFrame frame) { var arguments = frame.Function.GetArguments(frame); return(string.Join(", ", arguments.Select(DumpValue))); }
// Add item to list // 'stText' is what we display in the list box. // 'frame' is the underlying frame associated with the text. Can be null if there's no frame. void AddItem(string stText, MDbgFrame frame) { ListBox.ObjectCollection list = this.listBoxCallstack.Items; list.Add(new FramePair(frame, stText)); }
public FramePair(MDbgFrame f, String s) { m_frame = f; m_displayString = s; }
public virtual void DisplayCurrentLocation() { if (!Debugger.Processes.HaveActive) { CommandBase.WriteOutput("STOP: Process Exited"); return; // don't try to display current location } else { Debug.Assert(Debugger.Processes.HaveActive); Object stopReason = Debugger.Processes.Active.StopReason; Type stopReasonType = stopReason.GetType(); if (stopReasonType == typeof(StepCompleteStopReason)) { // just ignore those } else if (stopReasonType == typeof(ThreadCreatedStopReason)) { CommandBase.WriteOutput("STOP: Thread Created"); } else if (stopReasonType == typeof(BreakpointHitStopReason)) { MDbgBreakpoint b = (stopReason as BreakpointHitStopReason).Breakpoint; if (b.Number == 0) // specal case to keep compatibility with our test scripts. { CommandBase.WriteOutput("STOP: Breakpoint Hit"); } else { CommandBase.WriteOutput(String.Format(CultureInfo.InvariantCulture, "STOP: Breakpoint {0} Hit", new Object[] { b.Number })); } } else if (stopReasonType == typeof(ExceptionThrownStopReason)) { ExceptionThrownStopReason ex = (ExceptionThrownStopReason)stopReason; CommandBase.WriteOutput("STOP: Exception thrown"); PrintCurrentException(); if (Debugger.Options.StopOnExceptionEnhanced || ex.ExceptionEnhancedOn) { // when we are in ExceptionEnhanced mode, we print more information CommandBase.WriteOutput("\tOffset: " + ex.Offset); CommandBase.WriteOutput("\tEventType: " + ex.EventType); CommandBase.WriteOutput("\tIntercept: " + (ex.Flags != 0)); } } else if (stopReasonType == typeof(UnhandledExceptionThrownStopReason)) { CommandBase.WriteOutput("STOP: Unhandled Exception thrown"); PrintCurrentException(); CommandBase.WriteOutput(""); CommandBase.WriteOutput("This is unhandled exception, continuing will end the process"); } else if (stopReasonType == typeof(ExceptionUnwindStopReason)) { CommandBase.WriteOutput("STOP: Exception unwind"); CommandBase.WriteOutput("EventType: " + (stopReason as ExceptionUnwindStopReason).EventType); } else if (stopReasonType == typeof(ModuleLoadedStopReason)) { CommandBase.WriteOutput("STOP: Module loaded: " + (stopReason as ModuleLoadedStopReason).Module.CorModule.Name); } else if (stopReasonType == typeof(AssemblyLoadedStopReason)) { CommandBase.WriteOutput("STOP: Assembly loaded: " + (stopReason as AssemblyLoadedStopReason).Assembly.Name); } else if (stopReasonType == typeof(MDANotificationStopReason)) { CorMDA mda = (stopReason as MDANotificationStopReason).CorMDA; CommandBase.WriteOutput("STOP: MDANotification"); CommandBase.WriteOutput("Name=" + mda.Name); CommandBase.WriteOutput("XML=" + mda.XML); } else if (stopReasonType == typeof(MDbgErrorStopReason)) { Exception e = (stopReason as MDbgErrorStopReason).ExceptionThrown; CommandBase.WriteOutput("STOP: MdbgError"); CommandBase.WriteOutput(FormatExceptionDiagnosticText(e)); } else { CommandBase.WriteOutput("STOP " + Debugger.Processes.Active.StopReason); } } if (!Debugger.Processes.Active.Threads.HaveActive) { return; // we won't try to show current location } MDbgThread thr = Debugger.Processes.Active.Threads.Active; MDbgSourcePosition pos = thr.CurrentSourcePosition; if (pos == null) { MDbgFrame f = thr.CurrentFrame; if (f.IsManaged) { CorDebugMappingResult mappingResult; uint ip; f.CorFrame.GetIP(out ip, out mappingResult); string s = "IP: " + ip + " @ " + f.Function.FullName + " - " + mappingResult; CommandBase.WriteOutput(s); } else { CommandBase.WriteOutput("<Located in native code.>"); } } else { string fileLoc = FileLocator.GetFileLocation(pos.Path); if (fileLoc == null) { // Using the full path makes debugging output inconsistant during automated test runs. // For testing purposes we'll get rid of them. //CommandBase.WriteOutput("located at line "+pos.Line + " in "+ pos.Path); CommandBase.WriteOutput("located at line " + pos.Line + " in " + System.IO.Path.GetFileName(pos.Path)); } else { IMDbgSourceFile file = SourceFileMgr.GetSourceFile(fileLoc); string prefixStr = pos.Line.ToString(CultureInfo.InvariantCulture) + ":"; if (pos.Line < 1 || pos.Line > file.Count) { CommandBase.WriteOutput("located at line " + pos.Line + " in " + pos.Path); throw new MDbgShellException(string.Format("Could not display current location; file {0} doesn't have line {1}.", file.Path, pos.Line)); } Debug.Assert((pos.Line > 0) && (pos.Line <= file.Count)); string lineContent = file[pos.Line]; if (pos.StartColumn == 0 && pos.EndColumn == 0 || !(CommandBase.Shell.IO is IMDbgIO2)) // or we don't have support for IMDbgIO2 { // we don't know location in the line CommandBase.Shell.IO.WriteOutput(MDbgOutputConstants.StdOutput, prefixStr + lineContent + "\n"); } else { int hiStart; if (pos.StartColumn > 0) { hiStart = pos.StartColumn - 1; } else { hiStart = 0; } int hiLen; if (pos.EndColumn == 0 || // we don't know ending position (pos.EndLine > pos.StartLine)) // multi-line statement, select whole 1st line { hiLen = lineContent.Length; } else { hiLen = pos.EndColumn - 1 - hiStart; } Debug.Assert(CommandBase.Shell.IO is IMDbgIO2); // see if condition above (CommandBase.Shell.IO as IMDbgIO2).WriteOutput(MDbgOutputConstants.StdOutput, prefixStr + lineContent + "\n", hiStart + prefixStr.Length, hiLen); } } } }
private void DisplaySource() { if (!_Shell.Debugger.Processes.HaveActive) { //CommandBase.WriteOutput("STOP: Process Exited"); return; // don't try to display current location } else { Object stopReason = _Shell.Debugger.Processes.Active.StopReason; Type stopReasonType = stopReason.GetType(); if (stopReasonType == typeof(StepCompleteStopReason)) { // just ignore those } } if (!_Shell.Debugger.Processes.Active.Threads.HaveActive) { return; // we won't try to show current location } MDbgThread thr = _Shell.Debugger.Processes.Active.Threads.Active; MDbgSourcePosition pos = thr.CurrentSourcePosition; if (pos == null) { MDbgFrame f = thr.CurrentFrame; if (f.IsManaged) { CorDebugMappingResult mappingResult; uint ip; f.CorFrame.GetIP(out ip, out mappingResult); string s = "IP: " + ip + " @ " + f.Function.FullName + " - " + mappingResult; CommandBase.WriteOutput(s); } else { CommandBase.WriteOutput("<Located in native code.>"); } } else { string fileLoc = _Shell.FileLocator.GetFileLocation(pos.Path); if (fileLoc == null) { // Using the full path makes debugging output inconsistant during automated test runs. // For testing purposes we'll get rid of them. //CommandBase.WriteOutput("located at line "+pos.Line + " in "+ pos.Path); CommandBase.WriteOutput("located at line " + pos.Line + " in " + System.IO.Path.GetFileName(pos.Path)); } else { IMDbgSourceFile file = _Shell.SourceFileMgr.GetSourceFile(fileLoc); string prefixStr = pos.Line.ToString(CultureInfo.InvariantCulture) + ":"; if (pos.Line < 1 || pos.Line > file.Count) { CommandBase.WriteOutput("located at line " + pos.Line + " in " + pos.Path); throw new MDbgShellException(string.Format("Could not display current location; file {0} doesn't have line {1}.", file.Path, pos.Line)); } string lineContent = file[pos.Line]; DisplayFile(file.Path, pos.Line); } } }
public virtual LocationState DisplayCurrentLocation() { var locationState = new LocationState(ProcessStateEnum.Stop); if (!Debugger.Processes.HaveActive) { CommandBase.WriteOutput("STOP: Process Exited"); return(new LocationState(processState: ProcessStateEnum.Stop, message: "Process Exited")); } else { Debug.Assert(Debugger.Processes.HaveActive); Object stopReason = Debugger.Processes.Active.StopReason; Type stopReasonType = stopReason.GetType(); if (stopReasonType == typeof(StepCompleteStopReason)) { // just ignore those } else if (stopReasonType == typeof(ThreadCreatedStopReason)) { CommandBase.WriteOutput("STOP: Thread Created"); return(new LocationState(processState: ProcessStateEnum.Stop, message: "Thread Created")); } else if (stopReasonType == typeof(BreakpointHitStopReason)) { MDbgBreakpoint b = (stopReason as BreakpointHitStopReason).Breakpoint; if (b.Number == 0) // specal case to keep compatibility with our test scripts. { CommandBase.WriteOutput("STOP: Breakpoint Hit"); locationState = new LocationState(processState: ProcessStateEnum.Stop, message: "Breakpoint Hit"); } else { CommandBase.WriteOutput(String.Format(CultureInfo.InvariantCulture, "STOP: Breakpoint {0} Hit", new Object[] { b.Number })); locationState = new LocationState(processState: ProcessStateEnum.Stop, message: $"Breakpoint { b.Number } Hit"); } } else if (stopReasonType == typeof(ExceptionThrownStopReason)) { ExceptionThrownStopReason ex = (ExceptionThrownStopReason)stopReason; CommandBase.WriteOutput("STOP: Exception thrown"); PrintCurrentException(); if (Debugger.Options.StopOnExceptionEnhanced || ex.ExceptionEnhancedOn) { // when we are in ExceptionEnhanced mode, we print more information CommandBase.WriteOutput("\tOffset: " + ex.Offset); CommandBase.WriteOutput("\tEventType: " + ex.EventType); CommandBase.WriteOutput("\tIntercept: " + (ex.Flags != 0)); } locationState = new LocationState(processState: ProcessStateEnum.Stop, message: $"Exception thrown"); } else if (stopReasonType == typeof(UnhandledExceptionThrownStopReason)) { CommandBase.WriteOutput("STOP: Unhandled Exception thrown"); PrintCurrentException(); CommandBase.WriteOutput(""); CommandBase.WriteOutput("This is unhandled exception, continuing will end the process"); locationState = new LocationState(processState: ProcessStateEnum.Stop, message: $"Unhandled Exception thrown"); } else if (stopReasonType == typeof(ExceptionUnwindStopReason)) { CommandBase.WriteOutput("STOP: Exception unwind"); CommandBase.WriteOutput("EventType: " + (stopReason as ExceptionUnwindStopReason).EventType); locationState = new LocationState(processState: ProcessStateEnum.Stop, message: $"Exception unwind"); } else if (stopReasonType == typeof(ModuleLoadedStopReason)) { CommandBase.WriteOutput("STOP: Module loaded: " + (stopReason as ModuleLoadedStopReason).Module.CorModule.Name); locationState = new LocationState(processState: ProcessStateEnum.Stop, message: $"Module loaded: {(stopReason as ModuleLoadedStopReason).Module.CorModule.Name}"); } else if (stopReasonType == typeof(AssemblyLoadedStopReason)) { CommandBase.WriteOutput("STOP: Assembly loaded: " + (stopReason as AssemblyLoadedStopReason).Assembly.Name); locationState = new LocationState(processState: ProcessStateEnum.Stop, message: $"Assembly loaded: {(stopReason as AssemblyLoadedStopReason).Assembly.Name}"); } else if (stopReasonType == typeof(MDANotificationStopReason)) { CorMDA mda = (stopReason as MDANotificationStopReason).CorMDA; CommandBase.WriteOutput("STOP: MDANotification"); CommandBase.WriteOutput("Name=" + mda.Name); CommandBase.WriteOutput("XML=" + mda.XML); locationState = new LocationState(processState: ProcessStateEnum.Stop, message: $"MDANotification"); } else if (stopReasonType == typeof(MDbgErrorStopReason)) { Exception e = (stopReason as MDbgErrorStopReason).ExceptionThrown; CommandBase.WriteOutput("STOP: MdbgError"); CommandBase.WriteOutput(FormatExceptionDiagnosticText(e)); locationState = new LocationState(processState: ProcessStateEnum.Stop, message: $"MdbgError"); } else { CommandBase.WriteOutput("STOP " + Debugger.Processes.Active.StopReason); locationState = new LocationState(processState: ProcessStateEnum.Stop, message: Debugger.Processes.Active.StopReason.ToString()); } } if (!Debugger.Processes.Active.Threads.HaveActive) { return(locationState); } MDbgThread thr = Debugger.Processes.Active.Threads.Active; MDbgSourcePosition pos = thr.CurrentSourcePosition; if (pos == null) { MDbgFrame f = thr.CurrentFrame; if (f.IsManaged) { CorDebugMappingResult mappingResult; uint offset; f.CorFrame.GetIP(out offset, out mappingResult); CommandBase.WriteOutput($"Offset:{offset} Function:{f.Function.FullName}"); locationState = new LocationState(processState: ProcessStateEnum.Running, message: $"Offset:{offset} Function:{f.Function.FullName}", function: f.Function.FullName); } else { CommandBase.WriteOutput("<Located in native code.>"); locationState = new LocationState(processState: ProcessStateEnum.Running, message: "<Located in native code.>"); } } else { string fileLoc = FileLocator.GetFileLocation(pos.Path); MDbgFrame f = thr.CurrentFrame; if (fileLoc == null) { // Using the full path makes debugging output inconsistant during automated test runs. // For testing purposes we'll get rid of them. //CommandBase.WriteOutput("located at line "+pos.Line + " in "+ pos.Path); Console.WriteLine($@"ln:{pos.Line} col:{pos.StartColumn}:{pos.EndColumn} in [{f.Function.FullName}] - {pos.Path}"); locationState = new LocationState(processState: ProcessStateEnum.Running, function: f.Function.FullName, lineNumber: pos.Line, file: pos.Path); } else { IMDbgSourceFile file = SourceFileMgr.GetSourceFile(fileLoc); string prefixStr = pos.Line.ToString(CultureInfo.InvariantCulture) + ":"; if (pos.Line < 1 || pos.Line > file.Count) { Console.WriteLine($@"ln:{pos.Line} col:{pos.StartColumn}:{pos.EndColumn} in [{f.Function.FullName}] - {pos.Path}"); locationState = new LocationState(processState: ProcessStateEnum.Running, function: f.Function.FullName, lineNumber: pos.Line, file: pos.Path); throw new MDbgShellException(string.Format("Could not display current location; file {0} doesn't have line {1}.", file.Path, pos.Line)); } Debug.Assert((pos.Line > 0) && (pos.Line <= file.Count)); string lineContent = file[pos.Line]; if (pos.StartColumn == 0 && pos.EndColumn == 0 || !(CommandBase.Shell.IO is IMDbgIO2)) // or we don't have support for IMDbgIO2 { // we don't know location in the line CommandBase.Shell.IO.WriteOutput(MDbgOutputConstants.StdOutput, prefixStr + lineContent + "\n"); } else { Console.WriteLine($@"ln:{pos.Line} col:{pos.StartColumn}:{pos.EndColumn} in [{f.Function.FullName}] - {pos.Path}"); Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine(lineContent); Console.ResetColor(); locationState = new LocationState(processState: ProcessStateEnum.Running, function: f.Function.FullName, lineNumber: pos.Line, file: pos.Path, code: lineContent); } } } return(locationState); }
public static void ILDasmCmd(string args) { // Provides disassembly of IL opcodes. ArgParser ap = new ArgParser(args); if (ap.Count > 1) { WriteError("Wrong # of arguments."); return; } MDbgFrame functionFrame = null; MDbgFunction function = null; if (ap.Exists(0)) { function = Debugger.Processes.Active.ResolveFunctionNameFromScope(ap.AsString(0)); if (function == null) { throw new MDbgShellException("no such function."); } } else { functionFrame = Debugger.Processes.Active.Threads.Active.CurrentFrame; function = functionFrame.Function; } CorCode ilCode = function.CorFunction.ILCode; //CorMetadataImport importer = functionFrame.Function.Module.Importer; Debug.Assert(true == ilCode.IsIL); WriteOutput("code size: " + ilCode.Size); ILVirtualDocument doc = new ILVirtualDocument(function); int currentLine; if (functionFrame != null) { // we have frame and therefore we should show current location uint ip; CorDebugMappingResult mappingResult; functionFrame.CorFrame.GetIP(out ip, out mappingResult); WriteOutput("current IL-IP: " + ip); WriteOutput("mapping: " + mappingResult.ToString()); WriteOutput("URL: " + doc.Path); currentLine = doc.Ip2LineNo((int)ip); } else { // no current IP. currentLine = -1; } for (int i = 0; i < doc.Count; i++) { if (i == currentLine) { WriteOutput("* " + doc[i]); } else { WriteOutput(" " + doc[i]); } } }