4 using System.Net.Sockets;
5 using System.Threading;
6 using System.Collections.Generic;
8 using System.Diagnostics;
9 using Mono.Cecil.Metadata;
11 namespace Mono.Debugger.Soft
13 public class VersionInfo {
14 public string VMVersion {
18 public int MajorVersion {
22 public int MinorVersion {
27 * Check that this version is at least major:minor
29 public bool AtLeast (int major, int minor) {
30 if ((MajorVersion > major) || ((MajorVersion == major && MinorVersion >= minor)))
38 public int max_il_offset;
39 public string filename;
40 public int[] il_offsets;
41 public int[] line_numbers;
48 public StackFrameFlags flags;
52 public string ns, name, full_name;
53 public long assembly, module, base_type, element_type;
54 public int token, rank, attributes;
55 public bool is_byref, is_pointer, is_primitive, is_valuetype, is_enum;
56 public bool is_gtd, is_generic_type;
63 public long[] iface_methods;
64 public long[] target_methods;
68 public int attributes, iattributes, token;
69 public bool is_gmd, is_generic_method;
73 class MethodBodyInfo {
79 public int param_count;
80 public int generic_param_count;
82 public long[] param_types;
83 public string[] param_names;
88 public string[] names;
89 public int[] live_range_start;
90 public int[] live_range_end;
96 public long get_method, set_method;
100 class CattrNamedArgInfo {
101 public bool is_property;
103 public ValueImpl value;
108 public ValueImpl[] ctor_args;
109 public CattrNamedArgInfo[] named_args;
113 public bool is_thread_pool;
116 struct ObjectRefInfo {
118 public long domain_id;
122 VALUE_TYPE_ID_NULL = 0xf0,
123 VALUE_TYPE_ID_TYPE = 0xf1
128 DISABLE_BREAKPOINTS = 0x1,
129 SINGLE_THREADED = 0x2
175 public ElementType Type; /* or one of the VALUE_TYPE_ID constants */
178 public long Klass; // For ElementType.ValueType
179 public ValueImpl[] Fields; // for ElementType.ValueType
180 public bool IsEnum; // For ElementType.ValueType
181 public long Id; /* For VALUE_TYPE_ID_TYPE */
185 public string Name, ScopeName, FQName, Guid;
186 public long Assembly;
197 enum StackFrameFlags {
201 class ResolvedToken {
202 public TokenType Type;
210 class CountModifier : Modifier {
216 class LocationModifier : Modifier {
221 public long Location {
226 class StepModifier : Modifier {
240 class ThreadModifier : Modifier {
246 class ExceptionModifier : Modifier {
253 public bool Uncaught {
258 class AssemblyModifier : Modifier {
259 public long[] Assemblies {
264 class SourceFileModifier : Modifier {
265 public string[] SourceFiles {
270 class TypeNameModifier : Modifier {
271 public string[] TypeNames {
277 public EventType EventType {
285 public SuspendPolicy SuspendPolicy {
289 public long ThreadId {
297 public long Location {
305 public string Category {
309 public string Message {
313 public EventInfo (EventType type, int req_id) {
319 public enum ErrorCode {
322 INVALID_FIELDID = 25,
323 INVALID_FRAMEID = 30,
324 NOT_IMPLEMENTED = 100,
326 INVALID_ARGUMENT = 102,
328 ERR_NO_INVOCATION = 104,
329 ABSENT_INFORMATION = 105,
330 NO_SEQ_POINT_AT_IL_OFFSET = 106
333 public class ErrorHandlerEventArgs : EventArgs {
335 public ErrorCode ErrorCode {
341 * Represents the connection to the debuggee
343 public abstract class Connection
346 * The protocol and the packet format is based on JDWP, the differences
347 * are in the set of supported events, and the commands.
349 internal const string HANDSHAKE_STRING = "DWP-Handshake";
351 internal const int HEADER_LENGTH = 11;
353 static readonly bool EnableConnectionLogging = !String.IsNullOrEmpty (Environment.GetEnvironmentVariable ("MONO_SDB_LOG"));
354 static int ConnectionId;
355 readonly StreamWriter LoggingStream = EnableConnectionLogging ?
356 new StreamWriter (string.Format ("/tmp/sdb_conn_log_{0}", ConnectionId++), false) : null;
359 * Th version of the wire-protocol implemented by the library. The library
360 * and the debuggee can communicate if they implement the same major version.
361 * If they implement a different minor version, they can communicate, but some
362 * features might not be available. This allows older clients to communicate
363 * with newer runtimes, and vice versa.
365 internal const int MAJOR_VERSION = 2;
366 internal const int MINOR_VERSION = 12;
368 enum WPSuspendPolicy {
395 APPDOMAIN_CREATE = 4, // Not in JDI
396 APPDOMAIN_UNLOAD = 5, // Not in JDI
417 SOURCE_FILE_ONLY = 12,
429 SET_PROTOCOL_VERSION = 8,
432 GET_TYPES_FOR_SOURCE_FILE = 11,
445 /* FIXME: Merge into GET_INFO when the major protocol version is increased */
451 enum CmdEventRequest {
454 CLEAR_ALL_BREAKPOINTS = 3
459 GET_FRIENDLY_NAME = 2,
461 GET_ENTRY_ASSEMBLY = 4,
464 CREATE_BOXED_VALUE = 7
470 GET_MANIFEST_MODULE = 3,
482 GET_DECLARING_TYPE = 2,
497 GET_SOURCE_FILES = 6,
499 IS_ASSIGNABLE_FROM = 8,
502 GET_FIELD_CATTRS = 11,
503 GET_PROPERTY_CATTRS = 12,
504 /* FIXME: Merge into GET_SOURCE_FILES when the major protocol version is increased */
505 GET_SOURCE_FILES_2 = 13,
506 /* FIXME: Merge into GET_VALUES when the major protocol version is increased */
508 CMD_TYPE_GET_METHODS_BY_NAME_FLAGS = 15,
510 GET_INTERFACE_MAP = 17
513 enum BindingFlagsExtensions {
514 BINDING_FLAGS_IGNORE_CASE = 0x70000000,
547 public int command_set;
552 internal static int GetPacketLength (byte[] header) {
554 return decode_int (header, ref offset);
557 internal static bool IsReplyPacket (byte[] packet) {
559 return decode_byte (packet, ref offset) == 0x80;
562 internal static int GetPacketId (byte[] packet) {
564 return decode_int (packet, ref offset);
567 static int decode_byte (byte[] packet, ref int offset) {
568 return packet [offset++];
571 static int decode_short (byte[] packet, ref int offset) {
572 int res = ((int)packet [offset] << 8) | (int)packet [offset + 1];
577 static int decode_int (byte[] packet, ref int offset) {
578 int res = ((int)packet [offset] << 24) | ((int)packet [offset + 1] << 16) | ((int)packet [offset + 2] << 8) | (int)packet [offset + 3];
583 static long decode_id (byte[] packet, ref int offset) {
584 return decode_int (packet, ref offset);
587 static long decode_long (byte[] packet, ref int offset) {
588 uint high = (uint)decode_int (packet, ref offset);
589 uint low = (uint)decode_int (packet, ref offset);
591 return (long)(((ulong)high << 32) | (ulong)low);
594 internal static SuspendPolicy decode_suspend_policy (int suspend_policy) {
595 switch ((WPSuspendPolicy)suspend_policy) {
596 case WPSuspendPolicy.NONE:
597 return SuspendPolicy.None;
598 case WPSuspendPolicy.EVENT_THREAD:
599 return SuspendPolicy.EventThread;
600 case WPSuspendPolicy.ALL:
601 return SuspendPolicy.All;
603 throw new NotImplementedException ();
607 static Header decode_command_header (byte[] packet) {
609 Header res = new Header ();
611 decode_int (packet, ref offset);
612 res.id = decode_int (packet, ref offset);
613 res.flags = decode_byte (packet, ref offset);
614 res.command_set = decode_byte (packet, ref offset);
615 res.command = decode_byte (packet, ref offset);
620 static void encode_byte (byte[] buf, int b, ref int offset) {
621 buf [offset] = (byte)b;
625 static void encode_int (byte[] buf, int i, ref int offset) {
626 buf [offset] = (byte)((i >> 24) & 0xff);
627 buf [offset + 1] = (byte)((i >> 16) & 0xff);
628 buf [offset + 2] = (byte)((i >> 8) & 0xff);
629 buf [offset + 3] = (byte)((i >> 0) & 0xff);
633 static void encode_id (byte[] buf, long id, ref int offset) {
634 encode_int (buf, (int)id, ref offset);
637 static void encode_long (byte[] buf, long l, ref int offset) {
638 encode_int (buf, (int)((l >> 32) & 0xffffffff), ref offset);
639 encode_int (buf, (int)(l & 0xffffffff), ref offset);
642 internal static byte[] EncodePacket (int id, int commandSet, int command, byte[] data, int dataLen) {
643 byte[] buf = new byte [dataLen + 11];
646 encode_int (buf, buf.Length, ref offset);
647 encode_int (buf, id, ref offset);
648 encode_byte (buf, 0, ref offset);
649 encode_byte (buf, commandSet, ref offset);
650 encode_byte (buf, command, ref offset);
652 for (int i = 0; i < dataLen; ++i)
653 buf [offset + i] = data [i];
662 public PacketReader (byte[] packet) {
663 this.packet = packet;
666 Header header = decode_command_header (packet);
667 CommandSet = (CommandSet)header.command_set;
668 Command = header.command;
672 ReadInt (); // length
674 ReadByte (); // flags
675 ErrorCode = ReadShort ();
678 public CommandSet CommandSet {
686 public int ErrorCode {
696 public int ReadByte () {
697 return decode_byte (packet, ref offset);
700 public int ReadShort () {
701 return decode_short (packet, ref offset);
704 public int ReadInt () {
705 return decode_int (packet, ref offset);
708 public long ReadId () {
709 return decode_id (packet, ref offset);
712 public long ReadLong () {
713 return decode_long (packet, ref offset);
716 public float ReadFloat () {
717 float f = DataConverter.FloatFromBE (packet, offset);
722 public double ReadDouble () {
723 double d = DataConverter.DoubleFromBE (packet, offset);
728 public string ReadString () {
729 int len = decode_int (packet, ref offset);
730 string res = new String (Encoding.UTF8.GetChars (packet, offset, len));
735 public ValueImpl ReadValue () {
736 ElementType etype = (ElementType)ReadByte ();
739 case ElementType.Void:
740 return new ValueImpl { Type = etype };
742 return new ValueImpl { Type = etype, Value = (sbyte)ReadInt () };
744 return new ValueImpl { Type = etype, Value = (byte)ReadInt () };
745 case ElementType.Boolean:
746 return new ValueImpl { Type = etype, Value = ReadInt () != 0 };
748 return new ValueImpl { Type = etype, Value = (short)ReadInt () };
750 return new ValueImpl { Type = etype, Value = (ushort)ReadInt () };
751 case ElementType.Char:
752 return new ValueImpl { Type = etype, Value = (char)ReadInt () };
754 return new ValueImpl { Type = etype, Value = ReadInt () };
756 return new ValueImpl { Type = etype, Value = (uint)ReadInt () };
758 return new ValueImpl { Type = etype, Value = ReadLong () };
760 return new ValueImpl { Type = etype, Value = (ulong)ReadLong () };
762 return new ValueImpl { Type = etype, Value = ReadFloat () };
764 return new ValueImpl { Type = etype, Value = ReadDouble () };
767 case ElementType.Ptr:
768 // FIXME: The client and the debuggee might have different word sizes
769 return new ValueImpl { Type = etype, Value = ReadLong () };
770 case ElementType.String:
771 case ElementType.SzArray:
772 case ElementType.Class:
773 case ElementType.Array:
774 case ElementType.Object:
775 long objid = ReadId ();
776 return new ValueImpl () { Type = etype, Objid = objid };
777 case ElementType.ValueType:
778 bool is_enum = ReadByte () == 1;
779 long klass = ReadId ();
780 long nfields = ReadInt ();
781 ValueImpl[] fields = new ValueImpl [nfields];
782 for (int i = 0; i < nfields; ++i)
783 fields [i] = ReadValue ();
784 return new ValueImpl () { Type = etype, Klass = klass, Fields = fields, IsEnum = is_enum };
785 case (ElementType)ValueTypeId.VALUE_TYPE_ID_NULL:
786 return new ValueImpl { Type = etype };
787 case (ElementType)ValueTypeId.VALUE_TYPE_ID_TYPE:
788 return new ValueImpl () { Type = etype, Id = ReadId () };
790 throw new NotImplementedException ("Unable to handle type " + etype);
794 public long[] ReadIds (int n) {
795 long[] res = new long [n];
796 for (int i = 0; i < n; ++i)
807 public PacketWriter () {
808 data = new byte [1024];
812 void MakeRoom (int size) {
813 if (offset + size >= data.Length) {
814 int new_len = data.Length * 2;
815 while (new_len < offset + size) {
818 byte[] new_data = new byte [new_len];
819 Array.Copy (data, new_data, data.Length);
824 public PacketWriter WriteByte (byte val) {
826 encode_byte (data, val, ref offset);
830 public PacketWriter WriteInt (int val) {
832 encode_int (data, val, ref offset);
836 public PacketWriter WriteId (long id) {
838 encode_id (data, id, ref offset);
842 public PacketWriter WriteLong (long val) {
844 encode_long (data, val, ref offset);
848 public PacketWriter WriteFloat (float f) {
850 byte[] b = DataConverter.GetBytesBE (f);
851 for (int i = 0; i < 4; ++i)
852 data [offset + i] = b [i];
857 public PacketWriter WriteDouble (double d) {
859 byte[] b = DataConverter.GetBytesBE (d);
860 for (int i = 0; i < 8; ++i)
861 data [offset + i] = b [i];
866 public PacketWriter WriteInts (int[] ids) {
867 for (int i = 0; i < ids.Length; ++i)
872 public PacketWriter WriteIds (long[] ids) {
873 for (int i = 0; i < ids.Length; ++i)
878 public PacketWriter WriteString (string s) {
880 return WriteInt (-1);
882 byte[] b = Encoding.UTF8.GetBytes (s);
884 encode_int (data, b.Length, ref offset);
886 Buffer.BlockCopy (b, 0, data, offset, b.Length);
891 public PacketWriter WriteBool (bool val) {
892 WriteByte (val ? (byte)1 : (byte)0);
896 public PacketWriter WriteValue (ValueImpl v) {
900 t = TypeCodeToElementType (Type.GetTypeCode (v.Value.GetType ()));
905 case ElementType.Boolean:
906 WriteInt ((bool)v.Value ? 1 : 0);
908 case ElementType.Char:
909 WriteInt ((int)(char)v.Value);
912 WriteInt ((int)(sbyte)v.Value);
915 WriteInt ((int)(byte)v.Value);
918 WriteInt ((int)(short)v.Value);
921 WriteInt ((int)(ushort)v.Value);
924 WriteInt ((int)(int)v.Value);
927 WriteInt ((int)(uint)v.Value);
930 WriteLong ((long)(long)v.Value);
933 WriteLong ((long)(ulong)v.Value);
936 WriteFloat ((float)v.Value);
939 WriteDouble ((double)v.Value);
941 case ElementType.String:
942 case ElementType.SzArray:
943 case ElementType.Class:
944 case ElementType.Array:
945 case ElementType.Object:
948 case ElementType.ValueType:
951 throw new NotImplementedException ();
954 WriteInt (v.Fields.Length);
955 for (int i = 0; i < v.Fields.Length; ++i)
956 WriteValue (v.Fields [i]);
958 case (ElementType)ValueTypeId.VALUE_TYPE_ID_NULL:
961 throw new NotImplementedException ();
967 public PacketWriter WriteValues (ValueImpl[] values) {
968 for (int i = 0; i < values.Length; ++i)
969 WriteValue (values [i]);
986 delegate void ReplyCallback (int packet_id, byte[] packet);
989 Thread receiver_thread;
990 Dictionary<int, byte[]> reply_packets;
991 Dictionary<int, ReplyCallback> reply_cbs;
992 object reply_packets_monitor;
994 internal event EventHandler<ErrorHandlerEventArgs> ErrorHandler;
996 protected Connection () {
998 reply_packets = new Dictionary<int, byte[]> ();
999 reply_cbs = new Dictionary<int, ReplyCallback> ();
1000 reply_packets_monitor = new Object ();
1003 protected abstract int TransportReceive (byte[] buf, int buf_offset, int len);
1004 protected abstract int TransportSend (byte[] buf, int buf_offset, int len);
1005 protected abstract void TransportSetTimeouts (int send_timeout, int receive_timeout);
1006 protected abstract void TransportClose ();
1008 internal VersionInfo Version;
1010 int Receive (byte[] buf, int buf_offset, int len) {
1013 while (offset < len) {
1014 int n = TransportReceive (buf, buf_offset + offset, len - offset);
1024 // Do the wire protocol handshake
1025 internal void Connect () {
1026 byte[] buf = new byte [HANDSHAKE_STRING.Length];
1027 char[] cbuf = new char [buf.Length];
1029 // FIXME: Add a timeout
1030 int n = Receive (buf, 0, buf.Length);
1032 throw new IOException ("DWP Handshake failed.");
1033 for (int i = 0; i < buf.Length; ++i)
1034 cbuf [i] = (char)buf [i];
1036 if (new String (cbuf) != HANDSHAKE_STRING)
1037 throw new IOException ("DWP Handshake failed.");
1039 TransportSend (buf, 0, buf.Length);
1041 receiver_thread = new Thread (new ThreadStart (receiver_thread_main));
1042 receiver_thread.Start ();
1044 Version = VM_GetVersion ();
1047 // Tell the debuggee our protocol version, so newer debuggees can work
1048 // with older clients
1052 // Older debuggees might not support this request
1053 EventHandler<ErrorHandlerEventArgs> OrigErrorHandler = ErrorHandler;
1054 ErrorHandler = null;
1055 ErrorHandler += delegate (object sender, ErrorHandlerEventArgs args) {
1056 throw new NotSupportedException ();
1059 VM_SetProtocolVersion (MAJOR_VERSION, MINOR_VERSION);
1060 } catch (NotSupportedException) {
1062 ErrorHandler = OrigErrorHandler;
1065 internal byte[] ReadPacket () {
1066 // FIXME: Throw ClosedConnectionException () if the connection is closed
1067 // FIXME: Throw ClosedConnectionException () if another thread closes the connection
1069 byte[] header = new byte [HEADER_LENGTH];
1071 int len = Receive (header, 0, header.Length);
1073 return new byte [0];
1074 if (len != HEADER_LENGTH) {
1076 throw new IOException ("Packet of length " + len + " is read.");
1079 int packetLength = GetPacketLength (header);
1080 if (packetLength < 11)
1081 throw new IOException ("Invalid packet length.");
1083 if (packetLength == 11) {
1086 byte[] buf = new byte [packetLength];
1087 for (int i = 0; i < header.Length; ++i)
1088 buf [i] = header [i];
1089 len = Receive (buf, header.Length, packetLength - header.Length);
1090 if (len != packetLength - header.Length)
1091 throw new IOException ();
1096 internal void WritePacket (byte[] packet) {
1097 // FIXME: Throw ClosedConnectionException () if the connection is closed
1098 // FIXME: Throw ClosedConnectionException () if another thread closes the connection
1100 TransportSend (packet, 0, packet.Length);
1103 internal void Close () {
1107 internal bool IsClosed {
1115 void receiver_thread_main () {
1118 bool res = ReceivePacket ();
1121 } catch (Exception ex) {
1122 Console.WriteLine (ex);
1127 lock (reply_packets_monitor) {
1128 disconnected = true;
1129 Monitor.PulseAll (reply_packets_monitor);
1132 EventHandler.VMDisconnect (0, 0, null);
1135 bool ReceivePacket () {
1136 byte[] packet = ReadPacket ();
1138 if (packet.Length == 0) {
1142 if (IsReplyPacket (packet)) {
1143 int id = GetPacketId (packet);
1144 ReplyCallback cb = null;
1145 lock (reply_packets_monitor) {
1146 reply_cbs.TryGetValue (id, out cb);
1148 reply_packets [id] = packet;
1149 Monitor.PulseAll (reply_packets_monitor);
1154 cb.Invoke (id, packet);
1156 PacketReader r = new PacketReader (packet);
1158 if (r.CommandSet == CommandSet.EVENT && r.Command == (int)CmdEvent.COMPOSITE) {
1159 int spolicy = r.ReadByte ();
1160 int nevents = r.ReadInt ();
1162 SuspendPolicy suspend_policy = decode_suspend_policy (spolicy);
1164 EventInfo[] events = new EventInfo [nevents];
1166 for (int i = 0; i < nevents; ++i) {
1167 EventKind kind = (EventKind)r.ReadByte ();
1168 int req_id = r.ReadInt ();
1170 EventType etype = (EventType)kind;
1172 if (kind == EventKind.VM_START) {
1173 long thread_id = r.ReadId ();
1174 events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id };
1175 //EventHandler.VMStart (req_id, thread_id, null);
1176 } else if (kind == EventKind.VM_DEATH) {
1177 //EventHandler.VMDeath (req_id, 0, null);
1178 events [i] = new EventInfo (etype, req_id) { };
1179 } else if (kind == EventKind.THREAD_START) {
1180 long thread_id = r.ReadId ();
1181 events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = thread_id };
1182 //EventHandler.ThreadStart (req_id, thread_id, thread_id);
1183 } else if (kind == EventKind.THREAD_DEATH) {
1184 long thread_id = r.ReadId ();
1185 events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = thread_id };
1186 //EventHandler.ThreadDeath (req_id, thread_id, thread_id);
1187 } else if (kind == EventKind.ASSEMBLY_LOAD) {
1188 long thread_id = r.ReadId ();
1189 long id = r.ReadId ();
1190 events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id };
1191 //EventHandler.AssemblyLoad (req_id, thread_id, id);
1192 } else if (kind == EventKind.ASSEMBLY_UNLOAD) {
1193 long thread_id = r.ReadId ();
1194 long id = r.ReadId ();
1195 events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id };
1196 //EventHandler.AssemblyUnload (req_id, thread_id, id);
1197 } else if (kind == EventKind.TYPE_LOAD) {
1198 long thread_id = r.ReadId ();
1199 long id = r.ReadId ();
1200 events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id };
1201 //EventHandler.TypeLoad (req_id, thread_id, id);
1202 } else if (kind == EventKind.METHOD_ENTRY) {
1203 long thread_id = r.ReadId ();
1204 long id = r.ReadId ();
1205 events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id };
1206 //EventHandler.MethodEntry (req_id, thread_id, id);
1207 } else if (kind == EventKind.METHOD_EXIT) {
1208 long thread_id = r.ReadId ();
1209 long id = r.ReadId ();
1210 events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id };
1211 //EventHandler.MethodExit (req_id, thread_id, id);
1212 } else if (kind == EventKind.BREAKPOINT) {
1213 long thread_id = r.ReadId ();
1214 long id = r.ReadId ();
1215 long loc = r.ReadLong ();
1216 events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id, Location = loc };
1217 //EventHandler.Breakpoint (req_id, thread_id, id, loc);
1218 } else if (kind == EventKind.STEP) {
1219 long thread_id = r.ReadId ();
1220 long id = r.ReadId ();
1221 long loc = r.ReadLong ();
1222 events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id, Location = loc };
1223 //EventHandler.Step (req_id, thread_id, id, loc);
1224 } else if (kind == EventKind.EXCEPTION) {
1225 long thread_id = r.ReadId ();
1226 long id = r.ReadId ();
1227 long loc = 0; // FIXME
1228 events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id, Location = loc };
1229 //EventHandler.Exception (req_id, thread_id, id, loc);
1230 } else if (kind == EventKind.APPDOMAIN_CREATE) {
1231 long thread_id = r.ReadId ();
1232 long id = r.ReadId ();
1233 events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id };
1234 //EventHandler.AppDomainCreate (req_id, thread_id, id);
1235 } else if (kind == EventKind.APPDOMAIN_UNLOAD) {
1236 long thread_id = r.ReadId ();
1237 long id = r.ReadId ();
1238 events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id };
1239 //EventHandler.AppDomainUnload (req_id, thread_id, id);
1240 } else if (kind == EventKind.USER_BREAK) {
1241 long thread_id = r.ReadId ();
1244 events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id, Location = loc };
1245 //EventHandler.Exception (req_id, thread_id, id, loc);
1246 } else if (kind == EventKind.USER_LOG) {
1247 long thread_id = r.ReadId ();
1248 int level = r.ReadInt ();
1249 string category = r.ReadString ();
1250 string message = r.ReadString ();
1251 events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Level = level, Category = category, Message = message };
1252 //EventHandler.Exception (req_id, thread_id, id, loc);
1253 } else if (kind == EventKind.KEEPALIVE) {
1254 events [i] = new EventInfo (etype, req_id) { };
1256 throw new NotImplementedException ("Unknown event kind: " + kind);
1260 EventHandler.Events (suspend_policy, events);
1267 internal IEventHandler EventHandler {
1271 static String CommandString (CommandSet command_set, int command)
1274 switch (command_set) {
1276 cmd = ((CmdVM)command).ToString ();
1278 case CommandSet.OBJECT_REF:
1279 cmd = ((CmdObjectRef)command).ToString ();
1281 case CommandSet.STRING_REF:
1282 cmd = ((CmdStringRef)command).ToString ();
1284 case CommandSet.THREAD:
1285 cmd = ((CmdThread)command).ToString ();
1287 case CommandSet.ARRAY_REF:
1288 cmd = ((CmdArrayRef)command).ToString ();
1290 case CommandSet.EVENT_REQUEST:
1291 cmd = ((CmdEventRequest)command).ToString ();
1293 case CommandSet.STACK_FRAME:
1294 cmd = ((CmdStackFrame)command).ToString ();
1296 case CommandSet.APPDOMAIN:
1297 cmd = ((CmdAppDomain)command).ToString ();
1299 case CommandSet.ASSEMBLY:
1300 cmd = ((CmdAssembly)command).ToString ();
1302 case CommandSet.METHOD:
1303 cmd = ((CmdMethod)command).ToString ();
1305 case CommandSet.TYPE:
1306 cmd = ((CmdType)command).ToString ();
1308 case CommandSet.MODULE:
1309 cmd = ((CmdModule)command).ToString ();
1311 case CommandSet.EVENT:
1312 cmd = ((CmdEvent)command).ToString ();
1315 cmd = command.ToString ();
1318 return string.Format ("[{0} {1}]", command_set, cmd);
1321 long total_protocol_ticks;
1323 void LogPacket (int packet_id, byte[] encoded_packet, byte[] reply_packet, CommandSet command_set, int command, Stopwatch watch) {
1325 total_protocol_ticks += watch.ElapsedTicks;
1326 var ts = TimeSpan.FromTicks (total_protocol_ticks);
1327 string msg = string.Format ("Packet: {0} sent: {1} received: {2} ms: {3} total ms: {4} {5}",
1328 packet_id, encoded_packet.Length, reply_packet.Length, watch.ElapsedMilliseconds,
1329 (ts.Seconds * 1000) + ts.Milliseconds,
1330 CommandString (command_set, command));
1332 LoggingStream.WriteLine (msg);
1333 LoggingStream.Flush ();
1336 /* Send a request and call cb when a result is received */
1337 int Send (CommandSet command_set, int command, PacketWriter packet, Action<PacketReader> cb) {
1338 int id = IdGenerator;
1340 Stopwatch watch = null;
1341 if (EnableConnectionLogging)
1342 watch = Stopwatch.StartNew ();
1344 byte[] encoded_packet;
1346 encoded_packet = EncodePacket (id, (int)command_set, command, null, 0);
1348 encoded_packet = EncodePacket (id, (int)command_set, command, packet.Data, packet.Offset);
1350 lock (reply_packets_monitor) {
1351 reply_cbs [id] = delegate (int packet_id, byte[] p) {
1352 if (EnableConnectionLogging)
1353 LogPacket (packet_id, encoded_packet, p, command_set, command, watch);
1354 /* Run the callback on a tp thread to avoid blocking the receive thread */
1355 PacketReader r = new PacketReader (p);
1356 cb.BeginInvoke (r, null, null);
1360 WritePacket (encoded_packet);
1365 PacketReader SendReceive (CommandSet command_set, int command, PacketWriter packet) {
1366 int id = IdGenerator;
1367 Stopwatch watch = null;
1370 throw new VMDisconnectedException ();
1372 if (EnableConnectionLogging)
1373 watch = Stopwatch.StartNew ();
1375 byte[] encoded_packet;
1378 encoded_packet = EncodePacket (id, (int)command_set, command, null, 0);
1380 encoded_packet = EncodePacket (id, (int)command_set, command, packet.Data, packet.Offset);
1382 WritePacket (encoded_packet);
1386 /* Wait for the reply packet */
1388 lock (reply_packets_monitor) {
1389 if (reply_packets.ContainsKey (packetId)) {
1390 byte[] reply = reply_packets [packetId];
1391 reply_packets.Remove (packetId);
1392 PacketReader r = new PacketReader (reply);
1394 if (EnableConnectionLogging)
1395 LogPacket (packetId, encoded_packet, reply, command_set, command, watch);
1396 if (r.ErrorCode != 0) {
1397 if (ErrorHandler != null)
1398 ErrorHandler (this, new ErrorHandlerEventArgs () { ErrorCode = (ErrorCode)r.ErrorCode });
1399 throw new NotImplementedException ("No error handler set.");
1405 throw new VMDisconnectedException ();
1406 Monitor.Wait (reply_packets_monitor);
1412 PacketReader SendReceive (CommandSet command_set, int command) {
1413 return SendReceive (command_set, command, null);
1416 int packet_id_generator;
1420 return Interlocked.Increment (ref packet_id_generator);
1424 CattrInfo[] ReadCattrs (PacketReader r) {
1425 CattrInfo[] res = new CattrInfo [r.ReadInt ()];
1426 for (int i = 0; i < res.Length; ++i) {
1427 CattrInfo info = new CattrInfo ();
1428 info.ctor_id = r.ReadId ();
1429 info.ctor_args = new ValueImpl [r.ReadInt ()];
1430 for (int j = 0; j < info.ctor_args.Length; ++j) {
1431 info.ctor_args [j] = r.ReadValue ();
1433 info.named_args = new CattrNamedArgInfo [r.ReadInt ()];
1434 for (int j = 0; j < info.named_args.Length; ++j) {
1435 CattrNamedArgInfo arg = new CattrNamedArgInfo ();
1436 int arg_type = r.ReadByte ();
1437 arg.is_property = arg_type == 0x54;
1438 arg.id = r.ReadId ();
1439 arg.value = r.ReadValue ();
1440 info.named_args [j] = arg;
1447 static ElementType TypeCodeToElementType (TypeCode c) {
1449 case TypeCode.Boolean:
1450 return ElementType.Boolean;
1452 return ElementType.Char;
1453 case TypeCode.SByte:
1454 return ElementType.I1;
1456 return ElementType.U1;
1457 case TypeCode.Int16:
1458 return ElementType.I2;
1459 case TypeCode.UInt16:
1460 return ElementType.U2;
1461 case TypeCode.Int32:
1462 return ElementType.I4;
1463 case TypeCode.UInt32:
1464 return ElementType.U4;
1465 case TypeCode.Int64:
1466 return ElementType.I8;
1467 case TypeCode.UInt64:
1468 return ElementType.U8;
1469 case TypeCode.Single:
1470 return ElementType.R4;
1471 case TypeCode.Double:
1472 return ElementType.R8;
1474 throw new NotImplementedException ();
1479 * Implementation of debugger commands
1482 internal VersionInfo VM_GetVersion () {
1483 var res = SendReceive (CommandSet.VM, (int)CmdVM.VERSION, null);
1484 VersionInfo info = new VersionInfo ();
1485 info.VMVersion = res.ReadString ();
1486 info.MajorVersion = res.ReadInt ();
1487 info.MinorVersion = res.ReadInt ();
1491 internal void VM_SetProtocolVersion (int major, int minor) {
1492 SendReceive (CommandSet.VM, (int)CmdVM.SET_PROTOCOL_VERSION, new PacketWriter ().WriteInt (major).WriteInt (minor));
1495 internal long[] VM_GetThreads () {
1496 var res = SendReceive (CommandSet.VM, (int)CmdVM.ALL_THREADS, null);
1497 int len = res.ReadInt ();
1498 long[] arr = new long [len];
1499 for (int i = 0; i < len; ++i)
1500 arr [i] = res.ReadId ();
1504 internal void VM_Suspend () {
1505 SendReceive (CommandSet.VM, (int)CmdVM.SUSPEND);
1508 internal void VM_Resume () {
1509 SendReceive (CommandSet.VM, (int)CmdVM.RESUME);
1512 internal void VM_Exit (int exitCode) {
1513 SendReceive (CommandSet.VM, (int)CmdVM.EXIT, new PacketWriter ().WriteInt (exitCode));
1516 internal void VM_Dispose () {
1517 SendReceive (CommandSet.VM, (int)CmdVM.DISPOSE);
1520 internal ValueImpl VM_InvokeMethod (long thread, long method, ValueImpl this_arg, ValueImpl[] arguments, InvokeFlags flags, out ValueImpl exc) {
1522 PacketReader r = SendReceive (CommandSet.VM, (int)CmdVM.INVOKE_METHOD, new PacketWriter ().WriteId (thread).WriteInt ((int)flags).WriteId (method).WriteValue (this_arg).WriteInt (arguments.Length).WriteValues (arguments));
1523 if (r.ReadByte () == 0) {
1524 exc = r.ReadValue ();
1527 return r.ReadValue ();
1531 internal delegate void InvokeMethodCallback (ValueImpl v, ValueImpl exc, ErrorCode error, object state);
1533 internal int VM_BeginInvokeMethod (long thread, long method, ValueImpl this_arg, ValueImpl[] arguments, InvokeFlags flags, InvokeMethodCallback callback, object state) {
1534 return Send (CommandSet.VM, (int)CmdVM.INVOKE_METHOD, new PacketWriter ().WriteId (thread).WriteInt ((int)flags).WriteId (method).WriteValue (this_arg).WriteInt (arguments.Length).WriteValues (arguments), delegate (PacketReader r) {
1537 if (r.ErrorCode != 0) {
1538 callback (null, null, (ErrorCode)r.ErrorCode, state);
1540 if (r.ReadByte () == 0) {
1541 exc = r.ReadValue ();
1548 callback (v, exc, 0, state);
1553 internal void VM_AbortInvoke (long thread, int id)
1555 SendReceive (CommandSet.VM, (int)CmdVM.ABORT_INVOKE, new PacketWriter ().WriteId (thread).WriteInt (id));
1558 internal void SetSocketTimeouts (int send_timeout, int receive_timeout, int keepalive_interval)
1560 TransportSetTimeouts (send_timeout, receive_timeout);
1561 SendReceive (CommandSet.VM, (int)CmdVM.SET_KEEPALIVE, new PacketWriter ().WriteId (keepalive_interval));
1564 internal long[] VM_GetTypesForSourceFile (string fname, bool ignoreCase) {
1565 var res = SendReceive (CommandSet.VM, (int)CmdVM.GET_TYPES_FOR_SOURCE_FILE, new PacketWriter ().WriteString (fname).WriteBool (ignoreCase));
1566 int count = res.ReadInt ();
1567 long[] types = new long [count];
1568 for (int i = 0; i < count; ++i)
1569 types [i] = res.ReadId ();
1573 internal long[] VM_GetTypes (string name, bool ignoreCase) {
1574 var res = SendReceive (CommandSet.VM, (int)CmdVM.GET_TYPES, new PacketWriter ().WriteString (name).WriteBool (ignoreCase));
1575 int count = res.ReadInt ();
1576 long[] types = new long [count];
1577 for (int i = 0; i < count; ++i)
1578 types [i] = res.ReadId ();
1586 internal long RootDomain {
1588 return SendReceive (CommandSet.APPDOMAIN, (int)CmdAppDomain.GET_ROOT_DOMAIN, null).ReadId ();
1592 internal string Domain_GetName (long id) {
1593 return SendReceive (CommandSet.APPDOMAIN, (int)CmdAppDomain.GET_FRIENDLY_NAME, new PacketWriter ().WriteId (id)).ReadString ();
1596 internal long[] Domain_GetAssemblies (long id) {
1597 var res = SendReceive (CommandSet.APPDOMAIN, (int)CmdAppDomain.GET_ASSEMBLIES, new PacketWriter ().WriteId (id));
1598 int count = res.ReadInt ();
1599 long[] assemblies = new long [count];
1600 for (int i = 0; i < count; ++i)
1601 assemblies [i] = res.ReadId ();
1605 internal long Domain_GetEntryAssembly (long id) {
1606 return SendReceive (CommandSet.APPDOMAIN, (int)CmdAppDomain.GET_ENTRY_ASSEMBLY, new PacketWriter ().WriteId (id)).ReadId ();
1609 internal long Domain_GetCorlib (long id) {
1610 return SendReceive (CommandSet.APPDOMAIN, (int)CmdAppDomain.GET_CORLIB, new PacketWriter ().WriteId (id)).ReadId ();
1613 internal long Domain_CreateString (long id, string s) {
1614 return SendReceive (CommandSet.APPDOMAIN, (int)CmdAppDomain.CREATE_STRING, new PacketWriter ().WriteId (id).WriteString (s)).ReadId ();
1617 internal long Domain_CreateBoxedValue (long id, long type_id, ValueImpl v) {
1618 return SendReceive (CommandSet.APPDOMAIN, (int)CmdAppDomain.CREATE_BOXED_VALUE, new PacketWriter ().WriteId (id).WriteId (type_id).WriteValue (v)).ReadId ();
1625 internal string Method_GetName (long id) {
1626 return SendReceive (CommandSet.METHOD, (int)CmdMethod.GET_NAME, new PacketWriter ().WriteId (id)).ReadString ();
1629 internal long Method_GetDeclaringType (long id) {
1630 return SendReceive (CommandSet.METHOD, (int)CmdMethod.GET_DECLARING_TYPE, new PacketWriter ().WriteId (id)).ReadId ();
1633 internal DebugInfo Method_GetDebugInfo (long id) {
1634 var res = SendReceive (CommandSet.METHOD, (int)CmdMethod.GET_DEBUG_INFO, new PacketWriter ().WriteId (id));
1636 DebugInfo info = new DebugInfo ();
1637 info.max_il_offset = res.ReadInt ();
1638 info.filename = res.ReadString ();
1640 int n_il_offsets = res.ReadInt ();
1641 info.il_offsets = new int [n_il_offsets];
1642 info.line_numbers = new int [n_il_offsets];
1643 for (int i = 0; i < n_il_offsets; ++i) {
1644 info.il_offsets [i] = res.ReadInt ();
1645 info.line_numbers [i] = res.ReadInt ();
1651 internal ParamInfo Method_GetParamInfo (long id) {
1652 var res = SendReceive (CommandSet.METHOD, (int)CmdMethod.GET_PARAM_INFO, new PacketWriter ().WriteId (id));
1654 ParamInfo info = new ParamInfo ();
1655 info.call_conv = res.ReadInt ();
1656 info.param_count = res.ReadInt ();
1657 info.generic_param_count = res.ReadInt ();
1658 info.ret_type = res.ReadId ();
1659 info.param_types = new long [info.param_count];
1660 for (int i = 0; i < info.param_count; ++i)
1661 info.param_types [i] = res.ReadId ();
1662 info.param_names = new string [info.param_count];
1663 for (int i = 0; i < info.param_count; ++i)
1664 info.param_names [i] = res.ReadString ();
1669 internal LocalsInfo Method_GetLocalsInfo (long id) {
1670 var res = SendReceive (CommandSet.METHOD, (int)CmdMethod.GET_LOCALS_INFO, new PacketWriter ().WriteId (id));
1672 LocalsInfo info = new LocalsInfo ();
1673 int nlocals = res.ReadInt ();
1674 info.types = new long [nlocals];
1675 for (int i = 0; i < nlocals; ++i)
1676 info.types [i] = res.ReadId ();
1677 info.names = new string [nlocals];
1678 for (int i = 0; i < nlocals; ++i)
1679 info.names [i] = res.ReadString ();
1680 info.live_range_start = new int [nlocals];
1681 info.live_range_end = new int [nlocals];
1682 for (int i = 0; i < nlocals; ++i) {
1683 info.live_range_start [i] = res.ReadInt ();
1684 info.live_range_end [i] = res.ReadInt ();
1690 internal MethodInfo Method_GetInfo (long id) {
1691 var res = SendReceive (CommandSet.METHOD, (int)CmdMethod.GET_INFO, new PacketWriter ().WriteId (id));
1693 MethodInfo info = new MethodInfo ();
1694 info.attributes = res.ReadInt ();
1695 info.iattributes = res.ReadInt ();
1696 info.token = res.ReadInt ();
1697 if (Version.AtLeast (2, 12)) {
1698 int attrs = res.ReadByte ();
1699 if ((attrs & (1 << 0)) != 0)
1701 if ((attrs & (1 << 1)) != 0)
1702 info.is_generic_method = true;
1703 info.gmd = res.ReadId ();
1708 internal MethodBodyInfo Method_GetBody (long id) {
1709 var res = SendReceive (CommandSet.METHOD, (int)CmdMethod.GET_BODY, new PacketWriter ().WriteId (id));
1711 MethodBodyInfo info = new MethodBodyInfo ();
1712 info.il = new byte [res.ReadInt ()];
1713 for (int i = 0; i < info.il.Length; ++i)
1714 info.il [i] = (byte)res.ReadByte ();
1719 internal ResolvedToken Method_ResolveToken (long id, int token) {
1720 var res = SendReceive (CommandSet.METHOD, (int)CmdMethod.RESOLVE_TOKEN, new PacketWriter ().WriteId (id).WriteInt (token));
1722 TokenType type = (TokenType)res.ReadByte ();
1724 case TokenType.STRING:
1725 return new ResolvedToken () { Type = type, Str = res.ReadString () };
1726 case TokenType.TYPE:
1727 case TokenType.METHOD:
1728 case TokenType.FIELD:
1729 return new ResolvedToken () { Type = type, Id = res.ReadId () };
1730 case TokenType.UNKNOWN:
1731 return new ResolvedToken () { Type = type };
1733 throw new NotImplementedException ();
1741 internal string Thread_GetName (long id) {
1742 return SendReceive (CommandSet.THREAD, (int)CmdThread.GET_NAME, new PacketWriter ().WriteId (id)).ReadString ();
1745 internal FrameInfo[] Thread_GetFrameInfo (long id, int start_frame, int length) {
1746 var res = SendReceive (CommandSet.THREAD, (int)CmdThread.GET_FRAME_INFO, new PacketWriter ().WriteId (id).WriteInt (start_frame).WriteInt (length));
1747 int count = res.ReadInt ();
1749 var frames = new FrameInfo [count];
1750 for (int i = 0; i < count; ++i) {
1751 frames [i].id = res.ReadInt ();
1752 frames [i].method = res.ReadId ();
1753 frames [i].il_offset = res.ReadInt ();
1754 frames [i].flags = (StackFrameFlags)res.ReadByte ();
1759 internal int Thread_GetState (long id) {
1760 return SendReceive (CommandSet.THREAD, (int)CmdThread.GET_STATE, new PacketWriter ().WriteId (id)).ReadInt ();
1763 internal ThreadInfo Thread_GetInfo (long id) {
1764 PacketReader r = SendReceive (CommandSet.THREAD, (int)CmdThread.GET_INFO, new PacketWriter ().WriteId (id));
1766 ThreadInfo res = new ThreadInfo () { is_thread_pool = r.ReadByte () > 0 ? true : false };
1771 internal long Thread_GetId (long id) {
1772 return SendReceive (CommandSet.THREAD, (int)CmdThread.GET_ID, new PacketWriter ().WriteId (id)).ReadLong ();
1775 internal long Thread_GetTID (long id) {
1776 return SendReceive (CommandSet.THREAD, (int)CmdThread.GET_TID, new PacketWriter ().WriteId (id)).ReadLong ();
1783 internal ModuleInfo Module_GetInfo (long id) {
1784 PacketReader r = SendReceive (CommandSet.MODULE, (int)CmdModule.GET_INFO, new PacketWriter ().WriteId (id));
1785 ModuleInfo info = new ModuleInfo { Name = r.ReadString (), ScopeName = r.ReadString (), FQName = r.ReadString (), Guid = r.ReadString (), Assembly = r.ReadId () };
1793 internal string Assembly_GetLocation (long id) {
1794 return SendReceive (CommandSet.ASSEMBLY, (int)CmdAssembly.GET_LOCATION, new PacketWriter ().WriteId (id)).ReadString ();
1797 internal long Assembly_GetEntryPoint (long id) {
1798 return SendReceive (CommandSet.ASSEMBLY, (int)CmdAssembly.GET_ENTRY_POINT, new PacketWriter ().WriteId (id)).ReadId ();
1801 internal long Assembly_GetManifestModule (long id) {
1802 return SendReceive (CommandSet.ASSEMBLY, (int)CmdAssembly.GET_MANIFEST_MODULE, new PacketWriter ().WriteId (id)).ReadId ();
1805 internal long Assembly_GetObject (long id) {
1806 return SendReceive (CommandSet.ASSEMBLY, (int)CmdAssembly.GET_OBJECT, new PacketWriter ().WriteId (id)).ReadId ();
1809 internal long Assembly_GetType (long id, string name, bool ignoreCase) {
1810 return SendReceive (CommandSet.ASSEMBLY, (int)CmdAssembly.GET_TYPE, new PacketWriter ().WriteId (id).WriteString (name).WriteBool (ignoreCase)).ReadId ();
1813 internal string Assembly_GetName (long id) {
1814 return SendReceive (CommandSet.ASSEMBLY, (int)CmdAssembly.GET_NAME, new PacketWriter ().WriteId (id)).ReadString ();
1821 internal TypeInfo Type_GetInfo (long id) {
1822 PacketReader r = SendReceive (CommandSet.TYPE, (int)CmdType.GET_INFO, new PacketWriter ().WriteId (id));
1823 TypeInfo res = new TypeInfo ();
1825 res.ns = r.ReadString ();
1826 res.name = r.ReadString ();
1827 res.full_name = r.ReadString ();
1828 res.assembly = r.ReadId ();
1829 res.module = r.ReadId ();
1830 res.base_type = r.ReadId ();
1831 res.element_type = r.ReadId ();
1832 res.token = r.ReadInt ();
1833 res.rank = r.ReadByte ();
1834 res.attributes = r.ReadInt ();
1835 int b = r.ReadByte ();
1836 res.is_byref = (b & 1) != 0;
1837 res.is_pointer = (b & 2) != 0;
1838 res.is_primitive = (b & 4) != 0;
1839 res.is_valuetype = (b & 8) != 0;
1840 res.is_enum = (b & 16) != 0;
1841 res.is_gtd = (b & 32) != 0;
1842 res.is_generic_type = (b & 64) != 0;
1844 int nested_len = r.ReadInt ();
1845 res.nested = new long [nested_len];
1846 for (int i = 0; i < nested_len; ++i)
1847 res.nested [i] = r.ReadId ();
1849 if (Version.AtLeast (2, 12))
1850 res.gtd = r.ReadId ();
1855 internal long[] Type_GetMethods (long id) {
1856 PacketReader r = SendReceive (CommandSet.TYPE, (int)CmdType.GET_METHODS, new PacketWriter ().WriteId (id));
1858 int n = r.ReadInt ();
1859 long[] res = new long [n];
1860 for (int i = 0; i < n; ++i)
1861 res [i] = r.ReadId ();
1865 internal long[] Type_GetFields (long id, out string[] names, out long[] types, out int[] attrs) {
1866 PacketReader r = SendReceive (CommandSet.TYPE, (int)CmdType.GET_FIELDS, new PacketWriter ().WriteId (id));
1868 int n = r.ReadInt ();
1869 long[] res = new long [n];
1870 names = new string [n];
1871 types = new long [n];
1872 attrs = new int [n];
1873 for (int i = 0; i < n; ++i) {
1874 res [i] = r.ReadId ();
1875 names [i] = r.ReadString ();
1876 types [i] = r.ReadId ();
1877 attrs [i] = r.ReadInt ();
1882 internal PropInfo[] Type_GetProperties (long id) {
1883 PacketReader r = SendReceive (CommandSet.TYPE, (int)CmdType.GET_PROPERTIES, new PacketWriter ().WriteId (id));
1885 int n = r.ReadInt ();
1886 PropInfo[] res = new PropInfo [n];
1887 for (int i = 0; i < n; ++i) {
1888 res [i] = new PropInfo ();
1889 res [i].id = r.ReadId ();
1890 res [i].name = r.ReadString ();
1891 res [i].get_method = r.ReadId ();
1892 res [i].set_method = r.ReadId ();
1893 res [i].attrs = r.ReadInt ();
1899 internal long Type_GetObject (long id) {
1900 return SendReceive (CommandSet.TYPE, (int)CmdType.GET_OBJECT, new PacketWriter ().WriteId (id)).ReadId ();
1903 internal ValueImpl[] Type_GetValues (long id, long[] fields, long thread_id) {
1904 int len = fields.Length;
1907 r = SendReceive (CommandSet.TYPE, (int)CmdType.GET_VALUES_2, new PacketWriter ().WriteId (id).WriteId (thread_id).WriteInt (len).WriteIds (fields));
1909 r = SendReceive (CommandSet.TYPE, (int)CmdType.GET_VALUES, new PacketWriter ().WriteId (id).WriteInt (len).WriteIds (fields));
1911 ValueImpl[] res = new ValueImpl [len];
1912 for (int i = 0; i < len; ++i)
1913 res [i] = r.ReadValue ();
1917 internal void Type_SetValues (long id, long[] fields, ValueImpl[] values) {
1918 SendReceive (CommandSet.TYPE, (int)CmdType.SET_VALUES, new PacketWriter ().WriteId (id).WriteInt (fields.Length).WriteIds (fields).WriteValues (values));
1921 internal string[] Type_GetSourceFiles (long id, bool return_full_paths) {
1922 var r = SendReceive (CommandSet.TYPE, return_full_paths ? (int)CmdType.GET_SOURCE_FILES_2 : (int)CmdType.GET_SOURCE_FILES, new PacketWriter ().WriteId (id));
1923 int len = r.ReadInt ();
1924 string[] res = new string [len];
1925 for (int i = 0; i < len; ++i)
1926 res [i] = r.ReadString ();
1930 internal bool Type_IsAssignableFrom (long id, long c_id) {
1931 return SendReceive (CommandSet.TYPE, (int)CmdType.IS_ASSIGNABLE_FROM, new PacketWriter ().WriteId (id).WriteId (c_id)).ReadByte () > 0;
1934 internal CattrInfo[] Type_GetCustomAttributes (long id, long attr_type_id, bool inherit) {
1935 PacketReader r = SendReceive (CommandSet.TYPE, (int)CmdType.GET_CATTRS, new PacketWriter ().WriteId (id).WriteId (attr_type_id));
1936 return ReadCattrs (r);
1939 internal CattrInfo[] Type_GetFieldCustomAttributes (long id, long field_id, long attr_type_id, bool inherit) {
1940 PacketReader r = SendReceive (CommandSet.TYPE, (int)CmdType.GET_FIELD_CATTRS, new PacketWriter ().WriteId (id).WriteId (field_id).WriteId (attr_type_id));
1941 return ReadCattrs (r);
1944 internal CattrInfo[] Type_GetPropertyCustomAttributes (long id, long field_id, long attr_type_id, bool inherit) {
1945 PacketReader r = SendReceive (CommandSet.TYPE, (int)CmdType.GET_PROPERTY_CATTRS, new PacketWriter ().WriteId (id).WriteId (field_id).WriteId (attr_type_id));
1946 return ReadCattrs (r);
1949 public long[] Type_GetMethodsByNameFlags (long id, string name, int flags, bool ignoreCase) {
1950 flags |= ignoreCase ? (int)BindingFlagsExtensions.BINDING_FLAGS_IGNORE_CASE : 0;
1951 PacketReader r = SendReceive (CommandSet.TYPE, (int)CmdType.CMD_TYPE_GET_METHODS_BY_NAME_FLAGS, new PacketWriter ().WriteId (id).WriteString (name).WriteInt (flags));
1952 int len = r.ReadInt ();
1953 long[] res = new long [len];
1954 for (int i = 0; i < len; ++i)
1955 res [i] = r.ReadId ();
1959 internal long[] Type_GetInterfaces (long id) {
1960 PacketReader r = SendReceive (CommandSet.TYPE, (int)CmdType.GET_INTERFACES, new PacketWriter ().WriteId (id));
1961 int len = r.ReadInt ();
1962 return r.ReadIds (len);
1965 internal IfaceMapInfo[] Type_GetInterfaceMap (long id, long[] ids) {
1966 PacketReader r = SendReceive (CommandSet.TYPE, (int)CmdType.GET_INTERFACE_MAP, new PacketWriter ().WriteId (id).WriteInt (ids.Length).WriteIds (ids));
1967 var res = new IfaceMapInfo [ids.Length];
1968 for (int i = 0; i < ids.Length; ++i) {
1969 int n = r.ReadInt ();
1971 res [i].iface_id = ids [i];
1972 res [i].iface_methods = r.ReadIds (n);
1973 res [i].target_methods = r.ReadIds (n);
1983 internal int EnableEvent (EventType etype, SuspendPolicy suspend_policy, List<Modifier> mods) {
1984 var w = new PacketWriter ().WriteByte ((byte)etype).WriteByte ((byte)suspend_policy);
1986 if (mods.Count > 255)
1987 throw new NotImplementedException ();
1988 w.WriteByte ((byte)mods.Count);
1989 foreach (Modifier mod in mods) {
1990 if (mod is CountModifier) {
1991 w.WriteByte ((byte)ModifierKind.COUNT);
1992 w.WriteInt ((mod as CountModifier).Count);
1993 } else if (mod is LocationModifier) {
1994 w.WriteByte ((byte)ModifierKind.LOCATION_ONLY);
1995 w.WriteId ((mod as LocationModifier).Method);
1996 w.WriteLong ((mod as LocationModifier).Location);
1997 } else if (mod is StepModifier) {
1998 w.WriteByte ((byte)ModifierKind.STEP);
1999 w.WriteId ((mod as StepModifier).Thread);
2000 w.WriteInt ((mod as StepModifier).Size);
2001 w.WriteInt ((mod as StepModifier).Depth);
2002 } else if (mod is ThreadModifier) {
2003 w.WriteByte ((byte)ModifierKind.THREAD_ONLY);
2004 w.WriteId ((mod as ThreadModifier).Thread);
2005 } else if (mod is ExceptionModifier) {
2006 var em = mod as ExceptionModifier;
2007 w.WriteByte ((byte)ModifierKind.EXCEPTION_ONLY);
2008 w.WriteId (em.Type);
2009 if (Version.MajorVersion > 2 || Version.MinorVersion > 0) {
2010 /* This is only supported in protocol version 2.1 */
2011 w.WriteBool (em.Caught);
2012 w.WriteBool (em.Uncaught);
2013 } else if (!em.Caught || !em.Uncaught) {
2014 throw new NotSupportedException ("This request is not supported by the protocol version implemented by the debuggee.");
2016 } else if (mod is AssemblyModifier) {
2017 w.WriteByte ((byte)ModifierKind.ASSEMBLY_ONLY);
2018 var amod = (mod as AssemblyModifier);
2019 w.WriteInt (amod.Assemblies.Length);
2020 foreach (var id in amod.Assemblies)
2022 } else if (mod is SourceFileModifier) {
2023 w.WriteByte ((byte)ModifierKind.SOURCE_FILE_ONLY);
2024 var smod = (mod as SourceFileModifier);
2025 w.WriteInt (smod.SourceFiles.Length);
2026 foreach (var s in smod.SourceFiles)
2028 } else if (mod is TypeNameModifier) {
2029 w.WriteByte ((byte)ModifierKind.TYPE_NAME_ONLY);
2030 var tmod = (mod as TypeNameModifier);
2031 w.WriteInt (tmod.TypeNames.Length);
2032 foreach (var s in tmod.TypeNames)
2035 throw new NotImplementedException ();
2041 return SendReceive (CommandSet.EVENT_REQUEST, (int)CmdEventRequest.SET, w).ReadInt ();
2044 internal void ClearEventRequest (EventType etype, int req_id) {
2045 SendReceive (CommandSet.EVENT_REQUEST, (int)CmdEventRequest.CLEAR, new PacketWriter ().WriteByte ((byte)etype).WriteInt (req_id));
2048 internal void ClearAllBreakpoints () {
2049 SendReceive (CommandSet.EVENT_REQUEST, (int)CmdEventRequest.CLEAR_ALL_BREAKPOINTS, new PacketWriter ());
2055 internal ValueImpl StackFrame_GetThis (long thread_id, long id) {
2056 PacketReader r = SendReceive (CommandSet.STACK_FRAME, (int)CmdStackFrame.GET_THIS, new PacketWriter ().WriteId (thread_id).WriteId (id));
2057 return r.ReadValue ();
2060 internal ValueImpl[] StackFrame_GetValues (long thread_id, long id, int[] pos) {
2061 /* pos < 0 -> argument at pos (-pos) - 1 */
2062 /* pos >= 0 -> local at pos */
2063 int len = pos.Length;
2064 PacketReader r = SendReceive (CommandSet.STACK_FRAME, (int)CmdStackFrame.GET_VALUES, new PacketWriter ().WriteId (thread_id).WriteId (id).WriteInt (len).WriteInts (pos));
2066 ValueImpl[] res = new ValueImpl [len];
2067 for (int i = 0; i < len; ++i)
2068 res [i] = r.ReadValue ();
2072 internal void StackFrame_SetValues (long thread_id, long id, int[] pos, ValueImpl[] values) {
2073 /* pos < 0 -> argument at pos (-pos) - 1 */
2074 /* pos >= 0 -> local at pos */
2075 int len = pos.Length;
2076 SendReceive (CommandSet.STACK_FRAME, (int)CmdStackFrame.SET_VALUES, new PacketWriter ().WriteId (thread_id).WriteId (id).WriteInt (len).WriteInts (pos).WriteValues (values));
2082 internal int[] Array_GetLength (long id, out int rank, out int[] lower_bounds) {
2083 var r = SendReceive (CommandSet.ARRAY_REF, (int)CmdArrayRef.GET_LENGTH, new PacketWriter ().WriteId (id));
2084 rank = r.ReadInt ();
2085 int[] res = new int [rank];
2086 lower_bounds = new int [rank];
2087 for (int i = 0; i < rank; ++i) {
2088 res [i] = r.ReadInt ();
2089 lower_bounds [i] = r.ReadInt ();
2094 internal ValueImpl[] Array_GetValues (long id, int index, int len) {
2095 var r = SendReceive (CommandSet.ARRAY_REF, (int)CmdArrayRef.GET_VALUES, new PacketWriter ().WriteId (id).WriteInt (index).WriteInt (len));
2096 ValueImpl[] res = new ValueImpl [len];
2097 for (int i = 0; i < len; ++i)
2098 res [i] = r.ReadValue ();
2102 internal void Array_SetValues (long id, int index, ValueImpl[] values) {
2103 SendReceive (CommandSet.ARRAY_REF, (int)CmdArrayRef.SET_VALUES, new PacketWriter ().WriteId (id).WriteInt (index).WriteInt (values.Length).WriteValues (values));
2109 internal string String_GetValue (long id) {
2110 return SendReceive (CommandSet.STRING_REF, (int)CmdStringRef.GET_VALUE, new PacketWriter ().WriteId (id)).ReadString ();
2113 internal int String_GetLength (long id) {
2114 return (int)SendReceive (CommandSet.STRING_REF, (int)CmdStringRef.GET_LENGTH, new PacketWriter ().WriteId (id)).ReadLong ();
2117 internal char[] String_GetChars (long id, int index, int length) {
2118 var r = SendReceive (CommandSet.STRING_REF, (int)CmdStringRef.GET_CHARS, new PacketWriter ().WriteId (id).WriteLong (index).WriteLong (length));
2119 var res = new char [length];
2120 for (int i = 0; i < length; ++i)
2121 res [i] = (char)r.ReadShort ();
2128 internal long Object_GetType (long id) {
2129 return SendReceive (CommandSet.OBJECT_REF, (int)CmdObjectRef.GET_TYPE, new PacketWriter ().WriteId (id)).ReadId ();
2132 internal long Object_GetDomain (long id) {
2133 return SendReceive (CommandSet.OBJECT_REF, (int)CmdObjectRef.GET_DOMAIN, new PacketWriter ().WriteId (id)).ReadId ();
2136 internal ValueImpl[] Object_GetValues (long id, long[] fields) {
2137 int len = fields.Length;
2138 PacketReader r = SendReceive (CommandSet.OBJECT_REF, (int)CmdObjectRef.GET_VALUES, new PacketWriter ().WriteId (id).WriteInt (len).WriteIds (fields));
2140 ValueImpl[] res = new ValueImpl [len];
2141 for (int i = 0; i < len; ++i)
2142 res [i] = r.ReadValue ();
2146 internal void Object_SetValues (long id, long[] fields, ValueImpl[] values) {
2147 SendReceive (CommandSet.OBJECT_REF, (int)CmdObjectRef.SET_VALUES, new PacketWriter ().WriteId (id).WriteInt (fields.Length).WriteIds (fields).WriteValues (values));
2150 internal bool Object_IsCollected (long id) {
2151 return SendReceive (CommandSet.OBJECT_REF, (int)CmdObjectRef.IS_COLLECTED, new PacketWriter ().WriteId (id)).ReadInt () == 1;
2154 internal long Object_GetAddress (long id) {
2155 return SendReceive (CommandSet.OBJECT_REF, (int)CmdObjectRef.GET_ADDRESS, new PacketWriter ().WriteId (id)).ReadLong ();
2158 internal ObjectRefInfo Object_GetInfo (long id) {
2159 ObjectRefInfo res = new ObjectRefInfo ();
2160 PacketReader r = SendReceive (CommandSet.OBJECT_REF, (int)CmdObjectRef.GET_INFO, new PacketWriter ().WriteId (id));
2162 res.type_id = r.ReadId ();
2163 res.domain_id = r.ReadId ();
2169 class TcpConnection : Connection
2173 internal TcpConnection (Socket socket)
2175 this.socket = socket;
2176 //socket.SetSocketOption (SocketOptionLevel.IP, SocketOptionName.NoDelay, 1);
2179 internal EndPoint EndPoint {
2181 return socket.RemoteEndPoint;
2185 protected override int TransportSend (byte[] buf, int buf_offset, int len)
2187 return socket.Send (buf, buf_offset, len, SocketFlags.None);
2190 protected override int TransportReceive (byte[] buf, int buf_offset, int len)
2192 return socket.Receive (buf, buf_offset, len, SocketFlags.None);
2195 protected override void TransportSetTimeouts (int send_timeout, int receive_timeout)
2197 socket.SendTimeout = send_timeout;
2198 socket.ReceiveTimeout = receive_timeout;
2201 protected override void TransportClose ()
2207 /* This is the interface exposed by the debugger towards the debugger agent */
2208 interface IEventHandler
2210 void Events (SuspendPolicy suspend_policy, EventInfo[] events);
2212 void VMDisconnect (int req_id, long thread_id, string vm_uri);