Mono.Debugger.Backend.SingleSteppingEngine.DoProcessEvent C# (CSharp) Method

DoProcessEvent() protected method

protected DoProcessEvent ( Inferior cevent ) : void
cevent Inferior
return void
        protected void DoProcessEvent(Inferior.ChildEvent cevent)
        {
            Inferior.ChildEventType message = cevent.Type;
            int arg = (int) cevent.Argument;

            if (message == Inferior.ChildEventType.THROW_EXCEPTION) {
                TargetAddress info = new TargetAddress (inferior.AddressDomain, cevent.Data1);
                TargetAddress ip = new TargetAddress (manager.AddressDomain, cevent.Data2);

                Report.Debug (DebugFlags.EventLoop,
                          "{0} received exception: {1} {2} {3}", this, message, info, ip);

                TargetAddress stack = inferior.ReadAddress (info);
                TargetAddress exc = inferior.ReadAddress (info + inferior.TargetAddressSize);

                ExceptionAction action = throw_exception (stack, exc, ip);

                Report.Debug (DebugFlags.SSE,
                          "{0} throw exception ({1}:{2}:{3}) - {4} - {5} - {6}",
                          this, stack, exc, ip, action, current_operation, temp_breakpoint);

                switch (action) {
                case ExceptionAction.None:
                    do_continue ();
                    return;

                case ExceptionAction.Stop:
                    inferior.WriteInteger (info + 2 * inferior.TargetAddressSize, 1);
                    PushOperation (new OperationException (this, ip, exc, false));
                    return;

                case ExceptionAction.StopUnhandled:
                    if (!check_runtime_version (81, 1) && !check_runtime_version (80, 1))
                        goto case ExceptionAction.Stop;
                    inferior.WriteInteger (info + 4 + 2 * inferior.TargetAddressSize, 1);
                    do_continue ();
                    return;
                }
            }

            if (message == Inferior.ChildEventType.HANDLE_EXCEPTION) {
                TargetAddress info = new TargetAddress (inferior.AddressDomain, cevent.Data1);
                TargetAddress ip = new TargetAddress (manager.AddressDomain, cevent.Data2);

                Report.Debug (DebugFlags.EventLoop,
                          "{0} received exception: {1} {2} {3}", this, message, info, ip);

                TargetAddress stack = inferior.ReadAddress (info);
                TargetAddress exc = inferior.ReadAddress (info + inferior.TargetAddressSize);

                bool stop = handle_exception (stack, exc, ip);

                Report.Debug (DebugFlags.SSE,
                          "{0} {1}stopping at exception handler ({2}:{3}:{4}) - {4} - {5}",
                          this, stop ? "" : "not ", stack, exc, ip, current_operation, temp_breakpoint);

                if (stop) {
                    inferior.WriteInteger (info + 2 * inferior.TargetAddressSize, 1);
                    PushOperation (new OperationException (this, ip, exc, false));
                    return;
                }

                do_continue ();
                return;
            }

            if (lmf_breakpoint != null) {
                if ((message == Inferior.ChildEventType.CHILD_HIT_BREAKPOINT) &&
                    (arg == lmf_breakpoint.Breakpoint.ID)) {
                    remove_lmf_breakpoint ();

                    Report.Debug (DebugFlags.SSE, "{0} back in managed land: {1}",
                              this, inferior.CurrentFrame);

                    Method method = Lookup (inferior.CurrentFrame);

                    bool is_managed = (method != null) && method.Module.Language.IsManaged;
                    Report.Debug (DebugFlags.SSE, "{0} back in managed land #1: {1}", this, is_managed);

                    Queue<ManagedCallbackData> queue = process.MonoManager.ClearManagedCallbacks (inferior);
                    if (!OnManagedCallback (queue))
                        do_continue ();
                    return;
                }
            }

            // To step over a method call, the sse inserts a temporary
            // breakpoint immediately after the call instruction and then
            // resumes the target.
            //
            // If the target stops and we have such a temporary breakpoint, we
            // need to distinguish a few cases:
            //
            // a) we may have received a signal
            // b) we may have hit another breakpoint
            // c) we actually hit the temporary breakpoint
            //
            // In either case, we need to remove the temporary breakpoint if
            // the target is to remain stopped.  Note that this piece of code
            // here only deals with the temporary breakpoint, the handling of
            // a signal or another breakpoint is done later.
            if ((temp_breakpoint != null) &&
                (message == Inferior.ChildEventType.CHILD_HIT_BREAKPOINT) && (arg == temp_breakpoint.ID)) {
                // we hit the temporary breakpoint; this'll always
                // happen in the `correct' thread since the
                // `temp_breakpoint_id' is only set in this
                // SingleSteppingEngine and not in any other thread's.

                remove_temporary_breakpoint ();

                //
                // Lookup again using the current address since `arg' points to the hardware breakpoint,
                // but there may be a user breakpoint on the current instruction as well.
                //

                int idx;
                bool is_enabled;
                BreakpointHandle handle = process.BreakpointManager.LookupBreakpoint (
                    inferior.CurrentFrame, out idx, out is_enabled);

                Report.Debug (DebugFlags.SSE,
                          "{0} hit temporary breakpoint {1} at {2}: {3} {4} {5}",
                          this, arg, inferior.CurrentFrame, handle, idx, is_enabled);

                if ((handle == null) || !is_enabled || !handle.Breakpoint.Breaks (thread.ID) ||
                    handle.Breakpoint.HideFromUser) {
                    message = Inferior.ChildEventType.CHILD_STOPPED;
                    arg = 0;
                    cevent = new Inferior.ChildEvent (Inferior.ChildEventType.CHILD_STOPPED, 0, 0, 0);
                } else {
                    cevent = new Inferior.ChildEvent (Inferior.ChildEventType.CHILD_HIT_BREAKPOINT, idx, 0, 0);
                    ProcessOperationEvent (cevent);
                    return;
                }
            }

            if (message == Inferior.ChildEventType.UNHANDLED_EXCEPTION) {
                TargetAddress exc = new TargetAddress (manager.AddressDomain, cevent.Data1);
                TargetAddress ip = new TargetAddress (manager.AddressDomain, cevent.Data2);
                PushOperation (new OperationException (this, ip, exc, true));
                return;
            } else if (message == Inferior.ChildEventType.CHILD_HIT_BREAKPOINT) {
                // Ok, the next thing we need to check is whether this is actually "our"
                // breakpoint or whether it belongs to another thread.  In this case,
                // `step_over_breakpoint' does everything for us and we can just continue
                // execution.
                Breakpoint bpt;
                bool remain_stopped = child_breakpoint (cevent, arg, out bpt);
                if (!remain_stopped) {
                    do_continue ();
                    return;
                }
            }

            ProcessOperationEvent (cevent);
        }
SingleSteppingEngine