/// <summary> /// Prints the current exception settings. /// </summary> public override void Print() { CommandBase.WriteOutput("(ex) <Exception Type> Exception:"); if (m_items.Count == 0) { // behavior for specific exception types has not been specified - just print default behavior switch (m_default) { case DebuggerBehavior.Stop: CommandBase.WriteOutput(" Stop on all exceptions"); break; default: CommandBase.WriteOutput(" " + Enum.GetName(typeof(DebuggerBehavior), m_default) + " all exceptions"); break; } } else { // print default behavior and all other settings specified, in order of increasing precedence CommandBase.WriteOutput("Default: " + Enum.GetName(typeof(DebuggerBehavior), m_default)); foreach (ExceptionStopOptionPolicyItem item in m_items) { CommandBase.WriteOutput(item.ExceptionType + ": " + Enum.GetName(typeof(DebuggerBehavior), item.Behavior)); } } }
////////////////////////////////////////////////////////////////////////////////// // // Private implementation // ////////////////////////////////////////////////////////////////////////////////// /* // NOT USED by O2MDbg * private int RunInputLoop() * { * // Run the event loop * string input; * IMDbgCommand cmd = null; * string cmdArgs = null; * * int stopCount = -1; * * while (true) * { * Thread.Sleep(1000); * Debug.WriteLine("MSdn Shell, waiting for commands"); * } * * while (m_run && IO.ReadCommand(out input)) * { * try * { * if (Debugger.Processes.HaveActive) * { * stopCount = Debugger.Processes.Active.StopCounter; * } * * if (input.Length == 0) * { * if (cmd == null || !cmd.IsRepeatable) * { * continue; * } * } * else * { * Commands.ParseCommand(input, out cmd, out cmdArgs); * } * cmd.Execute(cmdArgs); * * int newStopCount = Debugger.Processes.HaveActive * ? Debugger.Processes.Active.StopCounter * : Int32.MaxValue; * bool movementCommand = newStopCount > stopCount; * stopCount = newStopCount; * * if (OnCommandExecuted != null) * { * OnCommandExecuted(this, new CommandExecutedEventArgs(this, cmd, cmdArgs, movementCommand)); * } * * newStopCount = Debugger.Processes.HaveActive * ? Debugger.Processes.Active.StopCounter * : Int32.MaxValue; * movementCommand = newStopCount > stopCount; * * while (newStopCount > stopCount) * { * stopCount = newStopCount; * * if (OnCommandExecuted != null) * { * OnCommandExecuted(this, new CommandExecutedEventArgs(this, null, null, movementCommand)); * } * * newStopCount = Debugger.Processes.HaveActive * ? Debugger.Processes.Active.StopCounter * : Int32.MaxValue; * movementCommand = newStopCount > stopCount; * } * stopCount = newStopCount; * } * catch (Exception e) * { * ReportException(e); * } * } // end while * return m_exitCode; * } */ private void PrintCurrentException() { MDbgValue ex = Debugger.Processes.Active.Threads.Active.CurrentException; CommandBase.WriteOutput("Exception=" + ex.GetStringValue(0)); foreach (MDbgValue f in ex.GetFields()) { string outputType; string outputValue; if (f.Name == "_xptrs" || f.Name == "_xcode" || f.Name == "_stackTrace" || f.Name == "_remoteStackTraceString" || f.Name == "_remoteStackIndex" || f.Name == "_exceptionMethodString") { outputType = MDbgOutputConstants.Ignore; } else { outputType = MDbgOutputConstants.StdOutput; } outputValue = f.GetStringValue(0); // remove new line characters in string if (outputValue != null && (f.Name == "_exceptionMethodString" || f.Name == "_remoteStackTraceString")) { outputValue = outputValue.Replace('\n', '#'); } CommandBase.WriteOutput(outputType, "\t" + f.Name + "=" + outputValue); } }
/// <summary> /// Acts on the debugger callback, based on the stop option policy settings and the /// type of exception thrown. /// </summary> /// <param name="currentProcess">Current MDbgProcess.</param> /// <param name="args">Callback arguments.</param> public override void ActOnCallback(MDbgProcess currentProcess, CustomPostCallbackEventArgs args) { var ea = args.CallbackArgs as CorException2EventArgs; var ua = args.CallbackArgs as CorExceptionUnwind2EventArgs; bool bException2 = (ea != null); if (m_exceptionEnhancedOn || (bException2 && (ea.EventType == CorDebugExceptionCallbackType.DEBUG_EXCEPTION_FIRST_CHANCE))) { MDbgThread currentThread = null; currentThread = currentProcess.Threads.GetThreadFromThreadId((args.CallbackArgs as CorThreadEventArgs).Thread.Id); string exceptionType = currentThread.CurrentException.TypeName; switch (DetermineBehavior(exceptionType)) { case DebuggerBehavior.Stop: if (bException2) { args.Controller.Stop(ea.Thread, new ExceptionThrownStopReason(ea.AppDomain, ea.Thread, ea.Frame, ea.Offset, ea.EventType, ea.Flags, m_exceptionEnhancedOn)); } else { args.Controller.Stop(ua.Thread, new ExceptionUnwindStopReason(ua.AppDomain, ua.Thread, ua.EventType, ua.Flags)); } break; case DebuggerBehavior.Log: CommandBase.WriteOutput("Exception thrown: " + currentThread.CurrentException.TypeName + " at function " + currentThread.CurrentFrame.Function.FullName + " in source file " + currentThread.CurrentSourcePosition.Path + ":" + currentThread.CurrentSourcePosition.Line); if (m_exceptionEnhancedOn) { if (bException2) { CommandBase.WriteOutput("Event type: " + ea.EventType); } else { CommandBase.WriteOutput("Event type: " + ua.EventType); } } CommandBase.WriteOutput(""); break; } } }
/// <summary> /// Prints the stop option policy. /// </summary> public override void Print() { string output = "(" + Acronym + ") " + m_fullName + ": "; int length = output.Length; var sb = new StringBuilder(output); for (int i = 0; i < 25 - length; i++) { //to ensure proper spacing sb.Append(" "); } CommandBase.WriteOutput(sb + Enum.GetName(typeof(DebuggerBehavior), m_behavior)); }
/// <summary> /// Acts on the current callback, based on the current debugger behavior for this stop /// option policy. /// </summary> /// <param name="currentProcess">Current MDbgProcess.</param> /// <param name="args">Callback arguments.</param> public override void ActOnCallback(MDbgProcess currentProcess, CustomPostCallbackEventArgs args) { var eventArgs = args.CallbackArgs as CorEventArgs; switch (m_behavior) { case DebuggerBehavior.Stop: args.Controller.Stop(eventArgs.Thread, MDbgUtil.CreateStopReasonFromEventArgs(eventArgs, currentProcess)); break; case DebuggerBehavior.Log: CommandBase.WriteOutput(eventArgs + "\n"); break; } }
public virtual void DisplayCurrentLocation() { if (!Debugger.Processes.HaveActive) { CommandBase.WriteOutput("STOP: Process Exited"); return; // don't try to display current location } else { if (false == Debugger.Processes.HaveActive) { return; } //Debug.Assert(Debugger.Processes.HaveActive); Object stopReason = Debugger.Processes.Active.StopReason; if (stopReason == null) { return; } 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)) { var 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)) { CommandBase.WriteOutput("STOP: MdbgErorr: " + (stopReason as MDbgErrorStopReason).ExceptionThrown.Message); #if DEBUG CommandBase.WriteOutput((stopReason as MDbgErrorStopReason).ExceptionThrown.ToString()); #endif } 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; //DC DI.o2MDbg.currentLocation = new O2MDbgCurrentLocation(thr); 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 " + 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); } } } }
/// <summary> /// Prints whether the ExceptionEnhanced switch of the associated ExceptionStopOptionPolicy object /// is turned on or off. /// </summary> public override void Print() { CommandBase.WriteOutput("(ee) ExceptionEnhanced: " + m_esop.ExceptionEnhancedOn); }