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)); }
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)); }); }
internal override ThreadCommandResult Old_Step(StepMode mode, StepFrame frame) { ThreadCommandResult result = new ThreadCommandResult (thread); StartOperation (new OperationStep (this, mode, frame, result)); return result; }