diff --git a/Mono.Debugger.Soft/Mono.Debugger.Soft/Connection.cs b/Mono.Debugger.Soft/Mono.Debugger.Soft/Connection.cs index 5003825b..6f2c5413 100644 --- a/Mono.Debugger.Soft/Mono.Debugger.Soft/Connection.cs +++ b/Mono.Debugger.Soft/Mono.Debugger.Soft/Connection.cs @@ -483,7 +483,9 @@ enum EventKind { KEEPALIVE = 14, USER_BREAK = 15, USER_LOG = 16, - CRASH = 17 + CRASH = 17, + ENC_UPDATE = 18, + METHOD_UPDATE = 19, } enum ModifierKind { @@ -1620,6 +1622,9 @@ bool ReceivePacket () { //EventHandler.Exception (req_id, thread_id, id, loc); } else if (kind == EventKind.KEEPALIVE) { events [i] = new EventInfo (etype, req_id) { }; + } else if (kind == EventKind.METHOD_UPDATE) { + long id = r.ReadId (); + events[i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id }; } else { throw new NotImplementedException ("Unknown event kind: " + kind); } diff --git a/Mono.Debugger.Soft/Mono.Debugger.Soft/EncEvents.cs b/Mono.Debugger.Soft/Mono.Debugger.Soft/EncEvents.cs new file mode 100644 index 00000000..32281750 --- /dev/null +++ b/Mono.Debugger.Soft/Mono.Debugger.Soft/EncEvents.cs @@ -0,0 +1,20 @@ + +namespace Mono.Debugger.Soft +{ + public class MethodUpdateEvent : Event + { + long id; + MethodMirror method; + internal MethodUpdateEvent (VirtualMachine vm, int req_id, long thread_id, long id) : base (EventType.MethodUpdate, vm, req_id, thread_id) + { + this.id = id; + method = vm.GetMethod (id); + method.ClearCachedLocalsDebugInfo (); + } + + public MethodMirror GetMethod() + { + return method; + } + } +} diff --git a/Mono.Debugger.Soft/Mono.Debugger.Soft/EventRequest.cs b/Mono.Debugger.Soft/Mono.Debugger.Soft/EventRequest.cs index 69f35f4c..5962f57f 100644 --- a/Mono.Debugger.Soft/Mono.Debugger.Soft/EventRequest.cs +++ b/Mono.Debugger.Soft/Mono.Debugger.Soft/EventRequest.cs @@ -138,5 +138,18 @@ protected void CheckMirror (VirtualMachine vm, Mirror m) { if (vm != m.VirtualMachine) throw new VMMismatchException (); } + + //Used by EnC + public void UpdateReqId (int id) + { + this.id = id; + enabled = true; + } + + public int GetId () + { + return id; + } + } } \ No newline at end of file diff --git a/Mono.Debugger.Soft/Mono.Debugger.Soft/EventType.cs b/Mono.Debugger.Soft/Mono.Debugger.Soft/EventType.cs index 9fd82bd1..6b17a297 100644 --- a/Mono.Debugger.Soft/Mono.Debugger.Soft/EventType.cs +++ b/Mono.Debugger.Soft/Mono.Debugger.Soft/EventType.cs @@ -27,8 +27,10 @@ public enum EventType { // UserLog = 16, // Fatal error handling - Crash = 17, - // Not part of the wire protocol + Crash = 17, + EnCUpdate = 18, + MethodUpdate = 19, + // Not part of the wire protocol VMDisconnect = 99 } } diff --git a/Mono.Debugger.Soft/Mono.Debugger.Soft/MethodMirror.cs b/Mono.Debugger.Soft/Mono.Debugger.Soft/MethodMirror.cs index 3c48682f..1500aa41 100644 --- a/Mono.Debugger.Soft/Mono.Debugger.Soft/MethodMirror.cs +++ b/Mono.Debugger.Soft/Mono.Debugger.Soft/MethodMirror.cs @@ -33,6 +33,10 @@ public class MethodMirror : Mirror internal MethodMirror (VirtualMachine vm, long id) : base (vm, id) { } + public long GetId() { + return id; + } + public string Name { get { if (name == null) @@ -248,6 +252,13 @@ public ParameterInfoMirror ReturnParameter { } } + public void ClearCachedLocalsDebugInfo () + { + locals = null; + debug_info = null; + locations = null; + } + public LocalScope [] GetScopes () { vm.CheckProtocolVersion (2, 43); GetLocals (); diff --git a/Mono.Debugger.Soft/Mono.Debugger.Soft/VirtualMachine.cs b/Mono.Debugger.Soft/Mono.Debugger.Soft/VirtualMachine.cs index 9cf3a119..3d516550 100644 --- a/Mono.Debugger.Soft/Mono.Debugger.Soft/VirtualMachine.cs +++ b/Mono.Debugger.Soft/Mono.Debugger.Soft/VirtualMachine.cs @@ -874,6 +874,9 @@ public void Events (SuspendPolicy suspend_policy, EventInfo[] events) { case EventType.Crash: l.Add (new CrashEvent (vm, req_id, thread_id, ei.Dump, ei.Hash)); break; + case EventType.MethodUpdate: + l.Add (new MethodUpdateEvent (vm, req_id, thread_id, id)); + break; } } diff --git a/Mono.Debugging.Soft/SoftDebuggerSession.cs b/Mono.Debugging.Soft/SoftDebuggerSession.cs index 3d4bb739..c68ba564 100644 --- a/Mono.Debugging.Soft/SoftDebuggerSession.cs +++ b/Mono.Debugging.Soft/SoftDebuggerSession.cs @@ -602,6 +602,9 @@ void ConnectionStarted (VirtualMachine machine) machine.EnableEvents (EventType.TypeLoad); } + + machine.EnableEvents (EventType.MethodUpdate); + started = true; /* Wait for the VMStart event */ @@ -1347,6 +1350,17 @@ void InsertBreakpoint (Breakpoint bp, BreakInfo bi) InsertBreakpoint (bp, bi, bi.Location.Method, bi.Location.ILOffset); } + void UpdateBreakpoint (Breakpoint bp, BreakInfo bi) + { + foreach (var req in bi.Requests) + { + req.Key.Disable (); + var request = vm.SetBreakpoint (bi.Location.Method, bi.Location.ILOffset); + req.Key.UpdateReqId (request.GetId()); + req.Key.Enabled = bp.Enabled; + } + } + void InsertBreakpoint (Breakpoint bp, BreakInfo bi, MethodMirror method, int ilOffset) { EventRequest request; @@ -1858,6 +1872,9 @@ void HandleEventSet (EventSet es) case EventType.UserLog: HandleUserLogEvents (Array.ConvertAll (es.Events, item => (UserLogEvent)item)); break; + case EventType.MethodUpdate: + HandleMethodUpdateEvents (Array.ConvertAll (es.Events, item => (MethodUpdateEvent)item)); + break; default: DebuggerLoggingService.LogMessage ("Ignoring unknown debugger event type {0}", type); break; @@ -2391,6 +2408,22 @@ void HandleUserLogEvents (UserLogEvent[] events) OnTargetDebug (ul.Level, ul.Category, ul.Message); } + void HandleMethodUpdateEvents(MethodUpdateEvent[] methods) + { + foreach (var method in methods) + { + foreach (var bp in breakpoints) { + if (bp.Value.Location.Method.GetId() == method.GetMethod().GetId()) + { + bool dummy = false; + var l = FindLocationByMethod (bp.Value.Location.Method, bp.Value.Location.SourceFile, bp.Value.Location.LineNumber, bp.Value.Location.ColumnNumber, ref dummy); + bp.Value.Location = l; + UpdateBreakpoint ((Breakpoint)bp.Value.BreakEvent, bp.Value); + } + } + } + } + public ObjectMirror GetExceptionObject (ThreadMirror thread) { ObjectMirror obj;