public long catch_type_id;
}
+ [Flags]
enum ExceptionClauseFlags {
None = 0x0,
Filter = 0x1,
VALUE_TYPE_ID_TYPE = 0xf1
}
+ [Flags]
enum InvokeFlags {
NONE = 0x0,
DISABLE_BREAKPOINTS = 0x1,
public long Assembly;
}
+ class FieldMirrorInfo {
+ public string Name;
+ public long Parent, TypeId;
+ public int Attrs;
+ }
+
enum TokenType {
STRING = 0,
TYPE = 1,
UNKNOWN = 4
}
+ [Flags]
enum StackFrameFlags {
NONE = 0,
DEBUGGER_INVOKE = 1,
public bool Uncaught {
get; set;
}
+ public bool Subclasses {
+ get; set;
+ }
}
class AssemblyModifier : Modifier {
get; set;
}
+ public int ExitCode {
+ get; set;
+ }
+
public EventInfo (EventType type, int req_id) {
EventType = type;
ReqId = req_id;
* with newer runtimes, and vice versa.
*/
internal const int MAJOR_VERSION = 2;
- internal const int MINOR_VERSION = 19;
+ internal const int MINOR_VERSION = 30;
enum WPSuspendPolicy {
NONE = 0,
METHOD = 22,
TYPE = 23,
MODULE = 24,
+ FIELD = 25,
EVENT = 64
}
ABORT_INVOKE = 9,
SET_KEEPALIVE = 10,
GET_TYPES_FOR_SOURCE_FILE = 11,
- GET_TYPES = 12
+ GET_TYPES = 12,
+ INVOKE_METHODS = 13
}
enum CmdEvent {
/* FIXME: Merge into GET_INFO when the major protocol version is increased */
GET_ID = 5,
/* Ditto */
- GET_TID = 6
+ GET_TID = 6,
+ SET_IP = 7
}
enum CmdEventRequest {
GET_LOCALS_INFO = 5,
GET_INFO = 6,
GET_BODY = 7,
- RESOLVE_TOKEN = 8
+ RESOLVE_TOKEN = 8,
+ GET_CATTRS = 9,
+ MAKE_GENERIC_METHOD = 10
}
enum CmdType {
GET_VALUES_2 = 14,
CMD_TYPE_GET_METHODS_BY_NAME_FLAGS = 15,
GET_INTERFACES = 16,
- GET_INTERFACE_MAP = 17
+ GET_INTERFACE_MAP = 17,
+ IS_INITIALIZED = 18
+ }
+
+ enum CmdField {
+ GET_INFO = 1
}
+ [Flags]
enum BindingFlagsExtensions {
BINDING_FLAGS_IGNORE_CASE = 0x70000000,
}
Thread receiver_thread;
Dictionary<int, byte[]> reply_packets;
Dictionary<int, ReplyCallback> reply_cbs;
+ Dictionary<int, int> reply_cb_counts;
object reply_packets_monitor;
internal event EventHandler<ErrorHandlerEventArgs> ErrorHandler;
closed = false;
reply_packets = new Dictionary<int, byte[]> ();
reply_cbs = new Dictionary<int, ReplyCallback> ();
+ reply_cb_counts = new Dictionary<int, int> ();
reply_packets_monitor = new Object ();
}
TransportSend (buf, 0, buf.Length);
receiver_thread = new Thread (new ThreadStart (receiver_thread_main));
+ receiver_thread.Name = "SDB Receiver";
+ receiver_thread.IsBackground = true;
receiver_thread.Start ();
Version = VM_GetVersion ();
if (cb == null) {
reply_packets [id] = packet;
Monitor.PulseAll (reply_packets_monitor);
+ } else {
+ int c = reply_cb_counts [id];
+ c --;
+ if (c == 0) {
+ reply_cbs.Remove (id);
+ reply_cb_counts.Remove (id);
+ }
}
}
EventType etype = (EventType)kind;
+ long thread_id = r.ReadId ();
if (kind == EventKind.VM_START) {
- long thread_id = r.ReadId ();
events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id };
//EventHandler.VMStart (req_id, thread_id, null);
} else if (kind == EventKind.VM_DEATH) {
+ int exit_code = 0;
+ if (Version.AtLeast (2, 27))
+ exit_code = r.ReadInt ();
//EventHandler.VMDeath (req_id, 0, null);
- events [i] = new EventInfo (etype, req_id) { };
+ events [i] = new EventInfo (etype, req_id) { ExitCode = exit_code };
} else if (kind == EventKind.THREAD_START) {
- long thread_id = r.ReadId ();
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 ();
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 ();
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 ();
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 ();
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 ();
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 ();
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 ();
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 ();
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
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 ();
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 ();
events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id };
//EventHandler.AppDomainUnload (req_id, thread_id, id);
} else if (kind == EventKind.USER_BREAK) {
- long thread_id = r.ReadId ();
long id = 0;
long loc = 0;
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.USER_LOG) {
- long thread_id = r.ReadId ();
int level = r.ReadInt ();
string category = r.ReadString ();
string message = r.ReadString ();
case CommandSet.MODULE:
cmd = ((CmdModule)command).ToString ();
break;
+ case CommandSet.FIELD:
+ cmd = ((CmdField)command).ToString ();
+ break;
case CommandSet.EVENT:
cmd = ((CmdEvent)command).ToString ();
break;
}
/* Send a request and call cb when a result is received */
- int Send (CommandSet command_set, int command, PacketWriter packet, Action<PacketReader> cb) {
+ int Send (CommandSet command_set, int command, PacketWriter packet, Action<PacketReader> cb, int count) {
int id = IdGenerator;
Stopwatch watch = null;
PacketReader r = new PacketReader (p);
cb.BeginInvoke (r, null, null);
};
+ reply_cb_counts [id] = count;
}
WritePacket (encoded_packet);
callback (v, exc, 0, state);
}
- });
+ }, 1);
+ }
+
+ internal int VM_BeginInvokeMethods (long thread, long[] methods, ValueImpl this_arg, List<ValueImpl[]> arguments, InvokeFlags flags, InvokeMethodCallback callback, object state) {
+ // FIXME: Merge this with INVOKE_METHOD
+ var w = new PacketWriter ();
+ w.WriteId (thread);
+ w.WriteInt ((int)flags);
+ w.WriteInt (methods.Length);
+ for (int i = 0; i < methods.Length; ++i) {
+ w.WriteId (methods [i]);
+ w.WriteValue (this_arg);
+ w.WriteInt (arguments [i].Length);
+ w.WriteValues (arguments [i]);
+ }
+ return Send (CommandSet.VM, (int)CmdVM.INVOKE_METHODS, w, delegate (PacketReader r) {
+ ValueImpl v, exc;
+
+ if (r.ErrorCode != 0) {
+ callback (null, null, (ErrorCode)r.ErrorCode, state);
+ } else {
+ if (r.ReadByte () == 0) {
+ exc = r.ReadValue ();
+ v = null;
+ } else {
+ v = r.ReadValue ();
+ exc = null;
+ }
+
+ callback (v, exc, 0, state);
+ }
+ }, methods.Length);
}
internal void VM_AbortInvoke (long thread, int id)
}
}
+ internal CattrInfo[] Method_GetCustomAttributes (long id, long attr_type_id, bool inherit) {
+ PacketReader r = SendReceive (CommandSet.METHOD, (int)CmdMethod.GET_CATTRS, new PacketWriter ().WriteId (id).WriteId (attr_type_id));
+ return ReadCattrs (r);
+ }
+
+ internal long Method_MakeGenericMethod (long id, long[] args) {
+ PacketReader r = SendReceive (CommandSet.METHOD, (int)CmdMethod.MAKE_GENERIC_METHOD, new PacketWriter ().WriteId (id).WriteInt (args.Length).WriteIds (args));
+ return r.ReadId ();
+ }
+
/*
* THREAD
*/
return SendReceive (CommandSet.THREAD, (int)CmdThread.GET_TID, new PacketWriter ().WriteId (id)).ReadLong ();
}
+ internal void Thread_SetIP (long id, long method_id, long il_offset) {
+ SendReceive (CommandSet.THREAD, (int)CmdThread.SET_IP, new PacketWriter ().WriteId (id).WriteId (method_id).WriteLong (il_offset));
+ }
+
/*
* MODULE
*/
return res;
}
+ internal bool Type_IsInitialized (long id) {
+ PacketReader r = SendReceive (CommandSet.TYPE, (int)CmdType.IS_INITIALIZED, new PacketWriter ().WriteId (id));
+ return r.ReadInt () == 1;
+ }
+
+ /*
+ * FIELD
+ */
+
+ internal FieldMirrorInfo Field_GetInfo (long id) {
+ PacketReader r = SendReceive (CommandSet.FIELD, (int)CmdField.GET_INFO, new PacketWriter ().WriteId (id));
+ FieldMirrorInfo info = new FieldMirrorInfo { Name = r.ReadString (), Parent = r.ReadId (), TypeId = r.ReadId (), Attrs = r.ReadInt () };
+ return info;
+ }
+
/*
* EVENTS
*/
} else if (!em.Caught || !em.Uncaught) {
throw new NotSupportedException ("This request is not supported by the protocol version implemented by the debuggee.");
}
+ if (Version.MajorVersion > 2 || Version.MinorVersion > 24) {
+ w.WriteBool (em.Subclasses);
+ } else if (!em.Subclasses) {
+ throw new NotSupportedException ("This request is not supported by the protocol version implemented by the debuggee.");
+ }
} else if (mod is AssemblyModifier) {
w.WriteByte ((byte)ModifierKind.ASSEMBLY_ONLY);
var amod = (mod as AssemblyModifier);
public void ForceDisconnect ()
{
+ closed = true;
+ disconnected = true;
TransportClose ();
}
}