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

Commit

Permalink
Browse files Browse the repository at this point in the history
**** Backport of 139425 ****
2009-08-05  Martin Baulig  <martin@ximian.com>

	**** Backport of 139425 ****

	Support removing breakpoints while the target is running.

	* backend/ProcessServant.cs
	(ProcessServant.ExceptionCatchPoints): Removed; the session now
	maintains exception catchpoints.

	* backend/SingleSteppingEngine.cs
	(SSE.ActivatePendingBreakpoints): We now also handle removals.
	(SSE.OperationRemoveBreakpoint): New operation to remove a managed
	breakpoint.

	* classes/Breakpoint.cs
	(Breakpoint.NeedsActivation): New public property; event handlers
	don't need any activation.

	* classes/DebuggerSession.cs
	(DebuggerSession.InsertExceptionCatchPoint): Exception catchpoints
	don't need to be activated.
	(DebuggerSession.ExceptionCatchPoints): The session now maintains
	all exception catchpoints; moved here from `ProcessServant'.
	(DebuggerSession.RemoveBreakpoint): Immediately remove the
	breakpoint from our list, but don't actually delete it - the
	target doesn't need to be stopped to call this method, the method
	is queued for removal during Process.ActivatePendingBreakpoints().

	* classes/Process.cs
	(Process.ActivatePendingBreakpoints): Don't block, return a
	`CommandResult' you can wait on.

svn path=/branches/mono-2-4-2/debugger/; revision=139440
  • Loading branch information
Martin Baulig committed Aug 5, 2009
1 parent dd54c5d commit 5a99cec
Show file tree
Hide file tree
Showing 12 changed files with 444 additions and 217 deletions.
34 changes: 34 additions & 0 deletions ChangeLog
@@ -1,3 +1,37 @@
**** Backport of 139425 ****
2009-08-05 Martin Baulig <martin@ximian.com>

**** Backport of 139425 ****

Support removing breakpoints while the target is running.

* backend/ProcessServant.cs
(ProcessServant.ExceptionCatchPoints): Removed; the session now
maintains exception catchpoints.

* backend/SingleSteppingEngine.cs
(SSE.ActivatePendingBreakpoints): We now also handle removals.
(SSE.OperationRemoveBreakpoint): New operation to remove a managed
breakpoint.

* classes/Breakpoint.cs
(Breakpoint.NeedsActivation): New public property; event handlers
don't need any activation.

* classes/DebuggerSession.cs
(DebuggerSession.InsertExceptionCatchPoint): Exception catchpoints
don't need to be activated.
(DebuggerSession.ExceptionCatchPoints): The session now maintains
all exception catchpoints; moved here from `ProcessServant'.
(DebuggerSession.RemoveBreakpoint): Immediately remove the
breakpoint from our list, but don't actually delete it - the
target doesn't need to be stopped to call this method, the method
is queued for removal during Process.ActivatePendingBreakpoints().

* classes/Process.cs
(Process.ActivatePendingBreakpoints): Don't block, return a
`CommandResult' you can wait on.

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

**** Backport of 139424 ****
Expand Down
45 changes: 36 additions & 9 deletions backend/BreakpointHandle.cs
@@ -1,10 +1,25 @@
using System;
using System.Collections.Generic;
using Mono.Debugger.Languages;
using Mono.Debugger.Languages.Mono;

namespace Mono.Debugger.Backend
{
internal class PendingBreakpointQueue : Queue<KeyValuePair<FunctionBreakpointHandle,BreakpointHandle.Action>>
{
public void Add (FunctionBreakpointHandle handle, BreakpointHandle.Action action)
{
Enqueue (new KeyValuePair<FunctionBreakpointHandle, BreakpointHandle.Action> (handle, action));
}
}

internal abstract class BreakpointHandle : DebuggerMarshalByRefObject
{
internal enum Action {
Insert,
Remove
}

public readonly Breakpoint Breakpoint;

protected BreakpointHandle (Breakpoint breakpoint)
Expand All @@ -14,6 +29,8 @@ protected BreakpointHandle (Breakpoint breakpoint)

public abstract void Insert (Inferior target);

public abstract void Remove (Inferior target);

public abstract void Insert (Thread target);

public abstract void Remove (Thread target);
Expand All @@ -39,6 +56,13 @@ public override void Insert (Thread target)
throw new InternalError ();
}

public override void Remove (Inferior target)
{
if (index > 0)
target.RemoveBreakpoint (this);
index = -1;
}

public override void Remove (Thread target)
{
if (index > 0)
Expand Down Expand Up @@ -77,7 +101,7 @@ public override void Insert (Inferior inferior)
has_breakpoint = true;
}

internal void Remove (Inferior inferior)
public override void Remove (Inferior inferior)
{
if (has_breakpoint)
inferior.RemoveBreakpoint (this);
Expand All @@ -91,6 +115,10 @@ internal class FunctionBreakpointHandle : BreakpointHandle
bool has_load_handler;
int line = -1, column;

internal int Index {
get; private set;
}

public FunctionBreakpointHandle (Breakpoint bpt, TargetFunctionType function, int line)
: this (bpt, function, line, -1)
{ }
Expand All @@ -102,20 +130,14 @@ public FunctionBreakpointHandle (Breakpoint bpt, TargetFunctionType function, in
this.function = function;
this.line = line;
this.column = column;

this.Index = MonoLanguageBackend.GetUniqueID ();
}

internal TargetFunctionType Function {
get { return function; }
}

internal bool Insert (SingleSteppingEngine sse)
{
if (has_load_handler)
return false;

throw new InternalError ();
}

public override void Insert (Inferior target)
{
throw new InternalError ();
Expand Down Expand Up @@ -153,6 +175,11 @@ internal void MethodLoaded (TargetAccess target, Method method)
}
}

public override void Remove (Inferior target)
{
throw new InternalError ();
}

public override void Remove (Thread target)
{
target.RemoveBreakpoint (this);
Expand Down
2 changes: 1 addition & 1 deletion backend/MonoThreadManager.cs
Expand Up @@ -313,7 +313,7 @@ internal void ThreadCreated (SingleSteppingEngine sse)
Inferior.StackFrame iframe = inferior.GetCurrentFrame (false);
engine.SetMainReturnAddress (iframe.StackPointer);
engine.ProcessServant.OnProcessReachedMainEvent ();
resume_target = !engine.OnModuleLoaded (null);
resume_target = !engine.InitializeBreakpoints ();
return true;
}

Expand Down
140 changes: 54 additions & 86 deletions backend/SingleSteppingEngine.cs
Expand Up @@ -394,7 +394,7 @@ public void ProcessEvent (Inferior.ChildEvent cevent)
Report.Error ("{0} got {1} at {2} while executing {2}", this, message,
inferior.CurrentFrame, current_operation);
OperationCompleted (new TargetEventArgs (TargetEventType.TargetSignaled, -1));
return true;
return;

case Inferior.ChildEventType.CHILD_EXITED:
OperationCompleted (new TargetEventArgs (TargetEventType.TargetExited, arg));
Expand Down Expand Up @@ -1573,86 +1573,20 @@ internal override void ReleaseThreadLockDone ()
ExecuteOperation (current_operation);
}

internal bool InitializeBreakpoints ()
{
return ActivatePendingBreakpoints (null);
}

internal bool OnModuleLoaded (Module module)
{
return ActivatePendingBreakpoints (module);
}

internal bool ActivatePendingBreakpoints (Module module)
{
Inferior.StackFrame iframe = inferior.GetCurrentFrame ();
Registers registers = inferior.GetRegisters ();

StackFrame main_frame;
if (process.MonoManager != null) {
MonoLanguageBackend mono = process.MonoLanguage;

MonoFunctionType main = mono.MainMethod;

MethodSource source = main.SymbolFile.GetMethodByToken (main.Token);
if (source != null) {
SourceLocation location = new SourceLocation (source);

main_frame = new StackFrame (
thread, FrameType.Normal, iframe.Address, iframe.StackPointer,
iframe.FrameAddress, registers, main, location);
} else {
main_frame = new StackFrame (
thread, FrameType.Normal, iframe.Address, iframe.StackPointer,
iframe.FrameAddress, registers);
}
update_current_frame (main_frame);
} else {
Method method = Lookup (inferior.MainMethodAddress);

if (method == null)
return false;

main_frame = new StackFrame (
thread, FrameType.Normal, iframe.Address, iframe.StackPointer,
iframe.FrameAddress, registers, method);
update_current_frame (main_frame);
}

Report.Debug (DebugFlags.SSE, "{0} activate pending breakpoints", this);

Queue pending = new Queue ();
foreach (Event e in process.Session.Events) {
Breakpoint breakpoint = e as Breakpoint;
if (breakpoint == null)
continue;

if (!e.IsEnabled || e.IsActivated)
continue;

if (e.IsUserModule && (module != null) && (module.ModuleGroup.Name != "user"))
continue;

try {
BreakpointHandle handle = breakpoint.Resolve (thread, main_frame);
if (handle == null)
continue;

FunctionBreakpointHandle fh = handle as FunctionBreakpointHandle;
if (fh == null) {
handle.Insert (thread);
continue;
}

pending.Enqueue (fh);
} catch (TargetException ex) {
if (ex.Type == TargetError.LocationInvalid)
breakpoint.OnResolveFailed ();
else
breakpoint.OnBreakpointError (
"Cannot insert breakpoint {0}: {1}", e.Index, ex.Message);
} catch (Exception ex) {
breakpoint.OnBreakpointError (
"Cannot insert breakpoint {0}: {1}", e.Index, ex.Message);
}
}

if (pending.Count == 0)
var pending = process.Session.GetPendingBreakpoints (this, module);
if ((pending == null) || (pending.Count == 0))
return false;

PushOperation (new OperationActivateBreakpoints (this, pending));
Expand Down Expand Up @@ -2748,7 +2682,7 @@ protected override void DoExecute ()
}

if (!sse.ProcessServant.IsManaged) {
if (sse.OnModuleLoaded (null))
if (sse.InitializeBreakpoints ())
return EventResult.Running;
}

Expand All @@ -2767,7 +2701,7 @@ public override bool HandleException (TargetAddress stack, TargetAddress exc)

protected class OperationActivateBreakpoints : Operation
{
public OperationActivateBreakpoints (SingleSteppingEngine sse, Queue pending)
public OperationActivateBreakpoints (SingleSteppingEngine sse, PendingBreakpointQueue pending)
: base (sse, null)
{
this.pending_events = pending;
Expand All @@ -2782,7 +2716,7 @@ protected override void DoExecute ()
get { return false; }
}

Queue pending_events;
PendingBreakpointQueue pending_events;
bool completed;

protected override EventResult DoProcessEvent (Inferior.ChildEvent cevent,
Expand Down Expand Up @@ -2819,28 +2753,31 @@ bool do_execute ()
return false;
}

FunctionBreakpointHandle handle =
(FunctionBreakpointHandle) pending_events.Dequeue ();
var entry = pending_events.Dequeue ();

BreakpointHandle.Action action = entry.Value;
FunctionBreakpointHandle handle = entry.Key;

Report.Debug (DebugFlags.SSE,
"{0} activate breakpoints: {1}", sse, handle);
"{0} activate breakpoints: {1} {2}", sse, action, handle);

sse.PushOperation (new OperationInsertBreakpoint (sse, handle));
if (action == BreakpointHandle.Action.Insert)
sse.PushOperation (new OperationInsertBreakpoint (sse, handle));
else
sse.PushOperation (new OperationRemoveBreakpoint (sse, handle));
return true;
}
}

protected class OperationInsertBreakpoint : OperationCallback
{
public readonly FunctionBreakpointHandle Handle;
public readonly int Index;

public OperationInsertBreakpoint (SingleSteppingEngine sse,
FunctionBreakpointHandle handle)
: base (sse, null)
{
this.Handle = handle;
this.Index = MonoLanguageBackend.GetUniqueID ();
}

protected override void DoExecute ()
Expand All @@ -2852,11 +2789,11 @@ protected override void DoExecute ()

Report.Debug (DebugFlags.SSE,
"{0} insert breakpoint: {1} {2} {3:x}",
sse, func, Index, func.Token);
sse, func, Handle.Index, func.Token);

inferior.CallMethod (
info.InsertSourceBreakpoint, image.Address,
func.Token, Index, func.DeclaringType.BaseName, ID);
func.Token, Handle.Index, func.DeclaringType.BaseName, ID);
}

protected override EventResult CallbackCompleted (long data1, long data2)
Expand All @@ -2865,7 +2802,7 @@ protected override EventResult CallbackCompleted (long data1, long data2)

Report.Debug (DebugFlags.SSE, "{0} insert breakpoint done: {1}", sse, info);

sse.Process.MonoLanguage.RegisterMethodLoadHandler (inferior, info, Index, Handle.MethodLoaded);
sse.Process.MonoLanguage.RegisterMethodLoadHandler (inferior, info, Handle.Index, Handle.MethodLoaded);

Handle.Breakpoint.OnBreakpointBound ();
return EventResult.AskParent;
Expand Down Expand Up @@ -2897,6 +2834,37 @@ protected override void DoExecute ()
}
}

protected class OperationRemoveBreakpoint : OperationCallback
{
public readonly FunctionBreakpointHandle Handle;
public readonly int Index;

public OperationRemoveBreakpoint (SingleSteppingEngine sse,
FunctionBreakpointHandle handle)
: base (sse, null)
{
this.Handle = handle;
this.Index = MonoLanguageBackend.GetUniqueID ();
}

protected override void DoExecute ()
{
MonoDebuggerInfo info = sse.ProcessServant.MonoManager.MonoDebuggerInfo;

Report.Debug (DebugFlags.SSE,
"{0} remove breakpoint: {1} {2}", sse, Handle, Handle.Index);

sse.Process.MonoLanguage.RemoveMethodLoadHandler (Handle.Index);
inferior.BreakpointManager.RemoveBreakpoint (inferior, Handle);
inferior.CallMethod (info.RemoveBreakpoint, Handle.Index, 0, ID);
}

protected override EventResult CallbackCompleted (long data1, long data2)
{
return EventResult.AskParent;
}
}

protected class OperationInitAfterFork : Operation
{
public OperationInitAfterFork (SingleSteppingEngine sse)
Expand Down
4 changes: 4 additions & 0 deletions classes/Breakpoint.cs
Expand Up @@ -19,6 +19,10 @@ public abstract class Breakpoint : Event
{
internal abstract BreakpointHandle Resolve (Thread target, StackFrame frame);

public override bool NeedsActivation {
get { return true; }
}

public virtual bool HideFromUser {
get { return false; }
}
Expand Down

0 comments on commit 5a99cec

Please sign in to comment.