public static void AttachCmd(string arguments) { ArgParser ap = new ArgParser(arguments); if (ap.Count > 1) { throw new MDbgShellException("Wrong # of arguments."); } if (!ap.Exists(0)) { throw new MDbgShellException("Wrong # of arguments."); } int pid = ap.AsInt(0); if (Process.GetCurrentProcess().Id == pid) { throw new MDbgShellException("Cannot attach to myself!"); } // time to attach, since the user isn't able to specify the DebugModeFlag for attach, use Debug which is the // default if (false == DebugActiveSilverlightProcess(pid, DebugModeFlag.Debug)) { throw new MDbgShellException("Could not find a match for *"); } }
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]); }
public static void Gui(string args) { // just do the check that gui is not already loaded, // strange things are happening else: ArgParser ap = new ArgParser(args); if( ap.Exists(0) ) { if( ap.AsString(0) == "close" ) { if( m_mainForm!=null ) { m_mainForm.CloseGui(); Application.Exit(); // this line will cause the message pump on other thread to quit. return; } else throw new MDbgShellException("GUI not started."); } else throw new MDbgShellException("invalid argument"); } if(Shell.IO == m_mainForm) { WriteOutput("GUI already started. Cannot start second instance."); return; } WriteOutput("starting gui"); m_mainForm = new MainForm(Shell); Thread t = new Thread(new ThreadStart(RunMessageLoop)); // Only MTA Threads can access CorDebug interfaces because mscordbi doesn't provide marshalling to make them accessable from STA Threads t.SetApartmentState(ApartmentState.MTA); t.IsBackground = true; t.Start(); m_mainForm.InitComplete.WaitOne(); // wait till form is fully displayed. WriteOutput("GUI: Simple Extension for Managed debugger (Mdbg) started"); WriteOutput("\nfor information on how to use the extension select in menu bar help->Info\n"); }
public static void Con(string args) { ArgParser ap = new ArgParser(args); if (ap.Exists(0)) { if (ap.AsString(0) == "close") { if (_console != null) { _console.Stop(); return; } else throw new MDbgShellException("Console not started."); } else throw new MDbgShellException("invalid argument"); } _console = new Screen(Shell); _console.Start(); }
public static void ActiveProcess(string arguments) { ArgParser 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 PathCmd(string arguments) { ArgParser ap = new ArgParser(arguments); if (!ap.Exists(0)) { WriteOutput("path: " + Shell.FileLocator.Path); } else { Shell.FileLocator.Path = Environment.ExpandEnvironmentVariables(arguments); WriteOutput("Path set to: " + arguments); if (Debugger.Processes.HaveActive) { ShowCmd(""); } } }
public static void DownCmd(string arguments) { string frameNum = "f"; ArgParser 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(); }
public static void AttachCmd(string arguments) { const string versionArg = "ver"; const string continuationEventArg = "attachEvent"; const string pidArg = "pid"; ArgParser ap = new ArgParser(arguments, versionArg + ":1;" + continuationEventArg + ":1;" + pidArg + ":1"); if (ap.Count > 1) { throw new MDbgShellException("Wrong # of arguments."); } if (!ap.Exists(0) && !ap.OptionPassed(pidArg)) { WriteOutput("Please choose some process to attach"); ProcessEnumCmd(""); return; } int pid; if (ap.Exists(0)) { pid = ap.AsInt(0); if (ap.OptionPassed(pidArg)) { WriteOutput("Do not specify pid option when also passing pid as last argument"); return; } } else { Debug.Assert(ap.OptionPassed(pidArg)); // verified above pid = ap.GetOption(pidArg).AsInt; } // // Do some sanity checks to give useful end-user errors. // // Can't attach to ourselves! if (Process.GetCurrentProcess().Id == pid) { throw new MDbgShellException("Cannot attach to myself!"); } // Can't attach to a process that we're already debugging. // ICorDebug may enforce this, but the error may not be very descriptive for an end-user. // For example, ICD may propogate an error from the OS, and the OS may return // something like AccessDenied if another debugger is already attached. // This only checks for cases where this same instance of MDbg is already debugging // the process of interest. foreach (MDbgProcess procOther in Debugger.Processes) { if (pid == procOther.CorProcess.Id) { throw new MDbgShellException("Can't attach to process " + pid + " because it's already being debugged"); } } // Get the OS handle if there was one SafeWin32Handle osEventHandle = null; if (ap.OptionPassed(continuationEventArg)) { osEventHandle = new SafeWin32Handle(new IntPtr(ap.GetOption(continuationEventArg).AsHexOrDecInt)); } // determine the version to attach to string version = null; if (ap.OptionPassed(versionArg)) { version = ap.GetOption(versionArg).AsString; } else { version = MdbgVersionPolicy.GetDefaultAttachVersion(pid); } if (version == null) { throw new MDbgShellException("Can't determine what version of the CLR to attach to in process " + pid + ". Use -ver to specify a version"); } // attach MDbgProcess p; p = Debugger.Attach(pid, osEventHandle, version); p.Go().WaitOne(); if (osEventHandle != null) { osEventHandle.Dispose(); } }
public static void RemapCmd(string args) { ArgParser ap = new ArgParser(args); if(!(Debugger.Processes.Active.StopReason is RemapOpportunityReachedStopReason)) { WriteError("Not stopped at RemapOpportunity breakpoint"); return; } RemapOpportunityReachedStopReason sr = (RemapOpportunityReachedStopReason)Debugger.Processes.Active.StopReason; if(!ap.Exists(0)) { // no arguments -- we just print content of last remap callback // we want to do remap. WriteOutput("Last FunctionRemapOpportunity Callback:"); WriteOutput("-----------------------------------------"); WriteOutput("AppDomain: "+sr.AppDomain.Name); WriteOutput("NewFunction: "+sr.NewFunction.Token); WriteOutput("OldFunction: "+sr.OldFunction.Token); WriteOutput("OldILOffset: "+sr.OldILOffset); WriteOutput("Thread Number: "+Debugger.Processes.Active.Threads.Lookup(sr.Thread).Number); } else { int newILOffset = ap.AsInt(0); sr.Thread.ActiveFrame.RemapFunction(newILOffset); Debugger.Processes.Active.Threads.InvalidateAllStacks(); WriteOutput("Remap successful."); } }
public static void QuitCmd(string arguments) { // Look for optional exit code. ArgParser 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. List<MDbgProcess> processesToKill = new List<MDbgProcess>(); 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(); // We can't wait for targets that never run (e.g. NoninvasiveStopGoController against a dump) if (p.CanExecute()) p.StopEvent.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); }
public static void NewObjCmd(string arguments) { ArgParser 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(); ArrayList 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("Newobj command not fully completed and debuggee has stopped"); WriteOutput("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) { MDbgValue mv = new MDbgValue(Debugger.Processes.Active, cv); WriteOutput("result = " + mv.GetStringValue(1)); if (Debugger.Processes.Active.DebuggerVars.SetEvalResult(cv)) WriteOutput("results saved to $result"); } } Shell.DisplayCurrentLocation(); }
public static void ModeCmd(string arguments) { // get mode settings first MDbgModeSettings modeSettings = Shell.Properties[MDbgModeSettings.PropertyName] as MDbgModeSettings; Debug.Assert(modeSettings != null); if (modeSettings == null) throw new MDbgShellException("corrupted internal state."); ArgParser 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; } }
public static void InterceptCmd(string arguments) { ArgParser 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."); }
private static void ThreadResumeSuspendHelper(ArgParser ap, CorDebugThreadState newState, bool showWarnings) { int threadNumber; if (ap == null) { throw new ArgumentException(); } 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, showWarnings); } } 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, showWarnings); } } } else { MDbgThread t = g_threadNickNames.GetThreadByNickName(ap.AsString(0)); if (t == null) { throw new ArgumentException(); } SetDebugStateWrapper(t, newState, showWarnings); } } else { SetDebugStateWrapper(Debugger.Processes.Active.Threads.Active, newState, showWarnings); } }
public static void WhenCmd(string arguments) { ArgParser 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.ToString()); } } 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 ConfigCmd(string arguments) { const string extPathCmd = "extpath"; const string extPathAddCmd = "extpath+"; ArgParser 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 ListCmd(string arguments) { const string verboseOpt = "v"; bool bVerbose; ArgParser 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 ShowCmd(string arguments) { MDbgSourcePosition pos = Debugger.Processes.Active.Threads.Active.CurrentSourcePosition; if (pos == null) { throw new MDbgShellException("No source location"); } string fileLoc = Shell.FileLocator.GetFileLocation(pos.Path); if (fileLoc == null) { throw new MDbgShellException(string.Format(CultureInfo.InvariantCulture, "Source file '{0}' not available.", pos.Path)); } IMDbgSourceFile file = Shell.SourceFileMgr.GetSourceFile(fileLoc); ArgParser 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++) { WriteOutput(String.Format(CultureInfo.InvariantCulture, "{0}{1}{2}", i, i == pos.Line ? ":*" : " ", file[i])); } }
/* * 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) { ArgParser 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 MDbgModule[] { 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 MDbgModule[] { m }; } else { modules = Debugger.Processes.Active.Modules; } foreach (MDbgModule m in modules) { WriteModuleStatus(m, false); } } break; default: Debug.Assert(false); break; } }
public static void EncCmd(string args) { ArgParser ap = new ArgParser(args); if(ap.Count==0) { WriteOutput("Performed edits:"); foreach(MDbgModule module in Debugger.Processes.Active.Modules) { if(module.EditsCounter>0) { WriteOutput(module.CorModule.Name); int edits = module.EditsCounter; for(int j=1;j<=edits;j++) { string editFile = module.GetEditsSourceFile(j); WriteOutput(String.Format(CultureInfo.InvariantCulture, " {0}. - {1}",new Object[]{j,editFile==null?"N/A":editFile})); } } } return; } if(ap.Count<1 && ap.Count>3) { WriteError("Wrong amount of arguments!"); return; } string encModule = ap.AsString(0); MDbgModule m = Debugger.Processes.Active.Modules.Lookup(encModule); string modName = System.IO.Path.DirectorySeparatorChar + Path.GetFileName(m.CorModule.Name); string pathToEncFiles = Path.GetDirectoryName(m.CorModule.Name); // defaults to location of the module string editSourceFile; if(ap.Exists(1)) editSourceFile = ap.AsString(1); else editSourceFile = null; string deltasBaseName; if(ap.Exists(2)) deltasBaseName = ap.AsString(2); else deltasBaseName = pathToEncFiles+modName+".1"; string deltaPdbFile = deltasBaseName+".pdb"; if( !File.Exists(deltaPdbFile) ) { WriteOutput("Delta PDB file not found; debug symbols won't be updated."); deltaPdbFile = null; } m.ApplyEdit(deltasBaseName+".dmeta", deltasBaseName+".dil", deltaPdbFile, editSourceFile); WriteOutput("ENC successfully applied."); }
public static void OpendumpCmd(string arguments) { const string pathArg = "path"; ArgParser ap = new ArgParser(arguments, pathArg + ":1"); if (ap.Count > 1) { throw new MDbgShellException("Wrong # of arguments."); } if (!ap.Exists(0) && !ap.OptionPassed(pathArg)) { throw new MDbgShellException("Specify a dump file to open"); } string path; if (ap.Exists(0)) path = ap.AsString(0); else path = ap.GetOption(pathArg).AsString; DumpReader dump = new DumpReader(path); MDbgProcess process = Debugger.Processes.CreateProcess(); // An exception partway through attaching can leave the debugger in an odd in-between state. // We need to attempt to detach. bool success = false; try { process.AttachToDump(dump, null); success = true; } finally { // Fault handler (emulate with finally & success bool since C# doesn't support fault blocks) // Detach on failure so we're not left with a partially attached process if (!success) process.Detach(); } WriteOutput("DBI path: " + ((LibraryProvider)process.LibraryProvider).LastLoadedDbi); // If there's an exception of interest stored in the dump, use it. // Otherwise, fall back on going to the first thread with managed code. if (dump.IsExceptionStream()) { uint TID = dump.ExceptionStreamThreadId(); WriteOutput("OS TID from last exception in dump was 0n" + TID); MDbgThread thread = process.Threads.GetThreadFromThreadId((int)TID); if (null == thread) { WriteOutput("Could not find a managed thread corresponding to native TID!\n" + "This should indicate that the last event was a native event on an unmanaged thread.\n" ); } else { process.Threads.Active = thread; WriteOutput("Active thread set to " + process.Threads.Active.Id); } } else { WriteOutput("No exception in dump, current thread will be chosen randomly."); // Set the currently active thread to the first thread we find with managed code on it. bool foundThread = false; for (int i = 0; i < process.Threads.Count && !foundThread; i++) { foreach (MDbgFrame frame in process.Threads[i].Frames) { if (frame != null && frame.IsManaged) { process.Threads.Active = process.Threads[i]; foundThread = true; } } } if (!foundThread) { WriteOutput("Warning: couldn't find thread with managed frame at base in dump"); } } // This can fail silently if we can't walk the first frame of the stack. process.AsyncStop(); process.Threads.Active.InvalidateStackWalker(); WriteOutput("Dump loaded successfully."); }