public static void Doit() { var processInfo = new ProcessInfo (StartupOptions.UnityProcessId, "Unity"); var engines = DebuggingService.GetDebuggerEngines (); var engine = engines.Where (e => e.Id == "MonoDevelop.Debugger.Soft.Unity").SingleOrDefault (); if (engine == null) return; IdeApp.ProjectOperations.AttachToProcess (engine, processInfo ); }
public static IAsyncOperation AttachToProcess (this ProjectOperations opers, DebuggerEngine debugger, ProcessInfo proc) { if (opers.CurrentRunOperation != null && !opers.CurrentRunOperation.IsCompleted) return opers.CurrentRunOperation; var oper = DebuggingService.AttachToProcess (debugger, proc); opers.CurrentRunOperation = oper; return opers.CurrentRunOperation; }
public ProcessInfo[] GetAttachableProcesses () { List<ProcessInfo> procs = new List<ProcessInfo> (); foreach (string dir in Directory.GetDirectories ("/proc")) { int id; if (!int.TryParse (Path.GetFileName (dir), out id)) continue; try { File.ReadAllText (Path.Combine (dir, "sessionid")); } catch { continue; } string cmdline = File.ReadAllText (Path.Combine (dir, "cmdline")); cmdline = cmdline.Replace ('\0',' '); ProcessInfo pi = new ProcessInfo (id, cmdline); procs.Add (pi); } return procs.ToArray (); }
public static IAsyncOperation AttachToProcess (DebuggerEngine debugger, ProcessInfo proc) { currentEngine = debugger; session = debugger.CreateSession (); session.ExceptionHandler = ExceptionHandler; IProgressMonitor monitor = IdeApp.Workbench.ProgressMonitors.GetRunProgressMonitor (); console = monitor as IConsole; SetupSession (); session.TargetExited += delegate { monitor.Dispose (); }; session.AttachToProcess (proc, GetUserOptions ()); return monitor.AsyncOperation; }
ProcessInfo GetProcess (CorProcess proc) { ProcessInfo info; lock (processes) { if (!processes.TryGetValue (proc.Id, out info)) { info = new ProcessInfo (proc.Id, ""); processes[proc.Id] = info; } } return info; }
ThreadInfo GetThread (ProcessInfo process, ThreadMirror thread) { long tid = GetId (thread); foreach (var t in OnGetThreads (process.Id)) if (t.Id == tid) return t; return null; }
void EnsureRecentThreadIsValid (ProcessInfo process) { var infos = process.GetThreads (); if (ThreadIsAlive (recent_thread) && HasUserFrame (GetId (recent_thread), infos)) return; var threads = vm.GetThreads (); foreach (var thread in threads) { if (ThreadIsAlive (thread) && HasUserFrame (GetId (thread), infos)) { recent_thread = thread; return; } } recent_thread = threads[0]; }
static void EnsureCreated() { lock (_lock) { if (_session != null) return; _session = new SoftDebuggerSession(); _session.Breakpoints = BreakEvents; _session.ExceptionHandler = ex => { if (Configuration.Current.LogInternalErrors) { Log.Error("Internal debugger error:", ex.GetType()); Log.Error(ex.ToString()); } return true; }; _session.LogWriter = (isStdErr, text) => { if (Configuration.Current.LogRuntimeSpew) Log.NoticeSameLine("[Mono] {0}", text); // The string already has a line feed. }; _session.OutputWriter = (isStdErr, text) => { //lock (Log.Lock) //{ if (Callback != null) { Callback.Invoke(isStdErr ? "ErrorOutput" : "Output", null, null, text); } else { if (isStdErr) Console.Error.Write(text); else Console.Write(text); } //} }; _session.TypeResolverHandler += (identifier, location) => { // I honestly have no idea how correct this is. I suspect you // could probably break it in some corner cases. It does make // something like `p Android.Runtime.JNIEnv.Handle` work, // though, which would otherwise have required `global::` to // be explicitly prepended. if (identifier == "__EXCEPTION_OBJECT__") return null; foreach (var loc in ActiveFrame.GetAllLocals()) if (loc.Name == identifier) return null; return identifier; }; _session.TargetEvent += (sender, e) => { Log.Debug("Event: '{0}'", e.Type); }; _session.TargetStarted += (sender, e) => { _activeFrame = null; /* if (_showResumeMessage) Log.Notice("Inferior process '{0}' ('{1}') resumed", ActiveProcess.Id, StringizeTarget()); */ }; _session.TargetReady += (sender, e) => { _activeProcess = _session.GetProcesses().SingleOrDefault(); // The inferior process has launched, so we can safely // set our `SIGINT` handler without it interfering with // the inferior. CommandLine.SetControlCHandler(); /* Log.Notice("Inferior process '{0}' ('{1}') started", ActiveProcess.Id, StringizeTarget()); */ }; _session.TargetStopped += (sender, e) => { //Log.Notice("Inferior process '{0}' ('{1}') suspended", // ActiveProcess.Id, StringizeTarget()); //Log.Emphasis(Utilities.StringizeFrame(ActiveFrame, true)); if (Callback != null) { Callback.Invoke("TargetStopped", ActiveFrame.SourceLocation, e.Thread, null); } CommandLine.ResumeEvent.Set(); }; _session.TargetInterrupted += (sender, e) => { Log.Notice("Inferior process '{0}' ('{1}') interrupted", ActiveProcess.Id, StringizeTarget()); Log.Emphasis(Utilities.StringizeFrame(ActiveFrame, true)); CommandLine.ResumeEvent.Set(); }; _session.TargetHitBreakpoint += (sender, e) => { // var bp = e.BreakEvent as Breakpoint; // var fbp = e.BreakEvent as FunctionBreakpoint; /* if (fbp != null) Log.Notice("Hit method breakpoint on '{0}'", fbp.FunctionName); else { var cond = bp.ConditionExpression != null ? string.Format(" (condition '{0}' met)", bp.ConditionExpression) : string.Empty; Log.Notice("Hit breakpoint at '{0}:{1}'{2}", bp.FileName, bp.Line, cond); } Log.Emphasis(Utilities.StringizeFrame(ActiveFrame, true)); */ if (Callback != null) { Callback.Invoke("TargetHitBreakpoint", ActiveFrame.SourceLocation, e.Thread, null); } CommandLine.ResumeEvent.Set(); }; _session.TargetExited += (sender, e) => { var p = ActiveProcess; /* // Can happen when a remote connection attempt fails. if (p == null) { if (_kind == SessionKind.Listening) Log.Notice("Listening socket closed"); else if (_kind == SessionKind.Connected) Log.Notice("Connection attempt terminated"); else Log.Notice("Failed to connect to '{0}'", StringizeTarget()); } else Log.Notice("Inferior process '{0}' ('{1}') exited", ActiveProcess.Id, StringizeTarget()); */ // Make sure we clean everything up on a normal exit. Kill(); _debuggeeKilled = true; _kind = SessionKind.Disconnected; if (Callback != null) { Callback.Invoke("TargetExited", null, null, null); } CommandLine.ResumeEvent.Set(); }; _session.TargetExceptionThrown += (sender, e) => { var ex = ActiveException; //Log.Notice("Trapped first-chance exception of type '{0}'", ex.Type); //Log.Emphasis(Utilities.StringizeFrame(ActiveFrame, true)); PrintException(ex); if (Callback != null) { Callback.Invoke("TargetExceptionThrown", ActiveFrame.SourceLocation, e.Thread, null); } CommandLine.ResumeEvent.Set(); }; _session.TargetUnhandledException += (sender, e) => { var ex = ActiveException; //Log.Notice("Trapped unhandled exception of type '{0}'", ex.Type); //Log.Emphasis(Utilities.StringizeFrame(ActiveFrame, true)); PrintException(ex); if (Callback != null) { Callback.Invoke("TargetUnhandledException", ActiveFrame.SourceLocation, e.Thread, null); } CommandLine.ResumeEvent.Set(); }; _session.TargetThreadStarted += (sender, e) => { //Log.Notice("Inferior thread '{0}' ('{1}') started", // e.Thread.Id, e.Thread.Name); if (Callback != null) { Callback.Invoke("TargetThreadStarted", null, e.Thread, null); } }; _session.TargetThreadStopped += (sender, e) => { //Log.Notice("Inferior thread '{0}' ('{1}') exited", // e.Thread.Id, e.Thread.Name); if (Callback != null) { Callback.Invoke("TargetThreadStopped", null, e.Thread, null); } }; } }
void AppendThreads (TreeIter it, ProcessInfo p) { ThreadInfo[] threads = p.GetThreads (); Array.Sort (threads, delegate (ThreadInfo t1, ThreadInfo t2) { return t1.Id.CompareTo (t2.Id); }); foreach (ThreadInfo t in threads) { ThreadInfo activeThread = DebuggingService.DebuggerSession.ActiveThread; Pango.Weight wi = t == activeThread ? Pango.Weight.Bold : Pango.Weight.Normal; string icon = t == activeThread ? Gtk.Stock.GoForward : null; if (it.Equals (TreeIter.Zero)) store.AppendValues (icon, t.Id.ToString (), t.Name, t, (int) wi, t.Location); else store.AppendValues (it, icon, t.Id.ToString (), t.Name, t, (int) wi, t.Location); } }
ThreadInfo GetThread (ProcessInfo process, ThreadMirror thread) { foreach (var t in OnGetThreads (process.Id)) if (t.Id == thread.Id) return t; return null; }
void AppendThreads (TreeIter iter, ProcessInfo process, DebuggerSession session) { var threads = process.GetThreads (); Array.Sort (threads, (ThreadInfo t1, ThreadInfo t2) => t1.Id.CompareTo (t2.Id)); session.FetchFrames (threads); var activeThread = session.ActiveThread; foreach (var thread in threads) { var name = thread.Name == null && thread.Id == 1 ? GettextCatalog.GetString ("Main Thread") : thread.Name; var weight = thread == activeThread ? Pango.Weight.Bold : Pango.Weight.Normal; var icon = thread == activeThread ? Gtk.Stock.GoForward : null; if (iter.Equals (TreeIter.Zero)) store.AppendValues (icon, thread.Id.ToString (), name, thread, (int)weight, thread.Location, session); else store.AppendValues (iter, icon, thread.Id.ToString (), name, thread, (int)weight, thread.Location, session); } }
void AppendThreads (TreeIter iter, ProcessInfo process) { var threads = process.GetThreads (); Array.Sort (threads, (ThreadInfo t1, ThreadInfo t2) => t1.Id.CompareTo (t2.Id)); DebuggingService.DebuggerSession.FetchFrames (threads); foreach (var thread in threads) { ThreadInfo activeThread = DebuggingService.DebuggerSession.ActiveThread; var weight = thread == activeThread ? Pango.Weight.Bold : Pango.Weight.Normal; var icon = thread == activeThread ? Gtk.Stock.GoForward : null; if (iter.Equals (TreeIter.Zero)) store.AppendValues (icon, thread.Id.ToString (), thread.Name, thread, (int) weight, thread.Location); else store.AppendValues (iter, icon, thread.Id.ToString (), thread.Name, thread, (int) weight, thread.Location); } }