diff options
author | Zoltan Varga <vargaz@gmail.com> | 2010-06-17 23:41:43 +0400 |
---|---|---|
committer | Zoltan Varga <vargaz@gmail.com> | 2010-06-17 23:41:43 +0400 |
commit | 9db915cfa56ca726f701a0bc67d3ec96948cba74 (patch) | |
tree | 94f6f2e9ff403b37b95c8487d5f2c6729150116b /mcs/class | |
parent | 369fb5ad04378842f57272438f4d22e6467dea88 (diff) |
2010-06-17 Zoltan Varga <vargaz@gmail.com>
* VirtualMachine.cs Connection.cs: Group events received together into an EventSet,
like it is done in JDI. Add a GetNextEventSet () method.
svn path=/branches/mono-2-6/mcs/; revision=159087
Diffstat (limited to 'mcs/class')
7 files changed, 234 insertions, 108 deletions
diff --git a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft.dll.sources b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft.dll.sources index 796f4a77031..df6a6901b41 100644 --- a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft.dll.sources +++ b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft.dll.sources @@ -35,6 +35,7 @@ Mono.Debugger.Soft/MethodEntryEventRequest.cs Mono.Debugger.Soft/LocalVariable.cs Mono.Debugger.Soft/ParameterInfoMirror.cs Mono.Debugger.Soft/Event.cs +Mono.Debugger.Soft/EventSet.cs Mono.Debugger.Soft/AppDomainCreateEvent.cs Mono.Debugger.Soft/ThreadDeathEvent.cs Mono.Debugger.Soft/SuspendPolicy.cs diff --git a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/ChangeLog b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/ChangeLog index c1788fd81c1..7fc9d2675f8 100644 --- a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/ChangeLog +++ b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/ChangeLog @@ -1,3 +1,8 @@ +2010-06-17 Zoltan Varga <vargaz@gmail.com> + + * VirtualMachine.cs Connection.cs: Group events received together into an EventSet, + like it is done in JDI. Add a GetNextEventSet () method. + 2010-06-04 Zoltan Varga <vargaz@gmail.com> * StackFrame.cs (GetVisibleVariables): New method to return the set of variables diff --git a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/Connection.cs b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/Connection.cs index c696c9129b7..c6c378fb865 100644 --- a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/Connection.cs +++ b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/Connection.cs @@ -193,6 +193,37 @@ namespace Mono.Debugger.Soft } } + class EventInfo { + public EventType EventType { + get; set; + } + + public int ReqId { + get; set; + } + + public SuspendPolicy SuspendPolicy { + get; set; + } + + public long ThreadId { + get; set; + } + + public long Id { + get; set; + } + + public long Location { + get; set; + } + + public EventInfo (EventType type, int req_id) { + EventType = type; + ReqId = req_id; + } + } + public enum ErrorCode { NONE = 0, INVALID_OBJECT = 20, @@ -979,71 +1010,93 @@ namespace Mono.Debugger.Soft PacketReader r = new PacketReader (packet); if (r.CommandSet == CommandSet.EVENT && r.Command == (int)CmdEvent.COMPOSITE) { - r.ReadByte (); // suspend_policy + int spolicy = r.ReadByte (); int nevents = r.ReadInt (); + SuspendPolicy suspend_policy = decode_suspend_policy (spolicy); + + EventInfo[] events = new EventInfo [nevents]; + for (int i = 0; i < nevents; ++i) { EventKind kind = (EventKind)r.ReadByte (); int req_id = r.ReadInt (); + EventType etype = (EventType)kind; + if (kind == EventKind.VM_START) { long thread_id = r.ReadId (); - EventHandler.VMStart (req_id, thread_id, null); + events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id }; + //EventHandler.VMStart (req_id, thread_id, null); } else if (kind == EventKind.VM_DEATH) { - EventHandler.VMDeath (req_id, 0, null); + //EventHandler.VMDeath (req_id, 0, null); + events [i] = new EventInfo (etype, req_id) { }; } else if (kind == EventKind.THREAD_START) { long thread_id = r.ReadId (); - EventHandler.ThreadStart (req_id, thread_id, thread_id); + events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = thread_id }; + //EventHandler.ThreadStart (req_id, thread_id, thread_id); } else if (kind == EventKind.THREAD_DEATH) { long thread_id = r.ReadId (); - EventHandler.ThreadDeath (req_id, thread_id, thread_id); + events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = thread_id }; + //EventHandler.ThreadDeath (req_id, thread_id, thread_id); } else if (kind == EventKind.ASSEMBLY_LOAD) { long thread_id = r.ReadId (); long id = r.ReadId (); - EventHandler.AssemblyLoad (req_id, thread_id, id); + events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id }; + //EventHandler.AssemblyLoad (req_id, thread_id, id); } else if (kind == EventKind.ASSEMBLY_UNLOAD) { long thread_id = r.ReadId (); long id = r.ReadId (); - EventHandler.AssemblyUnload (req_id, thread_id, id); + events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id }; + //EventHandler.AssemblyUnload (req_id, thread_id, id); } else if (kind == EventKind.TYPE_LOAD) { long thread_id = r.ReadId (); long id = r.ReadId (); - EventHandler.TypeLoad (req_id, thread_id, id); + events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id }; + //EventHandler.TypeLoad (req_id, thread_id, id); } else if (kind == EventKind.METHOD_ENTRY) { long thread_id = r.ReadId (); long id = r.ReadId (); - EventHandler.MethodEntry (req_id, thread_id, id); + events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id }; + //EventHandler.MethodEntry (req_id, thread_id, id); } else if (kind == EventKind.METHOD_EXIT) { long thread_id = r.ReadId (); long id = r.ReadId (); - EventHandler.MethodExit (req_id, thread_id, id); + events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id }; + //EventHandler.MethodExit (req_id, thread_id, id); } else if (kind == EventKind.BREAKPOINT) { long thread_id = r.ReadId (); long id = r.ReadId (); long loc = r.ReadLong (); - EventHandler.Breakpoint (req_id, thread_id, id, loc); + events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id, Location = loc }; + //EventHandler.Breakpoint (req_id, thread_id, id, loc); } else if (kind == EventKind.STEP) { long thread_id = r.ReadId (); long id = r.ReadId (); long loc = r.ReadLong (); - EventHandler.Step (req_id, thread_id, id, loc); + events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id, Location = loc }; + //EventHandler.Step (req_id, thread_id, id, loc); } else if (kind == EventKind.EXCEPTION) { long thread_id = r.ReadId (); long id = r.ReadId (); long loc = 0; // FIXME - EventHandler.Exception (req_id, thread_id, id, loc); + events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id, Location = loc }; + //EventHandler.Exception (req_id, thread_id, id, loc); } else if (kind == EventKind.APPDOMAIN_CREATE) { long thread_id = r.ReadId (); long id = r.ReadId (); - EventHandler.AppDomainCreate (req_id, thread_id, id); + events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id }; + //EventHandler.AppDomainCreate (req_id, thread_id, id); } else if (kind == EventKind.APPDOMAIN_UNLOAD) { long thread_id = r.ReadId (); long id = r.ReadId (); - EventHandler.AppDomainUnload (req_id, thread_id, id); + events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id }; + //EventHandler.AppDomainUnload (req_id, thread_id, id); } else { throw new NotImplementedException ("Unknown event kind: " + kind); } } + + EventHandler.Events (suspend_policy, events); } } @@ -1760,34 +1813,8 @@ namespace Mono.Debugger.Soft /* This is the interface exposed by the debugger towards the debugger agent */ interface IEventHandler { - void VMStart (int req_id, long thread_id, string vm_uri); - - void VMDeath (int req_id, long thread_id, string vm_uri); + void Events (SuspendPolicy suspend_policy, EventInfo[] events); void VMDisconnect (int req_id, long thread_id, string vm_uri); - - void ThreadStart (int req_id, long thread_id, long id); - - void ThreadDeath (int req_id, long thread_id, long id); - - void AssemblyLoad (int req_id, long thread_id, long id); - - void AssemblyUnload (int req_id, long thread_id, long id); - - void TypeLoad (int req_id, long thread_id, long id); - - void MethodEntry (int req_id, long thread_id, long id); - - void MethodExit (int req_id, long thread_id, long id); - - void Breakpoint (int req_id, long thread_id, long method_id, long loc); - - void Step (int req_id, long thread_id, long method_id, long loc); - - void Exception (int req_id, long thread_id, long exc_id, long loc); - - void AppDomainCreate (int req_id, long thread_id, long id); - - void AppDomainUnload (int req_id, long thread_id, long id); } } diff --git a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/EventSet.cs b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/EventSet.cs new file mode 100644 index 00000000000..cc83be595f2 --- /dev/null +++ b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/EventSet.cs @@ -0,0 +1,34 @@ +using System; + +namespace Mono.Debugger.Soft +{ + public class EventSet { + protected VirtualMachine vm; + SuspendPolicy suspend_policy; + Event[] events; + + internal EventSet (VirtualMachine vm, SuspendPolicy suspend_policy, Event[] events) { + this.vm = vm; + this.suspend_policy = suspend_policy; + this.events = events; + } + + public SuspendPolicy SuspendPolicy { + get { + return suspend_policy; + } + } + + public Event[] Events { + get { + return events; + } + } + + public Event this [int index] { + get { + return Events [index]; + } + } + } +} diff --git a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/VirtualMachine.cs b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/VirtualMachine.cs index 389c03d88d9..0571fa249b7 100644 --- a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/VirtualMachine.cs +++ b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/VirtualMachine.cs @@ -71,11 +71,18 @@ namespace Mono.Debugger.Soft } } + EventSet current_es; + int current_es_index; + public Event GetNextEvent () { lock (queue_monitor) { - if (queue.Count == 0) - Monitor.Wait (queue_monitor); - return (Event)queue.Dequeue (); + if (current_es == null || current_es_index == current_es.Events.Length) { + if (queue.Count == 0) + Monitor.Wait (queue_monitor); + current_es = (EventSet)queue.Dequeue (); + current_es_index = 0; + } + return current_es.Events [current_es_index ++]; } } @@ -83,6 +90,18 @@ namespace Mono.Debugger.Soft throw new NotImplementedException (); } + public EventSet GetNextEventSet () { + lock (queue_monitor) { + if (queue.Count == 0) + Monitor.Wait (queue_monitor); + + current_es = null; + current_es_index = 0; + + return (EventSet)queue.Dequeue (); + } + } + public T GetNextEvent<T> () where T : Event { return GetNextEvent () as T; } @@ -109,7 +128,7 @@ namespace Mono.Debugger.Soft public void Dispose () { conn.VM_Dispose (); conn.Close (); - notify_vm_event (EventType.VMDisconnect, 0, 0, null); + notify_vm_event (EventType.VMDisconnect, SuspendPolicy.None, 0, 0, null); } public IList<ThreadMirror> GetThreads () { @@ -186,9 +205,9 @@ namespace Mono.Debugger.Soft conn.ClearAllBreakpoints (); } - internal void queue_event (Event e) { + internal void queue_event_set (EventSet es) { lock (queue_monitor) { - queue.Enqueue (e); + queue.Enqueue (es); Monitor.Pulse (queue_monitor); } } @@ -223,7 +242,7 @@ namespace Mono.Debugger.Soft root_domain = GetDomain (root_domain_id); } - internal void notify_vm_event (EventType evtype, int req_id, long thread_id, string vm_uri) { + internal void notify_vm_event (EventType evtype, SuspendPolicy spolicy, int req_id, long thread_id, string vm_uri) { //Console.WriteLine ("Event: " + evtype + "(" + vm_uri + ")"); switch (evtype) { @@ -232,13 +251,13 @@ namespace Mono.Debugger.Soft lock (startup_monitor) { Monitor.Pulse (startup_monitor); } - queue_event (new VMStartEvent (vm, req_id, thread_id)); + queue_event_set (new EventSet (this, spolicy, new Event[] { new VMStartEvent (vm, req_id, thread_id) })); break; case EventType.VMDeath: - queue_event (new VMDeathEvent (vm, req_id)); + queue_event_set (new EventSet (this, spolicy, new Event[] { new VMDeathEvent (vm, req_id) })); break; case EventType.VMDisconnect: - queue_event (new VMDisconnectEvent (vm, req_id)); + queue_event_set (new EventSet (this, spolicy, new Event[] { new VMDisconnectEvent (vm, req_id) })); break; default: throw new Exception (); @@ -497,64 +516,70 @@ namespace Mono.Debugger.Soft this.vm = vm; } - public void VMStart (int req_id, long thread_id, string vm_uri) { - vm.notify_vm_event (EventType.VMStart, req_id, thread_id, vm_uri); - } - - public void VMDeath (int req_id, long thread_id, string vm_uri) { - vm.notify_vm_event (EventType.VMDeath, req_id, thread_id, vm_uri); - } + public void Events (SuspendPolicy suspend_policy, EventInfo[] events) { + var l = new List<Event> (); + + for (int i = 0; i < events.Length; ++i) { + EventInfo ei = events [i]; + int req_id = ei.ReqId; + long thread_id = ei.ThreadId; + long id = ei.Id; + long loc = ei.Location; + + switch (ei.EventType) { + case EventType.VMStart: + vm.notify_vm_event (EventType.VMStart, suspend_policy, req_id, thread_id, null); + break; + case EventType.VMDeath: + vm.notify_vm_event (EventType.VMDeath, suspend_policy, req_id, thread_id, null); + break; + case EventType.ThreadStart: + l.Add (new ThreadStartEvent (vm, req_id, id)); + break; + case EventType.ThreadDeath: + l.Add (new ThreadDeathEvent (vm, req_id, id)); + break; + case EventType.AssemblyLoad: + l.Add (new AssemblyLoadEvent (vm, req_id, thread_id, id)); + break; + case EventType.AssemblyUnload: + l.Add (new AssemblyUnloadEvent (vm, req_id, thread_id, id)); + break; + case EventType.TypeLoad: + l.Add (new TypeLoadEvent (vm, req_id, thread_id, id)); + break; + case EventType.MethodEntry: + l.Add (new MethodEntryEvent (vm, req_id, thread_id, id)); + break; + case EventType.MethodExit: + l.Add (new MethodExitEvent (vm, req_id, thread_id, id)); + break; + case EventType.Breakpoint: + l.Add (new BreakpointEvent (vm, req_id, thread_id, id, loc)); + break; + case EventType.Step: + l.Add (new StepEvent (vm, req_id, thread_id, id, loc)); + break; + case EventType.Exception: + l.Add (new ExceptionEvent (vm, req_id, thread_id, id, loc)); + break; + case EventType.AppDomainCreate: + l.Add (new AppDomainCreateEvent (vm, req_id, thread_id, id)); + break; + case EventType.AppDomainUnload: + l.Add (new AppDomainUnloadEvent (vm, req_id, thread_id, id)); + break; + default: + break; + } + } + + if (l.Count > 0) + vm.queue_event_set (new EventSet (vm, suspend_policy, l.ToArray ())); + } public void VMDisconnect (int req_id, long thread_id, string vm_uri) { - vm.notify_vm_event (EventType.VMDisconnect, req_id, thread_id, vm_uri); - } - - public void ThreadStart (int req_id, long thread_id, long id) { - vm.queue_event (new ThreadStartEvent (vm, req_id, id)); - } - - public void ThreadDeath (int req_id, long thread_id, long id) { - vm.queue_event (new ThreadDeathEvent (vm, req_id, id)); - } - - public void AssemblyLoad (int req_id, long thread_id, long id) { - vm.queue_event (new AssemblyLoadEvent (vm, req_id, thread_id, id)); - } - - public void AssemblyUnload (int req_id, long thread_id, long id) { - vm.queue_event (new AssemblyUnloadEvent (vm, req_id, thread_id, id)); - } - - public void TypeLoad (int req_id, long thread_id, long id) { - vm.queue_event (new TypeLoadEvent (vm, req_id, thread_id, id)); - } - - public void MethodEntry (int req_id, long thread_id, long id) { - vm.queue_event (new MethodEntryEvent (vm, req_id, thread_id, id)); - } - - public void MethodExit (int req_id, long thread_id, long id) { - vm.queue_event (new MethodExitEvent (vm, req_id, thread_id, id)); - } - - public void Breakpoint (int req_id, long thread_id, long id, long loc) { - vm.queue_event (new BreakpointEvent (vm, req_id, thread_id, id, loc)); - } - - public void Step (int req_id, long thread_id, long id, long loc) { - vm.queue_event (new StepEvent (vm, req_id, thread_id, id, loc)); - } - - public void Exception (int req_id, long thread_id, long id, long loc) { - vm.queue_event (new ExceptionEvent (vm, req_id, thread_id, id, loc)); - } - - public void AppDomainCreate (int req_id, long thread_id, long id) { - vm.queue_event (new AppDomainCreateEvent (vm, req_id, thread_id, id)); - } - - public void AppDomainUnload (int req_id, long thread_id, long id) { - vm.queue_event (new AppDomainUnloadEvent (vm, req_id, thread_id, id)); + vm.notify_vm_event (EventType.VMDisconnect, SuspendPolicy.None, req_id, thread_id, vm_uri); } } diff --git a/mcs/class/Mono.Debugger.Soft/Test/ChangeLog b/mcs/class/Mono.Debugger.Soft/Test/ChangeLog index 01d039ebe02..e36de0541e7 100644 --- a/mcs/class/Mono.Debugger.Soft/Test/ChangeLog +++ b/mcs/class/Mono.Debugger.Soft/Test/ChangeLog @@ -1,3 +1,7 @@ +2010-06-17 Zoltan Varga <vargaz@gmail.com> + + * dtest.cs: Add an EventSet test. + 2010-06-15 Zoltan Varga <vargaz@gmail.com> * dtest.cs dtest-app.cs: New files containing the soft debugger tests, moved here diff --git a/mcs/class/Mono.Debugger.Soft/Test/dtest.cs b/mcs/class/Mono.Debugger.Soft/Test/dtest.cs index 3b639badb55..62d52df8ea8 100644 --- a/mcs/class/Mono.Debugger.Soft/Test/dtest.cs +++ b/mcs/class/Mono.Debugger.Soft/Test/dtest.cs @@ -2123,6 +2123,36 @@ public class DebuggerTests }); } + [Test] + public void EventSets () { + // + // Create two filter which both match the same exception + // + Event e = run_until ("exceptions"); + + var req = vm.CreateExceptionRequest (null); + req.Enable (); + + var req2 = vm.CreateExceptionRequest (vm.RootDomain.Corlib.GetType ("System.OverflowException")); + req2.Enable (); + + vm.Resume (); + + var es = vm.GetNextEventSet (); + Assert.AreEqual (2, es.Events.Length); + + e = es [0]; + Assert.IsInstanceOfType (typeof (ExceptionEvent), e); + Assert.AreEqual ("OverflowException", (e as ExceptionEvent).Exception.Type.Name); + + e = es [1]; + Assert.IsInstanceOfType (typeof (ExceptionEvent), e); + Assert.AreEqual ("OverflowException", (e as ExceptionEvent).Exception.Type.Name); + + req.Disable (); + req2.Disable (); + } + // // Test single threaded invokes during processing of nullref exceptions. // These won't work if the exception handling is done from the sigsegv signal |