public static void LaunchProcessWithAttachedDebugger() { var filename = GetFilename(); Console.WriteLine("Launching " + filename); var stop = new ManualResetEvent(false); var engine = new MDbgEngine(); var process = engine.CreateProcess(filename, "", DebugModeFlag.Default, null); process.Go(); process.PostDebugEvent += (sender, e) => { if (e.CallbackType == ManagedCallbackType.OnBreakpoint) process.Go(); if (e.CallbackType == ManagedCallbackType.OnProcessExit) stop.Set(); }; //var p = Process.Start(filename); Console.WriteLine("Launched..."); stop.WaitOne(); Application.Exit(); }
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]; } } }
public static Dictionary<string, string> GetLocalVars(MDbgEngine pDebugger, List<string> specificVarNames = null, bool debuggerVarsOpt = false, bool noFuncevalOpt = false, int? expandDepthOpt = null) { Dictionary<string, string> retVal = new Dictionary<string, string>(); //const string debuggerVarsOpt = "d"; //const string noFuncevalOpt = "nf"; //const string expandDepthOpt = "r"; //ArgParser ap = new ArgParser(arguments, debuggerVarsOpt + ";" + noFuncevalOpt + ";" + expandDepthOpt + ":1"); bool canDoFunceval = !noFuncevalOpt; int? expandDepth = null; // we use optional here because // different codes bellow has different // default values. if (expandDepthOpt != null) { expandDepth = (int)expandDepthOpt; if (expandDepth < 0) throw new MDbgShellException("Depth cannot be negative."); } MDbgFrame frame = pDebugger.Processes.Active.Threads.Active.CurrentFrame; if (debuggerVarsOpt) { // let's print all debugger variables MDbgProcess p = pDebugger.Processes.Active; foreach (MDbgDebuggerVar dv in p.DebuggerVars) { MDbgValue v = new MDbgValue(p, dv.CorValue); string value = v.GetStringValue(expandDepth == null ? 0 : (int)expandDepth, canDoFunceval); retVal.Add(dv.Name, value); } } else { //!debuggerVarsOpt && !noFuncevalOpt && expandDepthOpt == null && if (specificVarNames == null || specificVarNames.Count == 0) { // get all active variables MDbgFunction f = frame.Function; ArrayList 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) { string value = v.GetStringValue(expandDepth == null ? 0 : (int)expandDepth, canDoFunceval); retVal.Add(v.Name, value); } } else { // user requested printing of specific variables for (int j = 0; j < specificVarNames.Count; ++j) { MDbgValue var = pDebugger.Processes.Active.ResolveVariable(specificVarNames[j], frame); if (var != null) { string value = var.GetStringValue(expandDepth == null ? 1 : (int)expandDepth, canDoFunceval); retVal.Add(specificVarNames[j], value); } else { throw new MDbgShellException("Variable not found"); } } } } return retVal; }
////////////////////////////////////////////////////////////////////////////////// // // Customization methods (to be overriden in aditional skins). // ////////////////////////////////////////////////////////////////////////////////// protected virtual void Init(string[] commandLineArguments) { string[] initialCommands = null; // process startup commands if (commandLineArguments.Length != 0) { ArrayList startupCommands = new ArrayList(); if (commandLineArguments[0].Length > 1 && commandLineArguments[0][0] == '!') { // ! commands on command line int i = 0; while (i < commandLineArguments.Length) { StringBuilder sb = new StringBuilder(); Debug.Assert(commandLineArguments[i][0] == '!'); sb.Append(commandLineArguments[i].Substring(1)); ++i; while (i < commandLineArguments.Length && !(commandLineArguments[i].Length > 1 && commandLineArguments[i][0] == '!')) { sb.Append(' '); sb.Append(commandLineArguments[i]); ++i; } startupCommands.Add(sb.ToString()); } } else { // it is name of executable on the command line StringBuilder sb = new StringBuilder("run"); for (int i = 0; i < commandLineArguments.Length; i++) { sb.Append(' '); string arg = commandLineArguments[i]; if (arg.IndexOf(' ') != -1) { // argument contains spaces, need to quote it sb.Append('\"').Append(arg).Append('\"'); } else { sb.Append(arg); } } startupCommands.Add(sb.ToString()); } initialCommands = (string[])startupCommands.ToArray(typeof(string)); } this.IO = new MDbgIO(this, initialCommands); MdbgCommands.Shell = this; m_debugger = new MDbgEngine(); MdbgCommands.Initialize(); OnCommandExecuted += new CommandExecutedEventHandler(MdbgCommands.WhenHandler); ProcessAutoExec(); }
public static void AttachCmd(int pid, MDbgEngine debugger) { 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 Exception("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 Exception("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 = MdbgVersionPolicy.GetDefaultAttachVersion(pid); //} if (version == null) { throw new Exception("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 = debugger.Attach(pid, null, version); p.Go().WaitOne(); //if (osEventHandle != null) //{ // osEventHandle.Dispose(); //} }
/// <summary> /// Skip past fake attach events. /// </summary> /// <param name="debugger"></param> /// <param name="proc"></param> public static void DrainAttach(MDbgEngine debugger, MDbgProcess proc) { bool fOldStatus = debugger.Options.StopOnNewThread; debugger.Options.StopOnNewThread = false; // skip while waiting for AttachComplete proc.Go().WaitOne(); Debug.Assert(proc.StopReason is AttachCompleteStopReason); debugger.Options.StopOnNewThread = true; // needed for attach= true; // needed for attach // Drain the rest of the thread create events. while (proc.CorProcess.HasQueuedCallbacks(null)) { proc.Go().WaitOne(); Debug.Assert(proc.StopReason is ThreadCreatedStopReason); } debugger.Options.StopOnNewThread = fOldStatus; }
internal MDbgProcessCollection(MDbgEngine engine) { m_engine = engine; }
static void Main(string[] args) { if (args.Length < 1) { Usage(); return; } int samples = 10; int sampleInterval = 1000; var state = ParseState.Unknown; foreach (var arg in args.Skip(1)) { switch (state) { case ParseState.Unknown: if (arg.ToLower() == "/s") { state = ParseState.Samples; } else if (arg.ToLower() == "/i") { state = ParseState.Interval; } else { Usage(); return; } break; case ParseState.Samples: if (!Int32.TryParse(arg, out samples)) { Usage(); return; } state = ParseState.Unknown; break; case ParseState.Interval: if (!Int32.TryParse(arg, out sampleInterval)) { Usage(); return; } state = ParseState.Unknown; break; default: break; } } string pidOrProcess = args[0]; var stats = new Dictionary<int, List<ThreadSnapshot>>(); var debugger = new MDbgEngine(); int pid = -1; var processes = Process.GetProcessesByName(pidOrProcess); if (processes.Length < 1) { try { pid = Int32.Parse(pidOrProcess); } catch { Console.WriteLine("Error: could not find any processes with that name or pid"); return; } } else { if (processes.Length > 1) { Console.WriteLine("Warning: multiple processes share that name, attaching to the first"); } pid = processes[0].Id; } MDbgProcess attached = null; try { attached = debugger.Attach(pid); } catch(Exception e) { Console.WriteLine("Error: failed to attach to process: " + e); return; } attached.Go().WaitOne(); for (int i = 0; i < samples; i++) { foreach (MDbgThread thread in attached.Threads) { var snapshot = ThreadSnapshot.GetThreadSnapshot(thread); List<ThreadSnapshot> snapshots; if (!stats.TryGetValue(snapshot.Id, out snapshots)) { snapshots = new List<ThreadSnapshot>(); stats[snapshot.Id] = snapshots; } snapshots.Add(snapshot); } attached.Go(); Thread.Sleep(sampleInterval); attached.AsyncStop().WaitOne(); } attached.Detach().WaitOne(); // perform basic analysis to see which are the top N stack traces observed, // weighted on cost Dictionary<Guid, long> costs = new Dictionary<Guid,long>(); Dictionary<Guid, string> stacks = new Dictionary<Guid, string>(); foreach (var stat in stats.Values) { long prevTime = -1; foreach (var snapshot in stat) { long time = snapshot.KernelTime + snapshot.UserTime; if (prevTime != -1) { foreach (var tuple in snapshot.StackHashes) { if (costs.ContainsKey(tuple.Item1)) { costs[tuple.Item1] += time - prevTime; } else { costs[tuple.Item1] = time - prevTime; stacks[tuple.Item1] = tuple.Item2; } } } prevTime = time; } } Console.WriteLine("Most expensive stacks"); Console.WriteLine("------------------------------------"); foreach (var group in costs.OrderByDescending(p => p.Value).GroupBy(p => p.Value)) { List<string> stacksToShow = new List<string>(); foreach (var pair in group.OrderByDescending(p => stacks[p.Key].Length)) { if (!stacksToShow.Any(s => s.Contains(stacks[pair.Key]))) { stacksToShow.Add(stacks[pair.Key]); } } foreach (var stack in stacksToShow) { Console.WriteLine(stack); Console.WriteLine("===> Cost ({0})", group.Key); Console.WriteLine(); } } var offenders = stats.Values .Select(_ => ThreadSnapshotStats.FromSnapshots(_)) .OrderBy(stat => stat.TotalKernelTime + stat.TotalUserTime) .Reverse(); foreach (var stat in offenders) { Console.WriteLine("------------------------------------"); Console.WriteLine(stat.ThreadId); Console.WriteLine("Kernel: {0} User: {1}", stat.TotalKernelTime, stat.TotalUserTime); foreach (var method in stat.CommonStack) { Console.WriteLine(method); } Console.WriteLine("Other Stacks:"); var prev = new List<string>(); foreach (var trace in stats[stat.ThreadId].Select(_ => _.StackTrace)) { if (!prev.SequenceEqual(trace)) { Console.WriteLine(); foreach (var method in trace) { Console.WriteLine(method); } } else { Console.WriteLine("<skipped>"); } prev = trace; } Console.WriteLine("------------------------------------"); } }
/// <summary>Starts the debugging process. This is synchronised on the Debugger /// object it is called on.</summary> /// <remarks> /// Assumes that the DebuggerSync object has been set up correctly and that something /// is listening to the BackgroundWorker events. It will lock indefinitely if something /// doesn't tell it to continue by calling set on the DebuggerSync.ContinueDebugExecution /// object. /// </remarks> public void Run() { lock (this) { int pid = DebugProcess.GetDebugProcessId(); CommandReceiver obj = DebugProcess.GetCommandReceiver(); // Get Assembly Search paths. These are used for finding // any assemblies that are used by the template. List<string> assemblySearchPaths = new List<string>(); foreach (string assemblyLocation in AssemblyLocations) { string dir = Path.GetDirectoryName(assemblyLocation).ToLower(); if (assemblySearchPaths.BinarySearch(dir) < 0) { assemblySearchPaths.Add(dir); assemblySearchPaths.Sort(); } } obj.ExecuteCommand(new RunFunctionCommand(CompiledAssemblyLocation, TestNamespace, TestClassname, TestFunctionName, ArgumentList, UserOptions, AaprojXml, IsFunctionStatic)); // This is a race condition, but it is required because we can't create the breakpoints // before attaching to the process. MDbgEngine debugger = new MDbgEngine(); proc = debugger.Attach(pid); _CurrentlyRunningBreakpoints.Clear(); foreach (int bp in _Breakpoints) { _CurrentlyRunningBreakpoints.Add(bp, proc.Breakpoints.CreateBreakpoint(CodeFilename, bp)); } proc.Breakpoints.CreateBreakpoint("Commands.cs", LAST_LINE_IN_MAIN); proc.Breakpoints.CreateBreakpoint(CodeFilename, LAST_LINE_IN_FUNCTION); _CurrentlyRunningProcess = proc; while (proc.IsAlive) { // Let the debuggee run and wait until it hits a debug event. switch (_DebuggerSync.NextDebugAction) { case DebugActionType.Continue: proc.Go().WaitOne(); break; case DebugActionType.StepInto: proc.StepInto(false).WaitOne(); break; case DebugActionType.StepOver: proc.StepOver(false).WaitOne(); break; case DebugActionType.StepOut: proc.StepOut().WaitOne(); break; case DebugActionType.Stop: _CurrentlyRunningProcess = null; proc.Breakpoints.DeleteAll(); proc.Detach(); break; } if (!proc.IsAlive) { proc = null; break; } // Get a DebugInformation object filled with the info we need. DebugInformation di = GetDebugInformation(proc); // If this is the last line, we need to stop debugging. if (di.StartLineNumber == LAST_LINE_IN_MAIN) { di.Stopped = false; di.StopReason = StopReason.DebuggerFinished; di.StopReasonText = "Debugger Finished"; _DebuggerSync.DebugBackgroundWorker.ReportProgress(99, di); _CurrentlyRunningProcess = null; proc.Breakpoints.DeleteAll(); proc.Detach(); break; } // Any other lines in the main function should just be skipped. if (di.SourceFile == "Commands.cs") { _DebuggerSync.NextDebugAction = DebugActionType.Continue; continue; } if (di.StartLineNumber == LAST_LINE_IN_FUNCTION) { _DebuggerSync.NextDebugAction = DebugActionType.StepOut; continue; } // If an exception was thrown, report it then stop debugging. if (di.ExceptionThrown) { di.Stopped = false; _DebuggerSync.DebugBackgroundWorker.ReportProgress(99, di); _CurrentlyRunningProcess = null; proc.Breakpoints.DeleteAll(); proc.Detach(); break; } di.Stopped = true; _DebuggerSync.DebugBackgroundWorker.ReportProgress(50, di); _DebuggerSync.ContinueDebugExecution.WaitOne(); continue; } } _CurrentlyRunningProcess = null; }
public FuncEvalSerializer(MDbgEngine debugger, bool useLoadFrom, IShell shell) { this.debugger = debugger; this.shell = shell; this.useLoadFrom = useLoadFrom; }
private void InitDebugging() { this.configuration = ReadConfiguration(options.Config); SymbolCache = new MDbgSymbolCache(); Debugger = new MDbgEngine(); BreakpointParser = new DefaultBreakpointParser(this); FileLocator = new MDbgFileLocator(); SourceFileMgr = new MDbgSourceFileMgr(); PdbSymbolCache = new PdbSymbolCache(configuration.assemblies.Select(a => a.path), this); languageUtils = new List<ILanguageUtil>(new[] { new CSharpLanguageUtil() }); methodLocators = new Dictionary<string, MethodLocator>(); foreach (var assembly in configuration.assemblies) { methodLocators[assembly.path] = new MethodLocator(assembly.path, assembly.language, this); } }
private static Dictionary<int, List<ThreadSnapshot>> CollectStats(SamplingParams sampling) { var stats = new Dictionary<int, List<ThreadSnapshot>>(); var debugger = new MDbgEngine(); MDbgProcess attached = null; try { attached = debugger.Attach(sampling.Pid); } catch (Exception e) { Console.WriteLine("Error: failed to attach to process: " + e); return stats; } attached.Go().WaitOne(); for (int i = 0; i < sampling.Samples; i++) { foreach (MDbgThread thread in attached.Threads) { try { var snapshot = ThreadSnapshot.GetThreadSnapshot(thread); List<ThreadSnapshot> snapshots; if (!stats.TryGetValue(snapshot.Id, out snapshots)) { snapshots = new List<ThreadSnapshot>(); stats[snapshot.Id] = snapshots; } snapshots.Add(snapshot); } catch (Exception ex) { Console.WriteLine("Exception getting sample #{0} from PID {1} : {2}", i, sampling.Pid, ex.ToString()); } } attached.Go(); Thread.Sleep(sampling.SampleInterval); attached.AsyncStop().WaitOne(); } attached.Detach().WaitOne(); return stats; }
/// <summary> /// Creates an MdbgProcess that can be compatible with dump debuggees. /// </summary> /// <param name="engine">owning engine object</param> /// <param name="stopGo">stopGo controller to provide policy for execution of process.</param> internal MDbgProcess(MDbgEngine engine, IStopGoController stopGo) { CommonInit(engine); m_stopGo = stopGo; }
/// <summary> /// Creates an MdbgProcess that can be compatible with the native pipeline /// debugging architecture /// </summary> /// <param name="engine">owning engine object</param> /// <param name="stopGo">stopGo controller to provide policy for execution of process.</param> public MDbgProcess(MDbgEngine engine) { CommonInit(engine); }
/// <summary>Creates an empty process object. /// This object can be used to start a debugging session by calling /// CreateProcess or Attach method on it. /// </summary> /// <param name="engine">Root engine object that manages this process.</param> /// <param name="debugger">CorDebugger object that will be used to do an actual /// debugging</param> public MDbgProcess(MDbgEngine engine, CorDebugger debugger) { Debug.Assert(debugger != null); if (debugger == null) throw new ArgumentNullException("debugger"); m_corDebugger = debugger; CommonInit(engine); }
/// <summary> /// /// attach and detach first to make sure that the process can be attached. /// next attach will be fast since the assembly loading is done on the first attach. /// </summary> /// <param name="pid"></param> public Task InitialAttach() { Task t = Task.Factory.StartNew(() => { MDbgEngine debugger = new MDbgEngine(); MDbgProcess process = DebuggerUtils.AttachToProcess(m_processId, debugger); process.CorProcess.Stop(0); process.Detach(); }); return t; }
public void StartListening() { if (m_processId == -1) return; if (m_blnIsListening) return; m_debugger = new MDbgEngine(); m_process = null; m_blnIsListening = true; Task t = Task.Factory.StartNew(() => { try { string timeString1 = DebuggerUtils.GetTimeString(true); m_process = DebuggerUtils.AttachToProcess(m_processId, m_debugger); LastLogFileName = Path.Combine(LogFileDirectory, m_process.Name + "(" + m_processId + ") T" + timeString1 + ".log"); } catch (Exception ex) { DebuggerUtils.HandleException(ex); } try { //m_process.Go(); //m_process.Go().WaitOne(); //m_process.Detach(); //m_debugger.Options.StopOnLogMessage = true; m_debugger.Options.StopOnException = true; //m_debugger.Options.StopOnExceptionEnhanced = false; m_debugger.Options.StopOnUnhandledException = true; m_blnIsListening = true; while (m_process.IsAlive) { //if (e.CallbackType == ManagedCallbackType.OnException2) //{ // var ce = (CorException2EventArgs)e.CallbackArgs; // if (ce.EventType == CorDebugExceptionCallbackType.DEBUG_EXCEPTION_FIRST_CHANCE) // { // var thread = process.Threads.Lookup(ce.Thread); // foreach (var frame in thread.Frames) // { // if (!frame.IsManaged || frame.Function.FullName.StartsWith("System.")) // break; // log.Log("{0}({1})", frame.Function.FullName, string.Join(", ", frame.Function.GetArguments(frame).Select( // arg => string.Format("{0} = {1}", arg.Name, arg.GetStringValue(false))))); // } // } //} try { m_process.Go().WaitOne(); //if (e.CallbackType == ManagedCallbackType.OnBreakpoint) //m_process.Go().WaitOne(); object o = m_process.StopReason; ExceptionThrownStopReason stopReason = o as ExceptionThrownStopReason; if (stopReason != null) { if (stopReason.EventType == Microsoft.Samples.Debugging.CorDebug.NativeApi.CorDebugExceptionCallbackType.DEBUG_EXCEPTION_UNHANDLED) { string timeString = DebuggerUtils.GetTimeString(true); if (WriteDumpOnUncaughtExceptions) { m_strLastDumpFileName = Path.Combine(m_strDumpFileDirectory, m_process.Name + timeString + ".dmp"); DumpWriter.WriteDump(m_process.CorProcess.Id, m_strLastDumpFileName, DumpOptions.WithFullMemory); } } if (LogExceptions) { //File.AppendAllText(LastLogFileName, DateTime.Now.ToString("dd\\MM\\yyyy mm:hh:ss.fff]") + DebuggerUtils.GetExceptionDescFromProcess(m_process) + "\n"); try { string exceptionDesc = DebuggerUtils.GetExceptionDescFromProcess(m_process, true); //Console.Out.WriteLine("----------------------------------------------------"); //Console.Out.WriteLine(exceptionDesc); File.AppendAllText(LastLogFileName, "----------------------------------------------------\n" + DateTime.Now.ToString("dd\\MM\\yyyy mm:hh:ss.fff]") + exceptionDesc + "\n"); m_sbProcessLog.AppendLine("----------------------------------------------------\n"); m_sbProcessLog.AppendLine(DateTime.Now.ToString("dd/MM/yyyy HH:mm:ss.fff")); m_sbProcessLog.AppendLine(exceptionDesc); } catch (Exception ex) { DebuggerUtils.HandleException(ex); } //m_process.Go(); } } } catch (Exception ex) { DebuggerUtils.HandleException(ex); } } m_blnIsListening = false; } catch (Exception ex) { DebuggerUtils.HandleException(ex); } //m_process.PostDebugEvent += m_processEventHandler; }); }
public static MDbgProcess AttachToProcess(int pid, MDbgEngine debugger) { debugger.Options.SymbolPath = ""; string ver = null; try { ver = CorDebugger.GetDebuggerVersionFromPid(pid); } catch (Exception ex) { //a problem getting the version doesn't mean that we can't attach, try with the default ver ver = CorDebugger.GetDefaultDebuggerVersion(); } MDbgProcess proc = debugger.Attach(pid, null, ver); DebuggerUtils.DrainAttach(debugger, proc); return proc; }
public List<ProcessSample> GetSample(int pid, int numOfSamples, int timeBetweenSamplesInMillis, bool extraDetails = false, bool originFirst = false) { List<ProcessSample> sample = null; MDbgProcess proc = null; try { MDbgEngine debugger = new MDbgEngine(); proc = DebuggerUtils.AttachToProcess(pid, debugger); sample = GetSample(proc, numOfSamples, timeBetweenSamplesInMillis, extraDetails, originFirst); } finally { if (proc != null) proc.Detach().WaitOne(); } return sample; }
public static MDbgProcess AttachToProcessWithName(string name) { MDbgEngine debugger = new MDbgEngine(); MDbgProcess retval = null; Process p = DebuggerUtils.GetFirstProcessWithName(name); if (p != null) retval = DebuggerUtils.AttachToProcess(p.Id, debugger); return retval; }
public static void DetachCmd(MDbgEngine debugger) { MDbgProcess active = debugger.Processes.Active; active.Breakpoints.DeleteAll(); active.Detach(); // We can't wait for targets that never run (e.g. NoninvasiveStopGoController against a dump) if (active.CanExecute()) active.StopEvent.WaitOne(); }
// Do common initiliazation and add to the process collection. void CommonInit(MDbgEngine engine) { Debug.Assert(engine != null); if (engine == null) throw new ArgumentException("Value cannot be null.", "engine"); m_engine = engine; m_threadMgr = new MDbgThreadCollection(this); m_appDomainMgr = new MDbgAppDomainCollection(this); m_moduleMgr = new MDbgModuleCollection(this); m_breakpointMgr = new MDbgBreakpointCollection(this); m_debuggerVarMgr = new MDbgDebuggerVarCollection(this); // we'll register as last code, so that other fields are already registered. m_number = engine.Processes.RegisterProcess(this); }