示例#1
0
        void DoAbortInvocation(long rti_id)
        {
            Report.Debug (DebugFlags.SSE, "{0} do abort invocation: {1}", this, rti_id);

            if (current_frame == null)
                throw new TargetException (TargetError.NoStack);

            process.UpdateSymbolTable (inferior);

            Inferior.CallbackFrame cframe = inferior.GetCallbackFrame (current_frame.StackPointer, false);

            bool found = false;
            foreach (OperationRuntimeInvoke rti in rti_stack) {
                if (rti.ID != rti_id)
                    continue;

                found = true;
                if (!rti.RequestAbort ())
                    throw new TargetException (TargetError.NoInvocation);
                break;
            }

            if (!found)
                throw new TargetException (TargetError.NoInvocation);

            if (cframe == null)
                throw new TargetException (TargetError.InvalidReturn, "No invocation found.");
            else if (cframe.ID != rti_id)
                throw new TargetException (TargetError.InvalidReturn,
                               "Requested to abort invocation {0}, but current invocation has id {1}.",
                               rti_id, cframe.ID);

            CommandResult result = new ThreadCommandResult (thread);

            if (MonoDebuggerInfo.HasAbortRuntimeInvoke) {
                PushOperation (new OperationAbortRuntimeInvoke (this, result));
                return;
            }

            Backtrace bt = new Backtrace (current_frame);

            bt.GetBacktrace (this, inferior, Backtrace.Mode.Native, cframe.StackPointer, -1);
            if (bt.Count < 2)
                throw new TargetException (TargetError.NoStack);

            //
            // Walk the stack and check whether we can abort this invocation.
            //

            bool stack_ok = true;

            for (int i = 0; i < bt.Count; i++) {
                StackFrame frame = bt.Frames [i];

                Report.Debug (DebugFlags.SSE, "{0} do abort invocation - frame {1} ({2}:{3}): {4}",
                          this, i, frame.Type, frame.IsManaged, frame);

                if ((frame.Type == FrameType.Normal) && frame.IsManaged) {
                    continue;
                } else if ((frame.Type == FrameType.RuntimeInvoke) && (i + 1 == bt.Count))
                    break;

                stack_ok = false;
                break;
            }

            if (!stack_ok)
                throw new TargetException (TargetError.InvalidReturn,
                               "Cannot abort an invocation which contains non-managed frames.");

            //
            // We're all set - the stack only contains managed frames, so we can go ahead here.
            //
            PushOperation (new OperationReturn (this, bt, ReturnMode.Invocation, result));
        }
示例#2
0
        public override CommandResult Return(ReturnMode mode)
        {
            return (CommandResult) SendCommand (delegate {
                if (!engine_stopped) {
                    Report.Debug (DebugFlags.Wait,
                              "{0} not stopped", this);
                    throw new TargetException (TargetError.NotStopped);
                }

                if (current_frame == null)
                    throw new TargetException (TargetError.NoStack);

                process.UpdateSymbolTable (inferior);

                if (!process.IsManagedApplication) {
                    if (mode == ReturnMode.Managed)
                        mode = ReturnMode.Native;
                    else if (mode == ReturnMode.Invocation)
                        throw new TargetException (TargetError.InvalidReturn, "Not a managed application.");
                }

                CommandResult result = new ThreadCommandResult (thread);

                Backtrace bt = new Backtrace (current_frame);

                if (mode == ReturnMode.Invocation) {
                    var cframe = inferior.GetCallbackFrame (current_frame.StackPointer, false);
                    if (cframe == null)
                        throw new TargetException (TargetError.NoInvocation);

                    if (MonoDebuggerInfo.HasAbortRuntimeInvoke) {
                        OperationRuntimeInvoke rti = rti_stack.Peek ();
                        if (rti.ID != cframe.ID)
                            throw new TargetException (TargetError.NoInvocation);

                        return StartOperation (new OperationAbortRuntimeInvoke (this, result));
                    }

                    bt.GetBacktrace (this, inferior, Backtrace.Mode.Native, cframe.StackPointer, -1);
                    for (int i = 0; i < bt.Count; i++) {
                        if ((bt.Frames [i].Type == FrameType.Normal) && bt.Frames [i].IsManaged)
                            continue;
                        else if ((bt.Frames [i].Type == FrameType.RuntimeInvoke) && (i + 1 == bt.Count))
                            break;
                        throw new TargetException (TargetError.InvalidReturn,
                                       "Cannot abort an invocation which contains non-managed frames.");
                    }
                } else {
                    bt.GetBacktrace (this, inferior, Backtrace.Mode.Native,
                             TargetAddress.Null, 2);
                }

                if (bt.Count < 2)
                    throw new TargetException (TargetError.NoStack);

                StackFrame parent_frame = bt.Frames [1];
                if (parent_frame == null)
                    return null;

                Report.Debug (DebugFlags.SSE, "{0} return: {1} {2} {3}", this, mode, current_frame.Type,
                          parent_frame.Type);

                if (mode == ReturnMode.Native) {
                    if ((current_frame.Type == FrameType.Signal) || (parent_frame.Type == FrameType.Signal) ||
                        (current_frame.Type == FrameType.Callback) || (parent_frame.Type == FrameType.Callback))
                        throw new TargetException (TargetError.InvalidReturn,
                                       "Cannot return from a signal handler or mdb-internal callback.");
                    if ((current_frame.Type != FrameType.Normal) || (parent_frame.Type != FrameType.Normal))
                        throw new TargetException (TargetError.InvalidReturn);
                } else if (mode == ReturnMode.Managed) {
                    bool ok = true;
                    if (current_frame.Type == FrameType.Normal) {
                        if (!current_frame.IsManaged)
                            ok = false;
                    } else {
                        if (current_frame.Type == FrameType.RuntimeInvoke)
                            throw new TargetException (TargetError.InvalidReturn,
                                           "Cannot return from an invocation.");
                        ok = false;
                    }

                    if (parent_frame.Type == FrameType.Normal) {
                        if (!parent_frame.IsManaged)
                            ok = false;
                    } else {
                        if (parent_frame.Type == FrameType.RuntimeInvoke)
                            throw new TargetException (TargetError.InvalidReturn,
                                           "Cannot return from an invocation.");
                        ok = false;
                    }

                    if (!ok)
                        throw new TargetException (TargetError.InvalidReturn,
                                       "Cannot return from a non-managed frame.");
                }

                if (mode == ReturnMode.Native) {
                    inferior.SetRegisters (parent_frame.Registers);
                    frame_changed (inferior.CurrentFrame, null);
                    TargetEventArgs args = new TargetEventArgs (
                        TargetEventType.TargetStopped, 0, current_frame);
                    process.Debugger.OnTargetEvent (thread, args);
                    return null;
                }

                return StartOperation (new OperationReturn (this, bt, mode, result));
            });
        }
示例#3
0
 internal override ThreadCommandResult Old_Step(StepMode mode, StepFrame frame)
 {
     ThreadCommandResult result = new ThreadCommandResult (thread);
     StartOperation (new OperationStep (this, mode, frame, result));
     return result;
 }