public static void InterceptCmd(string arguments) { var ap = new ArgParser(arguments); if (ap.Count > 1) { throw new MDbgShellException("Wrong number of arguments."); } if (!ap.Exists(0)) { throw new MDbgShellException("You must supply a frame number."); } int frameID = ap.AsInt(0); MDbgFrame f = Debugger.Processes.Active.Threads.Active.BottomFrame; while (--frameID >= 0) { f = f.NextUp; if (f == null) { break; } } if (f == null) { throw new MDbgShellException("Invalid frame number."); } CorThread t = Debugger.Processes.Active.Threads.Active.CorThread; t.InterceptCurrentException(f.CorFrame); WriteOutput("Interception point is set."); }
public static void ThreadCmd(string arguments) { const string nickNameStr = "nick"; var ap = new ArgParser(arguments, nickNameStr + ":1"); if (ap.Count == 0) { if (ap.OptionPassed(nickNameStr)) { g_threadNickNames.SetThreadNickName(ap.GetOption(nickNameStr).AsString, Debugger.Processes.Active.Threads.Active); } else { // we want to display active threads MDbgProcess p = Debugger.Processes.Active; WriteOutput("Active threads:"); foreach (MDbgThread t in p.Threads) { string stateDescription = GetThreadStateDescriptionString(t); WriteOutput(string.Format("th #:{0} (ID:{1}){2}", g_threadNickNames.GetThreadName(t), t.Id, stateDescription.Length == 0 ? String.Empty : " " + stateDescription)); } } } else { MDbgThread t = g_threadNickNames.GetThreadByNickName(ap.AsString(0)); if (t == null) { throw new MDbgShellException("No such thread"); } Debugger.Processes.Active.Threads.Active = t; string currentThreadStateString = GetThreadStateDescriptionString(t); if (currentThreadStateString.Length > 0) currentThreadStateString = currentThreadStateString.Insert(0, " "); WriteOutput(string.Format(CultureInfo.InvariantCulture, "Current thread is #{0}{1}.", t.Number, currentThreadStateString)); Shell.DisplayCurrentLocation(); } }
private static void ThreadResumeSuspendHelper(string arguments, CorDebugThreadState newState) { int threadNumber; var ap = new ArgParser(arguments); if (ap.Exists(0)) { if (ap.AsString(0) == "*") { // do an action on all threads foreach (MDbgThread t in Debugger.Processes.Active.Threads) { SetDebugStateWrapper(t, newState); } } else if (ap.AsString(0).StartsWith("~")) { threadNumber = Int32.Parse(ap.AsString(0).Substring(1), CultureInfo.CurrentUICulture); // it's ~number syntax -- do on all threads except this one. foreach (MDbgThread t in Debugger.Processes.Active.Threads) { if (t.Number != threadNumber) { SetDebugStateWrapper(t, newState); } } } else { MDbgThread t = g_threadNickNames.GetThreadByNickName(ap.AsString(0)); if (t == null) { throw new ArgumentException(); } SetDebugStateWrapper(t, newState); } } else { SetDebugStateWrapper(Debugger.Processes.Active.Threads.Active, newState); } }
public static void DeleteCmd(string arguments, O2Thread.FuncVoidT1<string> o2Callback) { var ap = new ArgParser(arguments); if (ap.Count != 1) { CommandBase.WriteOutput("Please choose some breakpoint to delete"); MdbgCommands.BreakCmd(""); return; } MDbgBreakpoint breakpoint = CommandBase.Debugger.Processes.Active.Breakpoints[ap.AsInt(0)]; if (breakpoint == null) { throw new MDbgShellException("Could not find breakpint #:" + ap.AsInt(0)); } else { breakpoint.Delete(); } }
public static void NewObjCmd(string arguments) { var ap = new ArgParser(arguments); string className = ap.AsString(0); MDbgFunction func = Debugger.Processes.Active.ResolveFunctionName(null, className, ".ctor", Debugger.Processes.Active.Threads.Active. CorThread.AppDomain); if (null == func) throw new MDbgShellException(String.Format(CultureInfo.InvariantCulture, "Could not resolve {0}", ap.AsString(0))); CorEval eval = Debugger.Processes.Active.Threads.Active.CorThread.CreateEval(); var callArguments = new ArrayList(); // parse the arguments to newobj int i = 1; while (ap.Exists(i)) { string arg = ap.AsString(i); // this is a normal argument MDbgValue rsMVar = Debugger.Processes.Active.ResolveVariable(arg, Debugger.Processes.Active.Threads.Active. CurrentFrame); if (rsMVar == null) { // cordbg supports also limited literals -- currently only NULL & I4. if (string.Compare(arg, "null", true) == 0) { callArguments.Add(eval.CreateValue(CorElementType.ELEMENT_TYPE_CLASS, null)); } else { int v; if (!Int32.TryParse(arg, out v)) throw new MDbgShellException(string.Format(CultureInfo.InvariantCulture, "Argument '{0}' could not be resolved to variable or number", arg)); CorGenericValue gv = eval.CreateValue(CorElementType.ELEMENT_TYPE_I4, null).CastToGenericValue(); Debug.Assert(gv != null); gv.SetValue(v); callArguments.Add(gv); } } else { callArguments.Add(rsMVar.CorValue); } ++i; } eval.NewParameterizedObject(func.CorFunction, null, (CorValue[]) callArguments.ToArray(typeof (CorValue))); Debugger.Processes.Active.Go().WaitOne(); // now display result of the funceval if (! (Debugger.Processes.Active.StopReason is EvalCompleteStopReason)) { // we could have received also EvalExceptionStopReason but it's derived from EvalCompleteStopReason WriteOutput(MDbgOutputConstants.StdOutput,"Newobj command not fully completed and debuggee has stopped"); WriteOutput(MDbgOutputConstants.StdOutput,"Result of Newobj won't be printed when finished."); } else { eval = (Debugger.Processes.Active.StopReason as EvalCompleteStopReason).Eval; Debug.Assert(eval != null); CorValue cv = eval.Result; if (cv != null) { var mv = new MDbgValue(Debugger.Processes.Active, cv); WriteOutput("result = " + mv.GetStringValue(1)); if (Debugger.Processes.Active.DebuggerVars.SetEvalResult(cv)) WriteOutput(MDbgOutputConstants.StdOutput,"results saved to $result"); } } Shell.DisplayCurrentLocation(); }
public static void FuncEvalCmd(string arguments, IMDbgShell Shell, O2Thread.FuncVoidT1<string> execOnEval) { try { var activeProcess = DI.o2MDbg.ActiveProcess; //Debugger.Processes.Active const string appDomainOption = "ad"; var ap = new ArgParser(arguments, appDomainOption + ":1"); if (!(ap.Count >= 1)) { throw new MDbgShellException("Not Enough arguments"); } // Currently debugger picks first function -- we have not implementing resolving overloaded functions. // Good example is Console.WriteLine -- there is 18 different types: // 1) [06000575] Void WriteLine() // 2) [06000576] Void WriteLine(Boolean) // 3) [06000577] Void WriteLine(Char) // 4) [06000578] Void WriteLine(Char[]) // 5) [06000579] Void WriteLine(Char[], Int32, Int32) // 6) [0600057a] Void WriteLine(Decimal) // 7) [0600057b] Void WriteLine(Double) // 8) [0600057c] Void WriteLine(Single) // 9) [0600057d] Void WriteLine(Int32) // 10) [0600057e] Void WriteLine(UInt32) // 11) [0600057f] Void WriteLine(Int64) // 12) [06000580] Void WriteLine(UInt64) // 13) [06000581] Void WriteLine(Object) // 14) [06000582] Void WriteLine(String) // 15) [06000583] Void WriteLine(String, Object) // 16) [06000584] Void WriteLine(String, Object, Object) // 17) [06000585] Void WriteLine(String, Object, Object, Object) // 18) [06000586] Void WriteLine(String, Object, Object, Object, Object, ...) // 19) [06000587] Void WriteLine(String, Object[]) // CorAppDomain appDomain; if (ap.OptionPassed(appDomainOption)) { MDbgAppDomain ad = activeProcess.AppDomains[ap.GetOption(appDomainOption).AsInt]; if (ad == null) { throw new ArgumentException("Invalid Appdomain Number"); } appDomain = ad.CorAppDomain; } else { appDomain = activeProcess.Threads.Active.CorThread.AppDomain; } MDbgFunction func = activeProcess.ResolveFunctionNameFromScope(ap.AsString(0), appDomain); if (null == func) { throw new MDbgShellException(String.Format(CultureInfo.InvariantCulture, "Could not resolve {0}", new Object[] {ap.AsString(0)})); } CorEval eval = activeProcess.Threads.Active.CorThread.CreateEval(); // Get Variables var vars = new ArrayList(); String arg; for (int i = 1; i < ap.Count; i++) { arg = ap.AsString(i); CorValue v = Shell.ExpressionParser.ParseExpression2(arg, activeProcess, activeProcess.Threads.Active. CurrentFrame); if (v == null) { throw new MDbgShellException("Cannot resolve expression or variable " + ap.AsString(i)); } if (v is CorGenericValue) { vars.Add(v); } else { CorHeapValue hv = v.CastToHeapValue(); if (hv != null) { // we cannot pass directly heap values, we need to pass reference to heap valus CorReferenceValue myref = eval.CreateValue(CorElementType.ELEMENT_TYPE_CLASS, null).CastToReferenceValue(); myref.Value = hv.Address; vars.Add(myref); } else { vars.Add(v); } } } eval.CallFunction(func.CorFunction, (CorValue[]) vars.ToArray(typeof (CorValue))); activeProcess.Go().WaitOne(); // now display result of the funceval if (!(activeProcess.StopReason is EvalCompleteStopReason)) { // we could have received also EvalExceptionStopReason but it's derived from EvalCompleteStopReason Shell.IO.WriteOutput(MDbgOutputConstants.StdOutput, "Func-eval not fully completed and debuggee has stopped"); Shell.IO.WriteOutput(MDbgOutputConstants.StdOutput, "Result of funceval won't be printed when finished."); } else { eval = (activeProcess.StopReason as EvalCompleteStopReason).Eval; Debug.Assert(eval != null); CorValue cv = eval.Result; if (cv != null) { var mv = new MDbgValue(activeProcess, cv); if (execOnEval != null) // if this callback is set then execute { execOnEval(mv.GetStringValue(1)); return; } Shell.IO.WriteOutput(MDbgOutputConstants.StdOutput, "result = " + mv.GetStringValue(1)); if (cv.CastToReferenceValue() != null) if (activeProcess.DebuggerVars.SetEvalResult(cv)) Shell.IO.WriteOutput(MDbgOutputConstants.StdOutput, "results saved to $result"); } } } catch (Exception ex) { DI.log.ex(ex, "in FuncEvalCmd"); } if (execOnEval != null) // need to call this here so that the sync AutoResetEvent is set execOnEval(null); }
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"); } } } } }
public static void ActiveProcess(string arguments) { var ap = new ArgParser(arguments); if (ap.Count > 1) { throw new MDbgShellException("Wrong # of arguments."); } if (ap.Exists(0)) { int logicalPID = ap.AsInt(0); bool found = false; foreach (MDbgProcess ps in Debugger.Processes) if (ps.Number == logicalPID) { Debugger.Processes.Active = ps; found = true; break; } if (found) { Shell.DisplayCurrentLocation(); } else { throw new MDbgShellException("Invalid process number"); } } else { MDbgProcess ActiveProcess = Debugger.Processes.HaveActive ? Debugger.Processes.Active : null; WriteOutput("Active Process:"); bool haveProcesses = false; CorPublish corPublish = null; foreach (MDbgProcess p in Debugger.Processes) { haveProcesses = true; string processName = p.Name; string launchMode; if (processName == null) { // in case we're attached (as opposed to launching), // we don't know process name. // Let's find it through CorPublishApi try { if (corPublish == null) { corPublish = new CorPublish(); } processName = corPublish.GetProcess(p.CorProcess.Id).DisplayName; } catch { processName = "N/A"; } launchMode = "attached"; } else { launchMode = "launched"; } WriteOutput((ActiveProcess == p ? "*" : " ") + string.Format(CultureInfo.InvariantCulture, "{0}. [PID: {1}, {2}] {3}", p.Number, p.CorProcess.Id, launchMode, processName)); } if (!haveProcesses) { WriteOutput("No Active Process!"); } } }
public static void WhenCmd(string arguments) { var ap = new ArgParser(arguments); if (ap.Count == 0) { // we want to list all actions foreach (ExecuteCmdAction a in m_events) { WriteOutput(a.Id + ".\t" + a); } } else if (ap.AsString(0) == "delete") { if (ap.AsString(1) == "all") { // delete all actions m_events.Clear(); } else { int idx = 1; while (true) { int actionToRemove = ap.AsInt(idx); foreach (ExecuteCmdAction a in m_events) { if (a.Id == actionToRemove) { m_events.Remove(a); break; // once we remove an item, we cannot iterate further, // this doesn't matter because id's are unique. } } idx++; if (!ap.Exists(idx)) { break; } } } } else { //we want to create an when action ExecuteCmdAction action = null; string cmdString; int argCount; GetDoPart(ap, out cmdString, out argCount); switch (ap.AsString(0)) { case "StepComplete": action = new ExecuteCmdAction(Shell, cmdString, typeof (StepCompleteStopReason)); switch (argCount) { case 0: break; default: throw new ArgumentException(); } break; case "ProcessExited": action = new ExecuteCmdAction(Shell, cmdString, typeof (ProcessExitedStopReason)); switch (argCount) { case 0: break; default: throw new ArgumentException(); } break; case "ThreadCreated": action = new ExecuteCmdAction(Shell, cmdString, typeof (ThreadCreatedStopReason)); switch (argCount) { case 0: break; case 1: action.Number = ap.AsInt(1); break; default: throw new ArgumentException(); } break; case "BreakpointHit": action = new ExecuteCmdAction(Shell, cmdString, typeof (BreakpointHitStopReason)); switch (argCount) { case 0: break; case 1: action.Number = ap.AsInt(1); break; default: throw new ArgumentException(); } break; case "ModuleLoaded": action = new ExecuteCmdAction(Shell, cmdString, typeof (BreakpointHitStopReason)); switch (argCount) { case 0: break; case 1: action.Name = ap.AsString(1); break; default: throw new ArgumentException(); } break; case "ClassLoaded": action = new ExecuteCmdAction(Shell, cmdString, typeof (ClassLoadedStopReason)); switch (argCount) { case 0: break; case 1: action.Name = ap.AsString(1); break; default: throw new ArgumentException(); } break; case "AssemblyLoaded": action = new ExecuteCmdAction(Shell, cmdString, typeof (AssemblyLoadedStopReason)); switch (argCount) { case 0: break; case 1: action.Name = ap.AsString(1); break; default: throw new ArgumentException(); } break; case "AssemblyUnloaded": throw new NotImplementedException(); case "ControlCTrapped": action = new ExecuteCmdAction(Shell, cmdString, typeof (ControlCTrappedStopReason)); switch (argCount) { case 0: break; default: throw new ArgumentException(); } break; case "ExceptionThrown": action = new ExecuteCmdAction(Shell, cmdString, typeof (ExceptionThrownStopReason)); switch (argCount) { case 0: break; case 1: action.Name = ap.AsString(1); break; default: throw new ArgumentException(); } break; case "UnhandledExceptionThrown": action = new ExecuteCmdAction(Shell, cmdString, typeof (UnhandledExceptionThrownStopReason)); switch (argCount) { case 0: break; case 1: action.Name = ap.AsString(1); break; default: throw new ArgumentException(); } break; case "AsyncStop": action = new ExecuteCmdAction(Shell, cmdString, typeof (AsyncStopStopReason)); switch (argCount) { case 0: break; default: throw new ArgumentException(); } break; case "AttachComplete": if (argCount != 0) { throw new ArgumentException(); } action = new ExecuteCmdAction(Shell, cmdString, typeof (AttachCompleteStopReason)); break; case "UserBreak": if (argCount != 0) { throw new ArgumentException(); } action = new ExecuteCmdAction(Shell, cmdString, typeof (UserBreakStopReason)); break; case "EvalComplete": if (argCount != 0) { throw new ArgumentException(); } action = new ExecuteCmdAction(Shell, cmdString, typeof (EvalCompleteStopReason)); break; case "EvalException": if (argCount != 0) { throw new ArgumentException(); } action = new ExecuteCmdAction(Shell, cmdString, typeof (EvalExceptionStopReason)); break; case "RemapOpportunityReached": if (argCount != 0) { throw new ArgumentException(); } action = new ExecuteCmdAction(Shell, cmdString, typeof (RemapOpportunityReachedStopReason)); break; default: throw new ArgumentException("invalid event name"); } m_events.Add(action); } }
public static void PathCmd(string arguments) { var ap = new ArgParser(arguments); if (!ap.Exists(0)) { WriteOutput("path: " + Shell.FileLocator.Path); } else { Shell.FileLocator.Path = arguments; WriteOutput("Path set to: " + Shell.FileLocator.Path); if (Debugger.Processes.HaveActive) { ShowCmd(""); } } }
public static void XCmd(string arguments) { if (arguments.Length == 0) { WriteOutput("Please specify module."); ListCmd("mo"); } else { const int default_count = 100; // default number of frames to print const string countOpt = "c"; var ap = new ArgParser(arguments, countOpt + ":1"); int count = default_count; if (ap.OptionPassed(countOpt)) { ArgToken countArg = ap.GetOption(countOpt); if (countArg.AsString == "all") { count = 0; // 0 means print all symbols } else { count = countArg.AsInt; if (count <= 0) { throw new MDbgShellException("Count must be positive number or string \"all\""); } } } string moduleName, substrPart; string expr = ap.AsString(0); int i = expr.IndexOf('!'); if (i == -1) { moduleName = expr; substrPart = null; } else { moduleName = expr.Substring(0, i); substrPart = expr.Substring(i + 1); } SymbolCache.Clear(); // enum functions from the module MDbgModule m = Debugger.Processes.Active.Modules.Lookup(moduleName); if (m == null) { throw new MDbgShellException("module not found!"); } bool shouldPrint = substrPart == null; Regex r = null; if (substrPart != null) { r = new Regex(ConvertSimpleExpToRegExp(substrPart)); } foreach (Type t in m.Importer.DefinedTypes) { foreach (MethodInfo mi in t.GetMethods()) { var sb = new StringBuilder(); sb.Append(t.Name).Append(".").Append(mi.Name).Append("("); bool needComma = false; foreach (ParameterInfo pi in mi.GetParameters()) { if (needComma) { sb.Append(","); } sb.Append(pi.Name); needComma = true; } sb.Append(")"); string fullFunctionName = sb.ToString(); if (r != null) { shouldPrint = r.IsMatch(fullFunctionName); } if (shouldPrint) { int idx = SymbolCache.Add(new MdbgSymbol(m.Number, t.Name, mi.Name, 0)); WriteOutput("~" + idx + ". " + fullFunctionName); if (count != 0 && idx >= count) { WriteOutput(string.Format(CultureInfo.CurrentUICulture, "displayed only first {0} hits. For more symbols use -c switch", count)); return; } } } } } }
public static void DownCmd(string arguments) { string frameNum = "f"; var ap = new ArgParser(arguments, frameNum); if (ap.OptionPassed(frameNum)) { SwitchToFrame(ap.AsInt(0)); } else { int count = 1; if (ap.Exists(0)) { count = ap.AsInt(0); } while (--count >= 0) { Debugger.Processes.Active.Threads.Active.MoveCurrentFrame(true); } } if (Debugger.Processes.Active.Threads.Active.CurrentFrame.IsManaged) { WriteOutput("Current Frame:" + Debugger.Processes.Active.Threads.Active.CurrentFrame.Function.FullName ); } Shell.DisplayCurrentLocation(); }
/* * We want to have following commnads: * * symbol path "value" -- sets symbol paths * symbol addpath "value" -- adds symbol path * symbol reload [module] -- reloads symbol for a module * symbol list [module] -- shows currently loaded symbols */ public static void SymbolCmd(string arguments) { var ap = new ArgParser(arguments); if (!ap.Exists(0)) { ExecuteCommand("help symbol"); return; } switch (ap.AsCommand(0, new CommandArgument("path", "addpath", "reload", "list"))) { case "path": if (!ap.Exists(1)) { // we want to print current path string p = Debugger.Options.SymbolPath; WriteOutput("Current symbol path: " + p); } else { // we are setting path Debugger.Options.SymbolPath = ap.AsString(1); WriteOutput("Current symbol path: " + Debugger.Options.SymbolPath); } break; case "addpath": Debugger.Options.SymbolPath = Debugger.Options.SymbolPath + Path.PathSeparator + ap.AsString(1); WriteOutput("Current symbol path: " + Debugger.Options.SymbolPath); break; case "reload": { IEnumerable modules; if (ap.Exists(1)) { // we want to reload only one module MDbgModule m = Debugger.Processes.Active.Modules.Lookup(ap.AsString(1)); if (m == null) { throw new MDbgShellException("No such module."); } modules = new[] {m}; } else { modules = Debugger.Processes.Active.Modules; } foreach (MDbgModule m in modules) { WriteOutput("Reloading symbols for module " + m.CorModule.Name); m.ReloadSymbols(true); WriteModuleStatus(m, true); } } break; case "list": { IEnumerable modules; if (ap.Exists(1)) { // we want to list only one module MDbgModule m = Debugger.Processes.Active.Modules.Lookup(ap.AsString(1)); if (m == null) { throw new MDbgShellException("No such module."); } modules = new[] {m}; } else { modules = Debugger.Processes.Active.Modules; } foreach (MDbgModule m in modules) { WriteModuleStatus(m, false); } } break; default: Debug.Assert(false); break; } }
public static void ListCmd(string arguments) { const string verboseOpt = "v"; bool bVerbose; var ap = new ArgParser(arguments, verboseOpt); string listWhat = ap.AsCommand(0, new CommandArgument("modules", "appdomains", "assemblies")); switch (listWhat) { case "modules": bVerbose = ap.OptionPassed(verboseOpt); if (ap.Exists(1)) { // user specified module to display info for MDbgModule m = Debugger.Processes.Active.Modules.Lookup(ap.AsString(1)); if (m == null) { throw new MDbgShellException("No such module."); } ListModuleInternal(m, true); } else { // we list all modules WriteOutput("Loaded Modules:"); foreach (MDbgModule m in Debugger.Processes.Active.Modules) { ListModuleInternal(m, bVerbose); } } break; case "appdomains": WriteOutput("Current appDomains:"); foreach (MDbgAppDomain ad in Debugger.Processes.Active.AppDomains) { WriteOutput(ad.Number + ". - " + ad.CorAppDomain.Name); } break; case "assemblies": WriteOutput("Current assemblies:"); foreach (MDbgAppDomain ad in Debugger.Processes.Active.AppDomains) { foreach (CorAssembly assem in ad.CorAppDomain.Assemblies) { WriteOutput("\t" + assem.Name); } } break; default: Debug.Assert(false); break; } }
public static void ModeCmd(string arguments) { // get mode settings first var modeSettings = Shell.Properties[MDbgModeSettings.PropertyName] as MDbgModeSettings; Debug.Assert(modeSettings != null); if (modeSettings == null) throw new MDbgShellException("corrupted internal state."); var ap = new ArgParser(arguments); if (!ap.Exists(0)) { WriteOutput("Debugging modes:"); foreach (MDbgModeItem item in modeSettings.Items) { WriteOutput(string.Format(CultureInfo.InvariantCulture, "({0}) {1}: {2}", item.ShortCut, item.Description.PadRight(50), item.OnOff ? "On" : "Off")); } } else { bool on = ap.AsCommand(1, new CommandArgument("on", "off")) == "on"; string shortcut = ap.AsString(0); // now find the correct modeItem MDbgModeItem item = null; foreach (MDbgModeItem i in modeSettings.Items) if (i.ShortCut == shortcut) { item = i; break; } if (item == null) throw new MDbgShellException("Invalid mode option. Modes are in (here)."); item.OnOff = on; } }
private static void GetDoPart(ArgParser ap, out string cmdString, out int argCount) { const int startPart = 1; Debug.Assert(ap != null); // all commands start with "when XXX [arguments...] do cmds int i; for (i = startPart; i < ap.Count; i++) { if (ap.AsString(i) == "do") { break; } } if (i == ap.Count) { throw new ArgumentException("Invalid command syntax"); } var sb = new StringBuilder(); int j = i + 1; sb.Append(ap.AsString(j)); for (j++; j < ap.Count; j++) { sb.Append("\n").Append(ap.AsString(j)); } cmdString = sb.ToString(); argCount = i - startPart; }
public static void LoadCmd(string arguments) { var ap = new ArgParser(arguments); string extName = ap.AsString(0); Assembly asext = FindExtensionAssembly(extName); if (asext == null) { throw new MDbgShellException("Extension not found"); } ExecuteExtension(asext); }
public static void UnwrapGCHandleCmd(string arguments) { var ap = new ArgParser(arguments); if (ap.Count != 1) { WriteError( "Wrong arguments, should be name or address of a \"System.Runtime.InteropServices.GCHandle\" object."); return; } long handleAdd = 0; // First try to resolve the argument as a variable in the current frame MDbgValue var = Debugger.Processes.Active.ResolveVariable( ap.AsString(0), Debugger.Processes.Active.Threads.Active.CurrentFrame); if (var != null) { if (var.TypeName != "System.Runtime.InteropServices.GCHandle") { WriteError("Variable is not of type \"System.Runtime.InteropServices.GCHandle\"."); return; } foreach (MDbgValue field in var.GetFields()) { if (field.Name == "m_handle") { handleAdd = Int64.Parse(field.GetStringValue(0)); break; } } } else { // Trying to resolve as a raw address now try { handleAdd = ap.GetArgument(0).AsAddress; } catch (FormatException) { WriteError("Couldn't recognize the argument as a variable name or address"); return; } } var add = new IntPtr(handleAdd); CorReferenceValue result; try { result = Debugger.Processes.Active.CorProcess.GetReferenceValueFromGCHandle(add); } catch (COMException e) { if (e.ErrorCode == (int) HResult.CORDBG_E_BAD_REFERENCE_VALUE) { WriteError("Invalid handle address."); return; } else { throw; } } CorValue v = result.Dereference(); var mv = new MDbgValue(Debugger.Processes.Active, v); if (mv.IsComplexType) { WriteOutput(string.Format("GCHandle to <{0}>", InternalUtil.PrintCorType(Debugger.Processes.Active, v.ExactType))); // now print fields as well foreach (MDbgValue f in mv.GetFields()) WriteOutput(" " + f.Name + "=" + f.GetStringValue(0)); } else { WriteOutput(string.Format("GCHandle to {0}", mv.GetStringValue(0))); } }
// O2.Debugger.Mdbg.OriginalMdbgCode.mdbg.mdbgCommandsCustomizedForO2 // , O2Thread.FuncVoid<string> o2Callback) public static bool AttachCmd(string arguments, O2Thread.FuncVoidT1<string> o2Callback) { try { var ap = new ArgParser(arguments); if (ap.Count > 1) { DI.log.error("in AttachCmd: Wrong # of arguments."); return false; } if (!ap.Exists(0)) { DI.log.error("in AttachCmd: Please choose some process to attach"); MdbgCommands.ProcessEnumCmd(""); return false; } int pid = ap.AsInt(0); if (Process.GetCurrentProcess().Id == pid) { DI.log.error("in AttachCmd: Cannot attach to myself!"); return false; } MDbgProcess p = CommandBase.Debugger.Attach(pid); p.Go().WaitOne(); return true; } catch (Exception ex) { DI.log.ex(ex, "in AttachCmd"); return false; } }
public static void ConfigCmd(string arguments) { const string extPathCmd = "extpath"; const string extPathAddCmd = "extpath+"; var ap = new ArgParser(arguments); if (!ap.Exists(0)) { WriteOutput("Current configuration:"); WriteOutput(string.Format("\tExtensionPath={0}", ExtensionPath)); return; } switch (ap.AsCommand(0, new CommandArgument(extPathCmd, extPathAddCmd))) { case extPathCmd: ExtensionPath = ap.AsString(1); PrintExt: WriteOutput(string.Format("ExtensionPath={0}", ExtensionPath)); break; case extPathAddCmd: ExtensionPath = ExtensionPath + Path.PathSeparator + ap.AsString(1); goto PrintExt; default: Debug.Assert(false); break; } }
public static void WhereCmd(string arguments, O2Thread.FuncVoidT1<string> o2Callback) { const int default_depth = 100; // default number of frames to print const string countOpt = "c"; const string verboseOpt = "v"; var ap = new ArgParser(arguments, countOpt + ":1;" + verboseOpt); int depth = default_depth; if (ap.OptionPassed(countOpt)) { ArgToken countArg = ap.GetOption(countOpt); if (countArg.AsString == "all") { depth = 0; // 0 means print entire stack0 } else { depth = countArg.AsInt; if (depth <= 0) { throw new MDbgShellException("Depth must be positive number or string \"all\""); } } } if (ap.Count != 0 && ap.Count != 1) { throw new MDbgShellException("Wrong # of arguments."); } if (ap.Count == 0) { // print current thread only InternalWhereCommand(CommandBase.Debugger.Processes.Active.Threads.Active, depth, ap.OptionPassed(verboseOpt)); } else if (ap.AsString(0).Equals("all")) { foreach (MDbgThread t in CommandBase.Debugger.Processes.Active.Threads) InternalWhereCommand(t, depth, ap.OptionPassed(verboseOpt)); } else { MDbgThread t = CommandBase.Debugger.Processes.Active.Threads[ap.AsInt(0)]; if (t == null) { throw new MDbgShellException("Wrong thread number"); } else { InternalWhereCommand(t, depth, ap.OptionPassed(verboseOpt)); } } }
public static void SetIPCmd(string arguments) { const string IlOpt = "il"; var ap = new ArgParser(arguments, IlOpt); if (ap.OptionPassed(IlOpt)) { Debugger.Processes.Active.Threads.Active.CurrentFrame.CorFrame.SetIP(ap.AsInt(0)); } else { int ilOffset; if ( !Debugger.Processes.Active.Threads.Active.CurrentFrame.Function.GetIPFromLine(ap.AsInt(0), out ilOffset)) { throw new MDbgShellException("cannot find correct function mapping"); } int hresult; if (!Debugger.Processes.Active.Threads.Active.CurrentFrame.CorFrame.CanSetIP(ilOffset, out hresult)) { string reason; switch ((HResult) hresult) { case HResult.CORDBG_S_BAD_START_SEQUENCE_POINT: reason = "Attempt to SetIP from non-sequence point."; break; case HResult.CORDBG_S_BAD_END_SEQUENCE_POINT: reason = "Attempt to SetIP from non-sequence point."; break; case HResult.CORDBG_S_INSUFFICIENT_INFO_FOR_SET_IP: reason = "Insufficient information to fix program flow."; break; case HResult.CORDBG_E_CANT_SET_IP_INTO_FINALLY: reason = "Attempt to SetIP into finally block."; break; case HResult.CORDBG_E_CANT_SET_IP_OUT_OF_FINALLY: case HResult.CORDBG_E_CANT_SET_IP_OUT_OF_FINALLY_ON_WIN64: reason = "Attempt to SetIP out of finally block."; break; case HResult.CORDBG_E_CANT_SET_IP_INTO_CATCH: reason = "Attempt to SetIP into catch block."; break; case HResult.CORDBG_E_CANT_SET_IP_OUT_OF_CATCH_ON_WIN64: reason = "Attempt to SetIP out of catch block."; break; case HResult.CORDBG_E_SET_IP_NOT_ALLOWED_ON_NONLEAF_FRAME: reason = "Attempt to SetIP on non-leaf frame."; break; case HResult.CORDBG_E_SET_IP_IMPOSSIBLE: reason = "The operation cannot be completed."; break; case HResult.CORDBG_E_CANT_SETIP_INTO_OR_OUT_OF_FILTER: reason = "Attempt to SetIP into or out of filter."; break; case HResult.CORDBG_E_SET_IP_NOT_ALLOWED_ON_EXCEPTION: reason = "SetIP is not allowed on exception."; break; default: reason = "Reason unknown."; break; } throw new MDbgShellException("Cannot set IP as requested. " + reason); } Debugger.Processes.Active.Threads.Active.CurrentFrame.CorFrame.SetIP(ilOffset); } Debugger.Processes.Active.Threads.RefreshStack(); Shell.DisplayCurrentLocation(); }
public static void ShowCmd(string arguments, O2Thread.FuncVoidT1<string> o2Callback) { MDbgSourcePosition pos = CommandBase.Debugger.Processes.Active.Threads.Active.CurrentSourcePosition; if (pos == null) { throw new MDbgShellException("No source location"); } string fileLoc = CommandBase.Shell.FileLocator.GetFileLocation(pos.Path); if (fileLoc == null) { throw new MDbgShellException(String.Format(CultureInfo.InvariantCulture, "Source file '{0}' not available.", pos.Path)); } IMDbgSourceFile file = CommandBase.Shell.SourceFileMgr.GetSourceFile(fileLoc); var ap = new ArgParser(arguments); if (ap.Count > 1) { throw new MDbgShellException("Wrong # of arguments."); } int around; if (ap.Exists(0)) { around = ap.AsInt(0); } else { around = 3; } int lo, hi; lo = pos.Line - around; if (lo < 1) { lo = 1; } hi = pos.Line + around; if (hi > file.Count) { hi = file.Count; } for (int i = lo; i < hi; i++) { CommandBase.WriteOutput(String.Format(CultureInfo.InvariantCulture, "{0}{1}{2}", i, i == pos.Line ? ":*" : " ", file[i])); } }
public static void QuitCmd(string arguments) { // Look for optional exit code. var ap = new ArgParser(arguments); int exitCode; if (ap.Exists(0)) { exitCode = ap.AsInt(0); } else { exitCode = 0; } // we cannot modify the collection during enumeration, so // we need to collect all processes to kill in advance. var processesToKill = new ArrayList(); foreach (MDbgProcess p in Debugger.Processes) { processesToKill.Add(p); } foreach (MDbgProcess p in processesToKill) { if (p.IsAlive) { Debugger.Processes.Active = p; WriteOutput("Terminating current process..."); try { p.Kill().WaitOne(); } catch { // some processes cannot be killed (e.g. the one that have not loaded runtime) try { Process np = Process.GetProcessById(p.CorProcess.Id); np.Kill(); } catch { } } } } Shell.QuitWithExitCode(exitCode); }