Skip to content
This repository has been archived by the owner on Feb 8, 2018. It is now read-only.

Commit

Permalink
Implement 'ReturnMode.Invocation' in SSE.Return().
Browse files Browse the repository at this point in the history
2009-05-19  Martin Baulig  <martin@ximian.com>

	* backend/Inferior.cs
	(Inferior.AbortInvoke): Only take `long rti_id' argument; we now
	abort one specific invocation and don't search on the stack.

	* backend/server/server.h
	(InferiorVTable.abort_invoke): Only take a `guint64 rti_id'
	argument, removed the `stack_pointer' and `*aborted_rti' ones.

	* backend/server/x86_64-arch.c
	(server_ptrace_abort_invoke): Only take a `guint64 rti_id'
	argument, removed the `stack_pointer' and `*aborted_rti' ones.

	* backend/server/i386-arch.c
	(server_ptrace_abort_invoke): Only take a `guint64 rti_id'
	argument, removed the `stack_pointer' and `*aborted_rti' ones.

	* backend/SingleSteppingEngine.cs
	(SSE.AbortRuntimeInvoke): Call `inferior.AbortInvoke()'.
	(SSE.Return): Implement `ReturnMode.Invocation'.
	(SSE.OperationReturn): Add support for aborting an entire
	invocation.

	* classes/Backtrace.cs
	(Backtrace.TryCallback): Take a `ref StackFrame last_frame'
	argument to allow the parent function to do some more checks on it
	before adding it.
	(Backtrace.TryUnwind): Improve handling of callback frames; also
	check `until'.

	* backend/ThreadServant.cs
	(ThreadServant.AbortInvocation): Removed.

	* classes/Thread.cs
	(Thread.AbortInvocation): Removed.

svn path=/branches/mono-2-4-1/debugger/; revision=134417
  • Loading branch information
Martin Baulig committed May 19, 2009
1 parent 4173de9 commit f6ff498
Show file tree
Hide file tree
Showing 11 changed files with 105 additions and 155 deletions.
37 changes: 37 additions & 0 deletions ChangeLog
@@ -1,3 +1,40 @@
2009-05-19 Martin Baulig <martin@ximian.com>

* backend/Inferior.cs
(Inferior.AbortInvoke): Only take `long rti_id' argument; we now
abort one specific invocation and don't search on the stack.

* backend/server/server.h
(InferiorVTable.abort_invoke): Only take a `guint64 rti_id'
argument, removed the `stack_pointer' and `*aborted_rti' ones.

* backend/server/x86_64-arch.c
(server_ptrace_abort_invoke): Only take a `guint64 rti_id'
argument, removed the `stack_pointer' and `*aborted_rti' ones.

* backend/server/i386-arch.c
(server_ptrace_abort_invoke): Only take a `guint64 rti_id'
argument, removed the `stack_pointer' and `*aborted_rti' ones.

* backend/SingleSteppingEngine.cs
(SSE.AbortRuntimeInvoke): Call `inferior.AbortInvoke()'.
(SSE.Return): Implement `ReturnMode.Invocation'.
(SSE.OperationReturn): Add support for aborting an entire
invocation.

* classes/Backtrace.cs
(Backtrace.TryCallback): Take a `ref StackFrame last_frame'
argument to allow the parent function to do some more checks on it
before adding it.
(Backtrace.TryUnwind): Improve handling of callback frames; also
check `until'.

* backend/ThreadServant.cs
(ThreadServant.AbortInvocation): Removed.

* classes/Thread.cs
(Thread.AbortInvocation): Removed.

2009-05-18 Martin Baulig <martin@ximian.com>

* classes/Thread.cs
Expand Down
10 changes: 3 additions & 7 deletions backend/Inferior.cs
Expand Up @@ -116,7 +116,7 @@ internal class Inferior : TargetAccess, ITargetNotification, IDisposable
static extern TargetError mono_debugger_server_mark_rti_frame (IntPtr handle);

[DllImport("monodebuggerserver")]
static extern TargetError mono_debugger_server_abort_invoke (IntPtr handle, long stack_pointer, out long aborted_rti);
static extern TargetError mono_debugger_server_abort_invoke (IntPtr handle, long rti_id);

[DllImport("monodebuggerserver")]
static extern TargetError mono_debugger_server_call_method_invoke (IntPtr handle, long invoke_method, long method_address, int num_params, int blob_size, IntPtr param_data, IntPtr offset_data, IntPtr blob_data, long callback_argument, bool debug);
Expand Down Expand Up @@ -510,14 +510,10 @@ public void MarkRuntimeInvokeFrame ()
check_error (mono_debugger_server_mark_rti_frame (server_handle));
}

public bool AbortInvoke (TargetAddress stack_pointer, out long aborted_rti)
public void AbortInvoke (long rti_id)
{
TargetError result = mono_debugger_server_abort_invoke (
server_handle, stack_pointer.Address, out aborted_rti);
if (result == TargetError.NoCallbackFrame)
return false;
TargetError result = mono_debugger_server_abort_invoke (server_handle, rti_id);
check_error (result);
return true;
}

public int InsertBreakpoint (TargetAddress address)
Expand Down
116 changes: 36 additions & 80 deletions backend/SingleSteppingEngine.cs
Expand Up @@ -516,6 +516,8 @@ void AbortRuntimeInvoke (long rti_id)
if (rti.ID != rti_id)
throw new InternalError ("{0} aborting rti failed: {1} {2}", this, rti.ID, rti_id);

inferior.AbortInvoke (rti_id);

if (rti.IsSuspended) {
InterruptibleOperation io = nested_break_stack.Pop ();
if (io != rti)
Expand Down Expand Up @@ -1759,12 +1761,31 @@ public override CommandResult Return (ReturnMode mode)

process.UpdateSymbolTable (inferior);

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

Backtrace bt = new Backtrace (current_frame);
bt.GetBacktrace (this, inferior, Backtrace.Mode.Native,
TargetAddress.Null, 2);

if (mode == ReturnMode.Invocation) {
Inferior.CallbackFrame cframe = inferior.GetCallbackFrame (current_frame.StackPointer, false);
if (cframe == null)
throw new TargetException (TargetError.InvalidReturn, "No invocation found.");
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)
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);
Expand Down Expand Up @@ -1803,40 +1824,10 @@ public override CommandResult Return (ReturnMode mode)
return null;
}

#if FIXME
if (!process.IsManagedApplication || (mode == ReturnMode.Native) || (mode == ReturnMode.ForceNative)) {
long aborted_rti;
inferior.AbortInvoke (parent_frame.StackPointer, out aborted_rti);
if (aborted_rti != 0)
AbortRuntimeInvoke (aborted_rti);
inferior.SetRegisters (parent_frame.Registers);
frame_changed (inferior.CurrentFrame, null);
TargetEventArgs args = new TargetEventArgs (
TargetEventType.TargetStopped, 0, current_frame);
process.OnTargetEvent (this, args);
return null;
}
#endif

return StartOperation (new OperationReturn (this, bt, mode));
});
}

public override CommandResult AbortInvocation ()
{
return (CommandResult) SendCommand (delegate {
GetBacktrace (Backtrace.Mode.Native, -1);
if (current_backtrace == null)
throw new TargetException (TargetError.NoStack);

if (!process.IsManagedApplication)
throw new InvalidOperationException ();

return StartOperation (new OperationAbortInvocation (
this, current_backtrace));
});
}

public override Backtrace GetBacktrace (Backtrace.Mode mode, int max_frames)
{
return (Backtrace) SendCommand (delegate {
Expand Down Expand Up @@ -4638,6 +4629,7 @@ protected class OperationReturn : OperationCallback
{
public readonly Backtrace Backtrace;
public readonly ReturnMode Mode;
int level = 0;

public OperationReturn (SingleSteppingEngine sse, Backtrace bt, ReturnMode mode)
: base (sse)
Expand All @@ -4648,67 +4640,31 @@ public OperationReturn (SingleSteppingEngine sse, Backtrace bt, ReturnMode mode)

protected override void DoExecute ()
{
Report.Debug (DebugFlags.SSE, "{0} executing return: {1}\n{2}", sse, Mode, Backtrace.Print ());
Report.Debug (DebugFlags.SSE, "{0} executing return: {1} {2}\n{2}", sse, Mode, level, Backtrace.Print ());
inferior.CallMethod (sse.MonoDebuggerInfo.RunFinally, null, ID);
}

protected override EventResult CallbackCompleted (long data1, long data2)
{
DiscardStack ();

StackFrame parent_frame = Backtrace.Frames [1];
StackFrame parent_frame = Backtrace.Frames [++level];
inferior.SetRegisters (parent_frame.Registers);

Inferior.CallbackFrame cframe = inferior.GetCallbackFrame (parent_frame.StackPointer, true);
if (cframe == null) {
Report.Debug (DebugFlags.SSE, "{0} completed return", sse);
inferior.SetRegisters (parent_frame.Registers);
Report.Debug (DebugFlags.SSE, "{0} return: {1} {2}\n{3}", sse, level, cframe, parent_frame);
if (cframe != null) {
Report.Debug (DebugFlags.SSE, "{0} return aborting rti: {1}", sse, cframe);
sse.AbortRuntimeInvoke (cframe.ID);
return EventResult.Completed;
}

long aborted_rti;
bool aborted = inferior.AbortInvoke (parent_frame.StackPointer, out aborted_rti);
Report.Debug (DebugFlags.SSE, "{0} completed return: {1} {2} {3}", sse, cframe, aborted, aborted_rti != null);
inferior.SetRegisters (parent_frame.Registers);

if (aborted_rti != 0)
sse.AbortRuntimeInvoke (aborted_rti);

return EventResult.Completed;
}
}

protected class OperationAbortInvocation : OperationCallback
{
public readonly Backtrace Backtrace;
int level = 0;

public OperationAbortInvocation (SingleSteppingEngine sse, Backtrace backtrace)
: base (sse)
{
this.Backtrace = backtrace;
}

protected override void DoExecute ()
{
inferior.CallMethod (sse.MonoDebuggerInfo.RunFinally, null, ID);
}

protected override EventResult CallbackCompleted (long data1, long data2)
{
Report.Debug (DebugFlags.SSE, "{0} callback completed", this);

StackFrame parent_frame = Backtrace.Frames [++level];

long aborted_rti;
if (inferior.AbortInvoke (parent_frame.StackPointer, out aborted_rti)) {
DiscardStack ();
if (aborted_rti != 0)
sse.AbortRuntimeInvoke (aborted_rti);
if (level == Backtrace.Count) {
Report.Debug (DebugFlags.SSE, "{0} completed return", sse);
return EventResult.Completed;
}

inferior.SetRegisters (parent_frame.Registers);
inferior.CallMethod (sse.MonoDebuggerInfo.RunFinally, null, ID);
DoExecute ();
return EventResult.Running;
}
}
Expand Down
2 changes: 0 additions & 2 deletions backend/ThreadServant.cs
Expand Up @@ -247,8 +247,6 @@ internal void SetDaemon ()

public abstract CommandResult Return (ReturnMode mode);

public abstract CommandResult AbortInvocation ();

public string PrintRegisters (StackFrame frame)
{
return Architecture.PrintRegisters (frame);
Expand Down
5 changes: 0 additions & 5 deletions backend/arch/CoreFile.cs
Expand Up @@ -611,11 +611,6 @@ public override CommandResult Return (ReturnMode mode)
throw new InvalidOperationException ();
}

public override CommandResult AbortInvocation ()
{
throw new InvalidOperationException ();
}

protected class CoreFileTargetAccess : TargetMemoryAccess
{
public readonly CoreFileThread Thread;
Expand Down
16 changes: 2 additions & 14 deletions backend/server/i386-arch.c
Expand Up @@ -1228,24 +1228,12 @@ server_ptrace_mark_rti_frame (ServerHandle *handle)
}

static ServerCommandError
server_ptrace_abort_invoke (ServerHandle *handle, guint64 stack_pointer, guint64 *aborted_rti)
server_ptrace_abort_invoke (ServerHandle *handle, guint64 rti_id)
{
CallbackData *cdata;

cdata = get_callback_data (handle->arch);
if (!cdata) {
*aborted_rti = 0;
return COMMAND_ERROR_NO_CALLBACK_FRAME;
}

if (cdata->is_rti)
*aborted_rti = cdata->callback_argument;
else
*aborted_rti = 0;

if (cdata->rti_frame && (stack_pointer < cdata->rti_frame))
return COMMAND_ERROR_NO_CALLBACK_FRAME;
if (stack_pointer < cdata->stack_pointer)
if (!cdata || !cdata->is_rti || (cdata->callback_argument != rti_id))
return COMMAND_ERROR_NO_CALLBACK_FRAME;

if (_server_ptrace_set_registers (handle->inferior, &cdata->saved_regs) != COMMAND_ERROR_NONE)
Expand Down
4 changes: 2 additions & 2 deletions backend/server/library.c
Expand Up @@ -302,12 +302,12 @@ mono_debugger_server_mark_rti_frame (ServerHandle *handle)
}

ServerCommandError
mono_debugger_server_abort_invoke (ServerHandle *handle, guint64 stack_pointer, guint64 *aborted_rti)
mono_debugger_server_abort_invoke (ServerHandle *handle, guint64 rti_id)
{
if (!global_vtable->abort_invoke)
return COMMAND_ERROR_NOT_IMPLEMENTED;

return (* global_vtable->abort_invoke) (handle, stack_pointer, aborted_rti);
return (* global_vtable->abort_invoke) (handle, rti_id);
}

ServerCommandError
Expand Down
6 changes: 2 additions & 4 deletions backend/server/server.h
Expand Up @@ -305,8 +305,7 @@ struct InferiorVTable {
ServerCommandError (* mark_rti_frame) (ServerHandle *handle);

ServerCommandError (* abort_invoke) (ServerHandle *handle,
guint64 stack_pointer,
guint64 *aborted_rti);
guint64 rti_id);

/*
* Insert a breakpoint at address `address' in the target's address space.
Expand Down Expand Up @@ -569,8 +568,7 @@ mono_debugger_mark_rti_framenvoke (ServerHandle *handle);

ServerCommandError
mono_debugger_server_abort_invoke (ServerHandle *handle,
guint64 stack_pointer,
guint64 *aborted_rti);
guint64 rti_id);

ServerCommandError
mono_debugger_server_insert_breakpoint (ServerHandle *handle,
Expand Down
16 changes: 2 additions & 14 deletions backend/server/x86_64-arch.c
Expand Up @@ -1277,24 +1277,12 @@ server_ptrace_mark_rti_frame (ServerHandle *handle)
}

static ServerCommandError
server_ptrace_abort_invoke (ServerHandle *handle, guint64 stack_pointer, guint64 *aborted_rti)
server_ptrace_abort_invoke (ServerHandle *handle, guint64 rti_id)
{
CallbackData *cdata;

cdata = get_callback_data (handle->arch);
if (!cdata) {
*aborted_rti = 0;
return COMMAND_ERROR_NO_CALLBACK_FRAME;
}

if (cdata->is_rti)
*aborted_rti = cdata->callback_argument;
else
*aborted_rti = 0;

if (cdata->rti_frame && (stack_pointer < cdata->rti_frame))
return COMMAND_ERROR_NO_CALLBACK_FRAME;
if (stack_pointer < cdata->stack_pointer)
if (!cdata || !cdata->is_rti || (cdata->callback_argument != rti_id))
return COMMAND_ERROR_NO_CALLBACK_FRAME;

if (_server_ptrace_set_registers (handle->inferior, &cdata->saved_regs) != COMMAND_ERROR_NONE)
Expand Down

0 comments on commit f6ff498

Please sign in to comment.