private void DoNonThreadedProcessExited(object sender, EventArgs e)
        {
            Contract.Requires(System.Threading.Thread.CurrentThread.ManagedThreadId == 1, "can only be used from the main thread");

            m_results.OnStopped();

            string errors = m_errors.ToString();
            if (m_process.ExitCode == 0 && errors.Length == 0)	// poorly written makefiles may return OK even if there were errors...
            {
                TimeSpan elapsed = DateTime.Now - m_startTime;
                m_results.WriteOutput(string.Format("built in {0:0.0} secs", elapsed.TotalSeconds));
                m_results.WriteOutput(Environment.NewLine);
                m_results.WriteOutput(Environment.NewLine);
            }
            else
            {
                m_results.WriteError("exited with code " + m_process.ExitCode);
                m_results.WriteError(Environment.NewLine);
                m_results.WriteError(Environment.NewLine);
            }

            if (m_process.ExitCode == 0)
                Broadcaster.Invoke("built target", m_target);

            DoHandleErrors(errors);

            m_process.Dispose();
            AssemblyCache.ReleaseLock();			// note that we need to be very careful about where we call this to ensure that we don't wind up calling it twice
            m_process = null;

            if (m_state != State.Canceled)
                m_state = State.Built;
            Broadcaster.Invoke("finished building", m_target);
        }
        private void DoTransition(State newState)
        {
            if (newState != m_state)
            {
                Log.WriteLine(TraceLevel.Verbose, "Debugger", "Transitioning from {0} to {1}", m_state, newState);
                m_state = newState;

                NSApplication.sharedApplication().BeginInvoke(() => m_debugger.OnStateChanged(newState));
            }
        }
        public void Cancel()
        {
            m_state = State.Canceled;

            try
            {
                if (m_process != null)	// toolbar buttons are enabled via a timer (and apple doesn't validate them before processing a click) so we can be called when we aren't actually building
                    m_process.Kill();
            }
            catch (InvalidOperationException e)
            {
                // This will be thrown if the process has already exited. This may happen
                // if we lose a race or if we get confused because of recursive make weirdness.
                Log.WriteLine(TraceLevel.Info, "Errors", "error killing the build process:");
                Log.WriteLine(TraceLevel.Info, "Errors", e.Message);
            }
        }
        public void Build()
        {
            DoSaveChanges();

            Boss boss = ObjectModel.Create("Application");
            var errorHandler = boss.Get<IHandleBuildError>();
            errorHandler.Close();

            m_state = State.Building;
            m_errors = new StringBuilder();

            try
            {
                if (m_process != null)		// this should not normally happen, but may if an exception is thrown (or Exited isn't called for some reason)
                {
                    Log.WriteLine(TraceLevel.Warning, "Errors", "m_process was not null");

                    AssemblyCache.ReleaseLock();
                    m_process.Dispose();
                    m_process = null;
                }

                m_process = m_builder.Build(m_target);
                AssemblyCache.AcquireLock();
                m_process.EnableRaisingEvents = true;
                m_process.Exited += this.DoProcessExited;
                m_process.StartInfo.RedirectStandardOutput = true;
                m_process.StartInfo.RedirectStandardError = true;
                m_process.OutputDataReceived += this.DoGotStdoutData;
                m_process.ErrorDataReceived += this.DoGotStderrData;

                m_results.OnStarted();
                m_results.WriteCommand(m_builder.Command);

                m_startTime = DateTime.Now;
                m_process.Start();

                m_process.BeginOutputReadLine();
                m_process.BeginErrorReadLine();
            }
            catch (Exception e)		// started getting "Error creating standard error pipe" with mono 2.6.1 (which is usually wrapped within a TargetInvocationException)
            {
                if (m_process != null)
                    m_process.Dispose();
                AssemblyCache.ReleaseLock();
                m_process = null;
                m_state = State.Canceled;

                Log.WriteLine(TraceLevel.Info, "Errors", "Failed to build:");
                Log.WriteLine(TraceLevel.Info, "Errors", e.ToString());

                NSString title = NSString.Create("Couldn't build {0}.", m_target);
                NSString message = NSString.Create(e.Message);
                Unused.Value = Functions.NSRunAlertPanel(title, message);
            }
        }
Exemple #5
0
 internal void OnStateChanged(State newState)
 {
     if (!m_shutDown)
         Broadcaster.Invoke("debugger state changed", newState);
 }
        public void OnBroadcast(string name, object value)
        {
            switch (name)
            {
                case "debugger started":
                    m_debugger = (Debugger) value;
                    DoRefreshThreads();
                    m_table.reloadData();
                    break;

                case "debugger stopped":
                    m_debugger = null;
                    m_threads.Clear();
                    m_table.reloadData();
                    break;

                case "debugger processed breakpoint event":
                case "debugger thrown exception":
                case "debugger break all":
                case "debugger processed step event":
                    var context = (Context) value;
                    DoRefreshThreads();						// need to refresh this each time because thread states may have changed
                    m_selected = m_threads.IndexOf(context.Thread);
                    m_table.reloadData();
                    break;

                case "debugger state changed":
                    var state = (State) value;
                    if (state != m_state)
                    {
                        m_state = state;
                        if (state != State.Paused && state != State.Running && m_threads.Count > 0)
                        {
                            m_threads.Clear();
                            m_table.reloadData();
                        }
                    }
                    break;

                case "debugger thread started":
                    DoRefreshThreads();
                    m_table.reloadData();
                    break;

                case "debugger thread died":
                    var thread = (ThreadMirror) value;
                    m_names.Remove(thread.Id);
                    DoRefreshThreads();
                    m_table.reloadData();
                    break;

                default:
                    Contract.Assert(false, "bad name: " + name);
                    break;
            }
        }
        public void OnBroadcast(string name, object value)
        {
            switch (name)
            {
                case "debugger stopped":
                    m_stack = null;
                    m_table.reloadData();
                    break;

                case "debugger processed breakpoint event":
                case "debugger thrown exception":
                case "debugger processed step event":
                case "debugger break all":
                    var context = (Context) value;
                    var stack = new LiveStack(context.Thread);

                    // Note that the new stack should almost always be different than the cached
                    // stack so there isn't much point in comparing the two (and the equals operator
                    // doesn't compare IL offsets (if it did then stepping would cause stacks to compare
                    // different and the variables window would do a full refresh instead of a partial
                    // refresh and we'd lose the ability to draw changes in red)).
                    m_stack = stack;
                    m_selected = 0;
                    m_table.reloadData();
                    m_table.scrollRowToVisible(m_stack.Length - 1);
                    break;

                case "changed thread":
                    var stack2 = (LiveStack) value;
                    if (stack2 != m_stack)
                    {
                        m_stack = stack2;
                        m_selected = 0;
                        m_table.reloadData();
                        m_table.scrollRowToVisible(m_stack.Length - 1);
                    }
                    break;

                case "debugger state changed":
                    var state = (State) value;
                    if (state != m_state)
                    {
                        m_state = state;
                        if (state != State.Paused && state != State.Running && m_stack != null)
                        {
                            m_stack = null;
                            m_table.reloadData();
                        }
                    }
                    break;

                default:
                    Contract.Assert(false, "bad name: " + name);
                    break;
            }
        }