Exemplo n.º 1
0
        public bool ProcessEvent(Inferior.ChildEvent cevent)
        {
            Report.Debug (DebugFlags.EventLoop, "{0} received event {1}",
                      this, cevent);

            if (killed) {
                if (cevent.Type == Inferior.ChildEventType.CHILD_INTERRUPTED) {
                    inferior.Continue ();
                    return true;
                } else if (cevent.Type != Inferior.ChildEventType.CHILD_EXITED) {
                    Report.Debug (DebugFlags.EventLoop,
                              "{0} received event {1} when already killed",
                              this, cevent);
                    return true;
                }
            }

            if ((cevent.Type == Inferior.ChildEventType.CHILD_EXITED) ||
                (cevent.Type == Inferior.ChildEventType.CHILD_SIGNALED)) {
                Report.Debug (DebugFlags.EventLoop, "{0} received {1} while running {2}",
                          this, cevent, current_operation);
                // we can't remove the breakpoint anymore after
                // the target exited, but we need to clear this id.
                temp_breakpoint = null;
                dead = true;
            } else {
                string frame_text = "";
                Inferior.StackFrame iframe = inferior.GetCurrentFrame (true);
                if (iframe != null)
                    frame_text = " at " + iframe.Address.ToString ();

                string running_text;
                if (HasThreadLock)
                    running_text = String.Format ("being thread-locked ({0})", thread_lock);
                else
                    running_text = String.Format ("running {0}", current_operation);

                string event_text;
                if (cevent.Type == Inferior.ChildEventType.CHILD_NOTIFICATION)
                    event_text = String.Format ("notification {0} ({1})", cevent, (NotificationType) cevent.Argument);
                else
                    event_text = "event " + cevent.ToString ();

                Report.Debug (DebugFlags.EventLoop, "{0} received {1}{2} while {3}",
                          this, event_text, frame_text, running_text);

                if (HasThreadLock) {
                    thread_lock.SetStopEvent (cevent);
                    return false;
                }
            }

            if (Process.IsAttached && !attach_initialized) {
                attach_initialized = true;

                if (cevent.Type == Inferior.ChildEventType.CHILD_INTERRUPTED)
                    cevent = new Inferior.ChildEvent (Inferior.ChildEventType.CHILD_STOPPED, 0, 0, 0);
            }

            bool resume_target;
            if (manager.HandleChildEvent (this, inferior, ref cevent, out resume_target)) {
                Report.Debug (DebugFlags.EventLoop,
                          "{0} done handling event: {1}{2}{3}{4}",
                          this, cevent, resume_target ? " resume-target" : "" ,
                          stop_requested ? " stop-requested" : "",
                          HasThreadLock ? " thread-lock" : "");
                if (stop_requested) {
                    OperationInterrupted ();
                } else if (resume_target) {
                    if (!current_operation.ResumeOperation ())
                        inferior.Continue ();
                }
                return true;
            }

            Inferior.ChildEventType message = cevent.Type;
            int arg = (int) cevent.Argument;

            switch (message) {
            case Inferior.ChildEventType.CHILD_INTERRUPTED:
                if (current_operation != null)
                    OperationInterrupted ();
                return true;
            case Inferior.ChildEventType.CHILD_SIGNALED:
                if (killed)
                    OperationCompleted (new TargetEventArgs (TargetEventType.TargetExited, 0));
                else
                    OperationCompleted (new TargetEventArgs (TargetEventType.TargetSignaled, arg));
                return true;

            case Inferior.ChildEventType.INTERNAL_ERROR:
                frame_changed (inferior.CurrentFrame, null);
                Report.Error ("{0} got {1} at {2} while executing {3}", this, message,
                          inferior.CurrentFrame, current_operation);
                OperationCompleted (new TargetEventArgs (TargetEventType.TargetSignaled, -1));
                return true;

            case Inferior.ChildEventType.CHILD_EXITED:
                OperationCompleted (new TargetEventArgs (TargetEventType.TargetExited, arg));
                return true;

            case Inferior.ChildEventType.CHILD_CALLBACK_COMPLETED:
                frame_changed (inferior.CurrentFrame, null);
                OperationCompleted (new TargetEventArgs (TargetEventType.TargetStopped, 0, current_frame));
                return true;

            case Inferior.ChildEventType.RUNTIME_INVOKE_DONE:
                OperationRuntimeInvoke rti = rti_stack.Pop ();
                if (rti.ID != cevent.Argument)
                    throw new InternalError ("{0} got unknown RUNTIME_INVOKE_DONE: {1} {2}", this, rti.ID, cevent);

                frame_changed (inferior.CurrentFrame, null);
                rti.Completed (cevent.Data1, cevent.Data2);

                if (rti.IsSuspended) {
                    InterruptibleOperation io = nested_break_stack.Pop ();
                    if (io != rti)
                        throw new InternalError ("{0} unexpected item on nested break state stack: {1}", this, io);
                    process.Debugger.OnLeaveNestedBreakState (thread);
                }

                if (current_operation != rti) {
                    OperationCommandResult result = current_operation.Result as OperationCommandResult;
                    if (result != null)
                        result.Completed (this, null);
                    current_operation.Result.Completed ();
                }
                current_operation = rti;

                TargetEventArgs args = rti.OperationCompleted (current_frame, false);
                OperationCompleted (args);
                return true;
            }

            if (stop_requested) {
                switch (message) {
                case Inferior.ChildEventType.CHILD_STOPPED:
                case Inferior.ChildEventType.CHILD_CALLBACK:
                case Inferior.ChildEventType.CHILD_HIT_BREAKPOINT:
                    OperationInterrupted ();
                    return true;

                case Inferior.ChildEventType.UNHANDLED_EXCEPTION:
                case Inferior.ChildEventType.THROW_EXCEPTION:
                case Inferior.ChildEventType.HANDLE_EXCEPTION:
                case Inferior.ChildEventType.CHILD_NOTIFICATION:
                    inferior.RestartNotification ();
                    OperationInterrupted ();
                    return true;

                default:
                    OperationInterrupted ();
                    return false;
                }
            }

            DoProcessEvent (cevent);
            return true;
        }