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 );
		}
Beispiel #2
0
		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);
					}
				};
			}
		}
Beispiel #9
0
		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;
		}
Beispiel #11
0
		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);
			}
		}
Beispiel #12
0
		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);
			}
		}