4 using System
.Net
.Sockets
;
5 using System
.Threading
;
6 using System
.Collections
.Generic
;
8 using System
.Diagnostics
;
10 namespace Mono
.Debugger
.Soft
12 public class VersionInfo
{
13 public string VMVersion
{
17 public int MajorVersion
{
21 public int MinorVersion
{
26 * Check that this version is at least major:minor
28 public bool AtLeast (int major
, int minor
) {
29 if ((MajorVersion
> major
) || ((MajorVersion
== major
&& MinorVersion
>= minor
)))
37 public string source_file
;
42 public int max_il_offset
;
43 public int[] il_offsets
;
44 public int[] line_numbers
;
45 public int[] column_numbers
;
46 public int[] end_line_numbers
;
47 public int[] end_column_numbers
;
48 public SourceInfo
[] source_files
;
55 public StackFrameFlags flags
;
59 public string ns
, name
, full_name
;
60 public long assembly
, module
, base_type
, element_type
;
61 public int token
, rank
, attributes
;
62 public bool is_byref
, is_pointer
, is_primitive
, is_valuetype
, is_enum
;
63 public bool is_gtd
, is_generic_type
;
66 public long[] type_args
;
71 public long[] iface_methods
;
72 public long[] target_methods
;
76 public int attributes
, iattributes
, token
;
77 public bool is_gmd
, is_generic_method
;
79 public long[] type_args
;
82 class MethodBodyInfo
{
84 public ExceptionClauseInfo
[] clauses
;
87 struct ExceptionClauseInfo
{
88 public ExceptionClauseFlags flags
;
89 public int try_offset
;
90 public int try_length
;
91 public int handler_offset
;
92 public int handler_length
;
93 public int filter_offset
;
94 public long catch_type_id
;
98 enum ExceptionClauseFlags
{
106 public int call_conv
;
107 public int param_count
;
108 public int generic_param_count
;
109 public long ret_type
;
110 public long[] param_types
;
111 public string[] param_names
;
116 public string[] names
;
117 public int[] live_range_start
;
118 public int[] live_range_end
;
119 public int[] scopes_start
;
120 public int[] scopes_end
;
126 public long get_method
, set_method
;
130 class CattrNamedArgInfo
{
131 public bool is_property
;
133 public ValueImpl
value;
138 public ValueImpl
[] ctor_args
;
139 public CattrNamedArgInfo
[] named_args
;
143 public bool is_thread_pool
;
146 struct ObjectRefInfo
{
148 public long domain_id
;
152 VALUE_TYPE_ID_NULL
= 0xf0,
153 VALUE_TYPE_ID_TYPE
= 0xf1,
154 VALUE_TYPE_ID_PARENT_VTYPE
= 0xf2,
155 VALUE_TYPE_ID_FIXED_ARRAY
= 0xf3
161 DISABLE_BREAKPOINTS
= 1,
211 public ElementType Type
; /* or one of the VALUE_TYPE_ID constants */
214 public long Klass
; // For ElementType.ValueType
215 public ValueImpl
[] Fields
; // for ElementType.ValueType
216 public bool IsEnum
; // For ElementType.ValueType
217 public long Id
; /* For VALUE_TYPE_ID_TYPE */
218 public int Index
; /* For VALUE_TYPE_PARENT_VTYPE */
219 public int FixedSize
;
223 public string Name
, ScopeName
, FQName
, Guid
, SourceLink
;
224 public long Assembly
;
227 class FieldMirrorInfo
{
229 public long Parent
, TypeId
;
242 enum StackFrameFlags
{
245 NATIVE_TRANSITION
= 2
248 class ResolvedToken
{
249 public TokenType Type
;
257 class CountModifier
: Modifier
{
263 class LocationModifier
: Modifier
{
268 public long Location
{
273 class StepModifier
: Modifier
{
291 class ThreadModifier
: Modifier
{
297 class ExceptionModifier
: Modifier
{
304 public bool Uncaught
{
307 public bool Subclasses
{
310 public bool NotFilteredFeature
{
313 public bool EverythingElse
{
319 class AssemblyModifier
: Modifier
{
320 public long[] Assemblies
{
325 class SourceFileModifier
: Modifier
{
326 public string[] SourceFiles
{
331 class TypeNameModifier
: Modifier
{
332 public string[] TypeNames
{
338 public EventType EventType
{
346 public SuspendPolicy SuspendPolicy
{
350 public long ThreadId
{
358 public long Location
{
366 public string Category
{
370 public string Message
{
374 public int ExitCode
{
386 public EventInfo (EventType type
, int req_id
) {
392 public enum ErrorCode
{
395 INVALID_FIELDID
= 25,
396 INVALID_FRAMEID
= 30,
397 NOT_IMPLEMENTED
= 100,
399 INVALID_ARGUMENT
= 102,
401 ERR_NO_INVOCATION
= 104,
402 ABSENT_INFORMATION
= 105,
403 NO_SEQ_POINT_AT_IL_OFFSET
= 106,
407 public class ErrorHandlerEventArgs
: EventArgs
{
409 public ErrorCode ErrorCode
{
415 * Represents the connection to the debuggee
417 public abstract class Connection
420 * The protocol and the packet format is based on JDWP, the differences
421 * are in the set of supported events, and the commands.
423 internal const string HANDSHAKE_STRING
= "DWP-Handshake";
425 internal const int HEADER_LENGTH
= 11;
427 static readonly bool EnableConnectionLogging
= !String
.IsNullOrEmpty (Environment
.GetEnvironmentVariable ("MONO_SDB_LOG"));
428 static int ConnectionId
;
429 readonly StreamWriter LoggingStream
;
432 * Th version of the wire-protocol implemented by the library. The library
433 * and the debuggee can communicate if they implement the same major version.
434 * If they implement a different minor version, they can communicate, but some
435 * features might not be available. This allows older clients to communicate
436 * with newer runtimes, and vice versa.
438 internal const int MAJOR_VERSION
= 2;
439 internal const int MINOR_VERSION
= 55;
441 enum WPSuspendPolicy
{
470 APPDOMAIN_CREATE
= 4, // Not in JDI
471 APPDOMAIN_UNLOAD
= 5, // Not in JDI
493 SOURCE_FILE_ONLY
= 12,
505 SET_PROTOCOL_VERSION
= 8,
508 GET_TYPES_FOR_SOURCE_FILE
= 11,
511 START_BUFFERING
= 14,
524 /* FIXME: Merge into GET_INFO when the major protocol version is increased */
532 enum CmdEventRequest
{
535 CLEAR_ALL_BREAKPOINTS
= 3
540 GET_FRIENDLY_NAME
= 2,
542 GET_ENTRY_ASSEMBLY
= 4,
545 CREATE_BOXED_VALUE
= 7,
546 CREATE_BYTE_ARRAY
= 8,
552 GET_MANIFEST_MODULE
= 3,
557 GET_METADATA_BLOB
= 8,
560 GET_TYPE_FROM_TOKEN
= 11,
561 GET_METHOD_FROM_TOKEN
= 12,
571 GET_DECLARING_TYPE
= 2,
579 MAKE_GENERIC_METHOD
= 10
588 GET_SOURCE_FILES
= 6,
590 IS_ASSIGNABLE_FROM
= 8,
593 GET_FIELD_CATTRS
= 11,
594 GET_PROPERTY_CATTRS
= 12,
595 /* FIXME: Merge into GET_SOURCE_FILES when the major protocol version is increased */
596 GET_SOURCE_FILES_2
= 13,
597 /* FIXME: Merge into GET_VALUES when the major protocol version is increased */
599 CMD_TYPE_GET_METHODS_BY_NAME_FLAGS
= 15,
601 GET_INTERFACE_MAP
= 17,
603 CREATE_INSTANCE
= 19,
612 enum BindingFlagsExtensions
{
613 BINDING_FLAGS_IGNORE_CASE
= 0x70000000,
616 enum MemberListTypeExtensions
{
657 public int command_set
;
662 internal static int GetPacketLength (byte[] header
) {
664 return decode_int (header
, ref offset
);
667 internal static bool IsReplyPacket (byte[] packet
) {
669 return decode_byte (packet
, ref offset
) == 0x80;
672 internal static int GetPacketId (byte[] packet
) {
674 return decode_int (packet
, ref offset
);
677 static int decode_byte (byte[] packet
, ref int offset
) {
678 return packet
[offset
++];
681 static byte[] decode_bytes (byte[] packet
, ref int offset
, int length
)
683 if (length
+ offset
> packet
.Length
)
684 throw new ArgumentOutOfRangeException ();
686 var bytes
= new byte[length
];
687 Array
.Copy (packet
, offset
, bytes
, 0, length
);
692 static int decode_short (byte[] packet
, ref int offset
) {
693 int res
= ((int)packet
[offset
] << 8) | (int)packet
[offset
+ 1];
698 static int decode_int (byte[] packet
, ref int offset
) {
699 int res
= ((int)packet
[offset
] << 24) | ((int)packet
[offset
+ 1] << 16) | ((int)packet
[offset
+ 2] << 8) | (int)packet
[offset
+ 3];
704 static long decode_id (byte[] packet
, ref int offset
) {
705 return decode_int (packet
, ref offset
);
708 static long decode_long (byte[] packet
, ref int offset
) {
709 uint high
= (uint)decode_int (packet
, ref offset
);
710 uint low
= (uint)decode_int (packet
, ref offset
);
712 return (long)(((ulong)high
<< 32) | (ulong)low
);
715 internal static SuspendPolicy
decode_suspend_policy (int suspend_policy
) {
716 switch ((WPSuspendPolicy
)suspend_policy
) {
717 case WPSuspendPolicy
.NONE
:
718 return SuspendPolicy
.None
;
719 case WPSuspendPolicy
.EVENT_THREAD
:
720 return SuspendPolicy
.EventThread
;
721 case WPSuspendPolicy
.ALL
:
722 return SuspendPolicy
.All
;
724 throw new NotImplementedException ();
728 static Header
decode_command_header (byte[] packet
) {
730 Header res
= new Header ();
732 decode_int (packet
, ref offset
);
733 res
.id
= decode_int (packet
, ref offset
);
734 res
.flags
= decode_byte (packet
, ref offset
);
735 res
.command_set
= decode_byte (packet
, ref offset
);
736 res
.command
= decode_byte (packet
, ref offset
);
741 static void encode_byte (byte[] buf
, int b
, ref int offset
) {
742 buf
[offset
] = (byte)b
;
746 static void encode_int (byte[] buf
, int i
, ref int offset
) {
747 buf
[offset
] = (byte)((i
>> 24) & 0xff);
748 buf
[offset
+ 1] = (byte)((i
>> 16) & 0xff);
749 buf
[offset
+ 2] = (byte)((i
>> 8) & 0xff);
750 buf
[offset
+ 3] = (byte)((i
>> 0) & 0xff);
754 static void encode_id (byte[] buf
, long id
, ref int offset
) {
755 encode_int (buf
, (int)id
, ref offset
);
758 static void encode_long (byte[] buf
, long l
, ref int offset
) {
759 encode_int (buf
, (int)((l
>> 32) & 0xffffffff), ref offset
);
760 encode_int (buf
, (int)(l
& 0xffffffff), ref offset
);
763 internal static byte[] EncodePacket (int id
, int commandSet
, int command
, byte[] data
, int dataLen
) {
764 byte[] buf
= new byte [dataLen
+ 11];
767 encode_int (buf
, buf
.Length
, ref offset
);
768 encode_int (buf
, id
, ref offset
);
769 encode_byte (buf
, 0, ref offset
);
770 encode_byte (buf
, commandSet
, ref offset
);
771 encode_byte (buf
, command
, ref offset
);
773 for (int i
= 0; i
< dataLen
; ++i
)
774 buf
[offset
+ i
] = data
[i
];
780 Connection connection
;
784 public PacketReader (Connection connection
, byte[] packet
) {
785 this.connection
= connection
;
786 this.packet
= packet
;
789 Header header
= decode_command_header (packet
);
790 CommandSet
= (CommandSet
)header
.command_set
;
791 Command
= header
.command
;
795 ReadInt (); // length
797 ReadByte (); // flags
798 ErrorCode
= ReadShort ();
801 public CommandSet CommandSet
{
809 public int ErrorCode
{
819 public int ReadByte () {
820 return decode_byte (packet
, ref offset
);
823 public int ReadShort () {
824 return decode_short (packet
, ref offset
);
827 public int ReadInt () {
828 return decode_int (packet
, ref offset
);
831 public long ReadId () {
832 return decode_id (packet
, ref offset
);
835 public long ReadLong () {
836 return decode_long (packet
, ref offset
);
839 public float ReadFloat () {
840 float f
= DataConverter
.FloatFromBE (packet
, offset
);
845 public double ReadDouble () {
846 double d
= DataConverter
.DoubleFromBE (packet
, offset
);
851 public string ReadString () {
852 int len
= decode_int (packet
, ref offset
);
853 string res
= new String (Encoding
.UTF8
.GetChars (packet
, offset
, len
));
858 public string ReadUTF16String () {
859 int len
= decode_int (packet
, ref offset
);
860 string res
= new String (Encoding
.Unicode
.GetChars (packet
, offset
, len
));
865 public ValueImpl
ReadValue () {
866 ElementType etype
= (ElementType
)ReadByte ();
868 case ElementType
.Void
:
869 return new ValueImpl { Type = etype }
;
871 return new ValueImpl { Type = etype, Value = (sbyte)ReadInt () }
;
873 return new ValueImpl { Type = etype, Value = (byte)ReadInt () }
;
874 case ElementType
.Boolean
:
875 return new ValueImpl { Type = etype, Value = ReadInt () != 0 }
;
877 return new ValueImpl { Type = etype, Value = (short)ReadInt () }
;
879 return new ValueImpl { Type = etype, Value = (ushort)ReadInt () }
;
880 case ElementType
.Char
:
881 return new ValueImpl { Type = etype, Value = (char)ReadInt () }
;
883 return new ValueImpl { Type = etype, Value = ReadInt () }
;
885 return new ValueImpl { Type = etype, Value = (uint)ReadInt () }
;
887 return new ValueImpl { Type = etype, Value = ReadLong () }
;
889 return new ValueImpl { Type = etype, Value = (ulong)ReadLong () }
;
891 return new ValueImpl { Type = etype, Value = ReadFloat () }
;
893 return new ValueImpl { Type = etype, Value = ReadDouble () }
;
896 // FIXME: The client and the debuggee might have different word sizes
897 return new ValueImpl { Type = etype, Value = ReadLong () }
;
898 case ElementType
.Ptr
:
899 long value = ReadLong ();
900 if (connection
.Version
.AtLeast (2, 46)) {
901 long pointerClass
= ReadId ();
902 return new ValueImpl { Type = etype, Klass = pointerClass, Value = value }
;
904 return new ValueImpl { Type = etype, Value = value }
;
906 case ElementType
.String
:
907 case ElementType
.SzArray
:
908 case ElementType
.Class
:
909 case ElementType
.Array
:
910 case ElementType
.Object
:
911 long objid
= ReadId ();
912 return new ValueImpl () { Type = etype, Objid = objid }
;
913 case ElementType
.ValueType
:
914 bool is_enum
= ReadByte () == 1;
915 long klass
= ReadId ();
916 long nfields
= ReadInt ();
917 ValueImpl
[] fields
= new ValueImpl
[nfields
];
918 for (int i
= 0; i
< nfields
; ++i
)
919 fields
[i
] = ReadValue ();
920 return new ValueImpl () { Type = etype, Klass = klass, Fields = fields, IsEnum = is_enum }
;
921 case (ElementType
)ValueTypeId
.VALUE_TYPE_ID_NULL
:
922 return new ValueImpl { Type = etype }
;
923 case (ElementType
)ValueTypeId
.VALUE_TYPE_ID_TYPE
:
924 return new ValueImpl () { Type = etype, Id = ReadId () }
;
925 case (ElementType
)ValueTypeId
.VALUE_TYPE_ID_PARENT_VTYPE
:
926 return new ValueImpl () { Type = etype, Index = ReadInt () }
;
927 case (ElementType
)ValueTypeId
.VALUE_TYPE_ID_FIXED_ARRAY
:
928 return ReadValueFixedSize ();
930 throw new NotImplementedException ("Unable to handle type " + etype
);
934 ValueImpl
ReadValueFixedSize () {
935 var lenFixedSize
= 1;
936 ElementType etype
= (ElementType
)ReadByte ();
937 lenFixedSize
= ReadInt ();
939 case ElementType
.I1
: {
940 var val
= new sbyte[lenFixedSize
];
941 for (int i
= 0; i
< lenFixedSize
; i
++)
942 val
[i
] = (sbyte)ReadInt ();
943 return new ValueImpl { Type = etype, Value = val }
;
945 case ElementType
.U1
: {
946 var val
= new byte[lenFixedSize
];
947 for (int i
= 0; i
< lenFixedSize
; i
++)
948 val
[i
] = (byte)ReadInt ();
949 return new ValueImpl { Type = etype, Value = val }
;
951 case ElementType
.Boolean
: {
952 var val
= new bool[lenFixedSize
];
953 for (int i
= 0; i
< lenFixedSize
; i
++)
954 val
[i
] = (ReadInt () != 0);
955 return new ValueImpl { Type = etype, Value = val }
;
957 case ElementType
.I2
: {
958 var val
= new short[lenFixedSize
];
959 for (int i
= 0; i
< lenFixedSize
; i
++)
960 val
[i
] = (short)ReadInt ();
961 return new ValueImpl { Type = etype, Value = val }
;
963 case ElementType
.U2
: {
964 var val
= new ushort[lenFixedSize
];
965 for (int i
= 0; i
< lenFixedSize
; i
++)
966 val
[i
] = (ushort)ReadInt ();
967 return new ValueImpl { Type = etype, Value = val }
;
969 case ElementType
.Char
: {
970 var val
= new char[lenFixedSize
];
971 for (int i
= 0; i
< lenFixedSize
; i
++)
972 val
[i
] = (char)ReadInt ();
973 return new ValueImpl { Type = etype, Value = val }
;
975 case ElementType
.I4
: {
976 var val
= new int[lenFixedSize
];
977 for (int i
= 0; i
< lenFixedSize
; i
++)
979 return new ValueImpl { Type = etype, Value = val }
;
981 case ElementType
.U4
: {
982 var val
= new uint[lenFixedSize
];
983 for (int i
= 0; i
< lenFixedSize
; i
++)
984 val
[i
] = (uint)ReadInt ();
985 return new ValueImpl { Type = etype, Value = val }
;
987 case ElementType
.I8
: {
988 var val
= new long[lenFixedSize
];
989 for (int i
= 0; i
< lenFixedSize
; i
++)
990 val
[i
] = ReadLong ();
991 return new ValueImpl { Type = etype, Value = val }
;
993 case ElementType
.U8
: {
994 var val
= new ulong[lenFixedSize
];
995 for (int i
= 0; i
< lenFixedSize
; i
++)
996 val
[i
] = (ulong) ReadLong ();
997 return new ValueImpl { Type = etype, Value = val }
;
999 case ElementType
.R4
: {
1000 var val
= new float[lenFixedSize
];
1001 for (int i
= 0; i
< lenFixedSize
; i
++)
1002 val
[i
] = ReadFloat ();
1003 return new ValueImpl { Type = etype, Value = val }
;
1005 case ElementType
.R8
: {
1006 var val
= new double[lenFixedSize
];
1007 for (int i
= 0; i
< lenFixedSize
; i
++)
1008 val
[i
] = ReadDouble ();
1009 return new ValueImpl { Type = etype, Value = val }
;
1012 throw new NotImplementedException ("Unable to handle type " + etype
);
1015 public long[] ReadIds (int n
) {
1016 long[] res
= new long [n
];
1017 for (int i
= 0; i
< n
; ++i
)
1018 res
[i
] = ReadId ();
1022 public byte[] ReadByteArray () {
1023 var length
= ReadInt ();
1024 return decode_bytes (packet
, ref offset
, length
);
1027 public bool ReadBool () {
1028 return ReadByte () != 0;
1032 class PacketWriter
{
1037 public PacketWriter () {
1038 data
= new byte [1024];
1042 void MakeRoom (int size
) {
1043 if (offset
+ size
>= data
.Length
) {
1044 int new_len
= data
.Length
* 2;
1045 while (new_len
< offset
+ size
) {
1048 byte[] new_data
= new byte [new_len
];
1049 Array
.Copy (data
, new_data
, data
.Length
);
1054 public PacketWriter
WriteByte (byte val
) {
1056 encode_byte (data
, val
, ref offset
);
1060 public PacketWriter
WriteInt (int val
) {
1062 encode_int (data
, val
, ref offset
);
1066 public PacketWriter
WriteId (long id
) {
1068 encode_id (data
, id
, ref offset
);
1072 public PacketWriter
WriteLong (long val
) {
1074 encode_long (data
, val
, ref offset
);
1078 public PacketWriter
WriteFloat (float f
) {
1080 byte[] b
= DataConverter
.GetBytesBE (f
);
1081 for (int i
= 0; i
< 4; ++i
)
1082 data
[offset
+ i
] = b
[i
];
1087 public PacketWriter
WriteDouble (double d
) {
1089 byte[] b
= DataConverter
.GetBytesBE (d
);
1090 for (int i
= 0; i
< 8; ++i
)
1091 data
[offset
+ i
] = b
[i
];
1096 public PacketWriter
WriteInts (int[] ids
) {
1097 for (int i
= 0; i
< ids
.Length
; ++i
)
1102 public PacketWriter
WriteIds (long[] ids
) {
1103 for (int i
= 0; i
< ids
.Length
; ++i
)
1108 public PacketWriter
WriteString (string s
) {
1110 return WriteInt (-1);
1112 byte[] b
= Encoding
.UTF8
.GetBytes (s
);
1114 encode_int (data
, b
.Length
, ref offset
);
1115 MakeRoom (b
.Length
);
1116 Buffer
.BlockCopy (b
, 0, data
, offset
, b
.Length
);
1120 public PacketWriter
WriteBytes (byte[] b
) {
1122 return WriteInt (-1);
1124 encode_int (data
, b
.Length
, ref offset
);
1125 MakeRoom (b
.Length
);
1126 Buffer
.BlockCopy (b
, 0, data
, offset
, b
.Length
);
1131 public PacketWriter
WriteBool (bool val
) {
1132 WriteByte (val
? (byte)1 : (byte)0);
1136 public PacketWriter
WriteValue (ValueImpl v
) {
1139 if (v
.Value
!= null)
1140 t
= TypeCodeToElementType (Type
.GetTypeCode (v
.Value
.GetType ()), v
.Value
.GetType ());
1143 if (v
.FixedSize
> 1 && t
!= ElementType
.ValueType
) {
1144 WriteFixedSizeValue (v
);
1147 WriteByte ((byte)t
);
1149 case ElementType
.Boolean
:
1150 WriteInt ((bool)v
.Value
? 1 : 0);
1152 case ElementType
.Char
:
1153 WriteInt ((int)(char)v
.Value
);
1155 case ElementType
.I1
:
1156 WriteInt ((int)(sbyte)v
.Value
);
1158 case ElementType
.U1
:
1159 WriteInt ((int)(byte)v
.Value
);
1161 case ElementType
.I2
:
1162 WriteInt ((int)(short)v
.Value
);
1164 case ElementType
.U2
:
1165 WriteInt ((int)(ushort)v
.Value
);
1167 case ElementType
.I4
:
1168 WriteInt ((int)(int)v
.Value
);
1170 case ElementType
.U4
:
1171 WriteInt ((int)(uint)v
.Value
);
1173 case ElementType
.I8
:
1174 WriteLong ((long)(long)v
.Value
);
1176 case ElementType
.U8
:
1177 WriteLong ((long)(ulong)v
.Value
);
1179 case ElementType
.R4
:
1180 WriteFloat ((float)v
.Value
);
1182 case ElementType
.R8
:
1183 WriteDouble ((double)v
.Value
);
1185 case ElementType
.String
:
1186 case ElementType
.SzArray
:
1187 case ElementType
.Class
:
1188 case ElementType
.Array
:
1189 case ElementType
.Object
:
1192 case ElementType
.ValueType
:
1195 throw new NotImplementedException ();
1198 WriteInt (v
.Fields
.Length
);
1199 for (int i
= 0; i
< v
.Fields
.Length
; ++i
)
1200 WriteValue (v
.Fields
[i
]);
1202 case (ElementType
)ValueTypeId
.VALUE_TYPE_ID_NULL
:
1205 throw new NotImplementedException ();
1211 PacketWriter
WriteFixedSizeValue (ValueImpl v
) {
1214 if (v
.Value
!= null)
1215 t
= TypeCodeToElementType (Type
.GetTypeCode (v
.Value
.GetType ()), v
.Value
.GetType ());
1218 WriteByte ((byte) ValueTypeId
.VALUE_TYPE_ID_FIXED_ARRAY
);
1219 WriteByte ((byte)t
);
1220 WriteInt (v
.FixedSize
);
1221 for (int j
= 0 ; j
< v
.FixedSize
; j
++) {
1223 case ElementType
.Boolean
:
1224 WriteInt (((bool[])v
.Value
)[j
]? 1 : 0);
1226 case ElementType
.Char
:
1227 WriteInt ((int)((char[])v
.Value
)[j
]);
1229 case ElementType
.I1
:
1230 WriteInt ((int)((sbyte[])v
.Value
)[j
]);
1232 case ElementType
.U1
:
1233 WriteInt ((int)((byte[])v
.Value
)[j
]);
1235 case ElementType
.I2
:
1236 WriteInt ((int)((short[])v
.Value
)[j
]);
1238 case ElementType
.U2
:
1239 WriteInt ((int)((ushort[])v
.Value
)[j
]);
1241 case ElementType
.I4
:
1242 WriteInt ((int)((int[])v
.Value
)[j
]);
1244 case ElementType
.U4
:
1245 WriteInt ((int)((uint[])v
.Value
)[j
]);
1247 case ElementType
.I8
:
1248 WriteLong ((long)((long[])v
.Value
)[j
]);
1250 case ElementType
.U8
:
1251 WriteLong ((long)((ulong[])v
.Value
)[j
]);
1253 case ElementType
.R4
:
1254 WriteFloat (((float[])v
.Value
)[j
]);
1256 case ElementType
.R8
:
1257 WriteDouble (((double[])v
.Value
)[j
]);
1260 throw new NotImplementedException ();
1266 public PacketWriter
WriteValues (ValueImpl
[] values
) {
1267 for (int i
= 0; i
< values
.Length
; ++i
)
1268 WriteValue (values
[i
]);
1272 public byte[] Data
{
1285 delegate void ReplyCallback (int packet_id
, byte[] packet
);
1288 Thread receiver_thread
;
1289 Dictionary
<int, byte[]> reply_packets
;
1290 Dictionary
<int, ReplyCallback
> reply_cbs
;
1291 Dictionary
<int, int> reply_cb_counts
;
1292 object reply_packets_monitor
;
1294 internal event EventHandler
<ErrorHandlerEventArgs
> ErrorHandler
;
1296 protected Connection () {
1298 reply_packets
= new Dictionary
<int, byte[]> ();
1299 reply_cbs
= new Dictionary
<int, ReplyCallback
> ();
1300 reply_cb_counts
= new Dictionary
<int, int> ();
1301 reply_packets_monitor
= new Object ();
1302 if (EnableConnectionLogging
) {
1303 var path
= Environment
.GetEnvironmentVariable ("MONO_SDB_LOG");
1304 if (path
.Contains ("{0}")) {
1305 //C:\SomeDir\sdbLog{0}.txt -> C:\SomeDir\sdbLog1.txt
1306 LoggingStream
= new StreamWriter (string.Format (path
, ConnectionId
++), false);
1307 } else if (Path
.HasExtension (path
)) {
1308 //C:\SomeDir\sdbLog.txt -> C:\SomeDir\sdbLog1.txt
1309 LoggingStream
= new StreamWriter (Path
.GetDirectoryName (path
) + Path
.DirectorySeparatorChar
+ Path
.GetFileNameWithoutExtension (path
) + ConnectionId
++ + "." + Path
.GetExtension (path
), false);
1311 //C:\SomeDir\sdbLog -> C:\SomeDir\sdbLog1
1312 LoggingStream
= new StreamWriter (path
+ ConnectionId
++, false);
1317 protected abstract int TransportReceive (byte[] buf
, int buf_offset
, int len
);
1318 protected abstract int TransportSend (byte[] buf
, int buf_offset
, int len
);
1319 protected abstract void TransportSetTimeouts (int send_timeout
, int receive_timeout
);
1320 protected abstract void TransportClose ();
1321 // Shutdown breaks all communication, resuming blocking waits
1322 protected abstract void TransportShutdown ();
1324 internal VersionInfo Version
;
1326 int Receive (byte[] buf
, int buf_offset
, int len
) {
1329 while (offset
< len
) {
1330 int n
= TransportReceive (buf
, buf_offset
+ offset
, len
- offset
);
1340 // Do the wire protocol handshake
1341 internal void Connect () {
1342 byte[] buf
= new byte [HANDSHAKE_STRING
.Length
];
1343 char[] cbuf
= new char [buf
.Length
];
1345 // FIXME: Add a timeout
1346 int n
= Receive (buf
, 0, buf
.Length
);
1348 throw new IOException ("DWP Handshake failed.");
1349 for (int i
= 0; i
< buf
.Length
; ++i
)
1350 cbuf
[i
] = (char)buf
[i
];
1352 if (new String (cbuf
) != HANDSHAKE_STRING
)
1353 throw new IOException ("DWP Handshake failed.");
1355 TransportSend (buf
, 0, buf
.Length
);
1357 receiver_thread
= new Thread (new ThreadStart (receiver_thread_main
));
1358 receiver_thread
.Name
= "SDB Receiver";
1359 receiver_thread
.IsBackground
= true;
1360 receiver_thread
.Start ();
1362 Version
= VM_GetVersion ();
1365 // Tell the debuggee our protocol version, so newer debuggees can work
1366 // with older clients
1370 // Older debuggees might not support this request
1371 EventHandler
<ErrorHandlerEventArgs
> OrigErrorHandler
= ErrorHandler
;
1372 ErrorHandler
= null;
1373 ErrorHandler
+= delegate (object sender
, ErrorHandlerEventArgs args
) {
1374 throw new NotSupportedException ();
1377 VM_SetProtocolVersion (MAJOR_VERSION
, MINOR_VERSION
);
1378 } catch (NotSupportedException
) {
1380 ErrorHandler
= OrigErrorHandler
;
1383 internal byte[] ReadPacket () {
1384 // FIXME: Throw ClosedConnectionException () if the connection is closed
1385 // FIXME: Throw ClosedConnectionException () if another thread closes the connection
1387 byte[] header
= new byte [HEADER_LENGTH
];
1389 int len
= Receive (header
, 0, header
.Length
);
1391 return new byte [0];
1392 if (len
!= HEADER_LENGTH
) {
1394 throw new IOException ("Packet of length " + len
+ " is read.");
1397 int packetLength
= GetPacketLength (header
);
1398 if (packetLength
< 11)
1399 throw new IOException ("Invalid packet length.");
1401 if (packetLength
== 11) {
1404 byte[] buf
= new byte [packetLength
];
1405 for (int i
= 0; i
< header
.Length
; ++i
)
1406 buf
[i
] = header
[i
];
1407 len
= Receive (buf
, header
.Length
, packetLength
- header
.Length
);
1408 if (len
!= packetLength
- header
.Length
)
1409 throw new IOException ();
1414 internal void WritePacket (byte[] packet
) {
1415 // FIXME: Throw ClosedConnectionException () if the connection is closed
1416 // FIXME: Throw ClosedConnectionException () if another thread closes the connection
1418 TransportSend (packet
, 0, packet
.Length
);
1421 internal void WritePackets (List
<byte[]> packets
) {
1422 // FIXME: Throw ClosedConnectionException () if the connection is closed
1423 // FIXME: Throw ClosedConnectionException () if another thread closes the connection
1426 for (int i
= 0; i
< packets
.Count
; ++i
)
1427 len
+= packets
[i
].Length
;
1428 byte[] data
= new byte [len
];
1430 for (int i
= 0; i
< packets
.Count
; ++i
) {
1431 Buffer
.BlockCopy (packets
[i
], 0, data
, pos
, packets
[i
].Length
);
1432 pos
+= packets
[i
].Length
;
1434 TransportSend (data
, 0, data
.Length
);
1437 internal void Close () {
1439 TransportShutdown ();
1442 internal bool IsClosed
{
1449 VMCrashException crashed
;
1451 internal ManualResetEvent DisconnectedEvent
= new ManualResetEvent (false);
1453 void receiver_thread_main () {
1456 bool res
= ReceivePacket ();
1460 } catch (ThreadAbortException
) {
1462 } catch (VMCrashException ex
) {
1465 } catch (Exception ex
) {
1467 Console
.WriteLine (ex
);
1473 lock (reply_packets_monitor
) {
1474 disconnected
= true;
1475 DisconnectedEvent
.Set ();
1476 Monitor
.PulseAll (reply_packets_monitor
);
1479 EventHandler
.VMDisconnect (0, 0, null);
1482 void disconnected_check () {
1485 else if (crashed
!= null)
1488 throw new VMDisconnectedException ();
1491 bool ReceivePacket () {
1492 byte[] packet
= ReadPacket ();
1494 if (packet
.Length
== 0) {
1498 if (IsReplyPacket (packet
)) {
1499 int id
= GetPacketId (packet
);
1500 ReplyCallback cb
= null;
1501 lock (reply_packets_monitor
) {
1502 reply_cbs
.TryGetValue (id
, out cb
);
1504 reply_packets
[id
] = packet
;
1505 Monitor
.PulseAll (reply_packets_monitor
);
1507 int c
= reply_cb_counts
[id
];
1510 reply_cbs
.Remove (id
);
1511 reply_cb_counts
.Remove (id
);
1517 cb
.Invoke (id
, packet
);
1519 PacketReader r
= new PacketReader (this, packet
);
1521 if (r
.CommandSet
== CommandSet
.EVENT
&& r
.Command
== (int)CmdEvent
.COMPOSITE
) {
1522 int spolicy
= r
.ReadByte ();
1523 int nevents
= r
.ReadInt ();
1525 SuspendPolicy suspend_policy
= decode_suspend_policy (spolicy
);
1527 EventInfo
[] events
= new EventInfo
[nevents
];
1529 for (int i
= 0; i
< nevents
; ++i
) {
1530 EventKind kind
= (EventKind
)r
.ReadByte ();
1531 int req_id
= r
.ReadInt ();
1533 EventType etype
= (EventType
)kind
;
1535 long thread_id
= r
.ReadId ();
1536 if (kind
== EventKind
.VM_START
) {
1537 events
[i
] = new EventInfo (etype
, req_id
) { ThreadId = thread_id }
;
1538 //EventHandler.VMStart (req_id, thread_id, null);
1539 } else if (kind
== EventKind
.VM_DEATH
) {
1541 if (Version
.AtLeast (2, 27))
1542 exit_code
= r
.ReadInt ();
1543 //EventHandler.VMDeath (req_id, 0, null);
1544 events
[i
] = new EventInfo (etype
, req_id
) { ExitCode = exit_code }
;
1545 } else if (kind
== EventKind
.CRASH
) {
1546 ulong hash
= (ulong) r
.ReadLong ();
1547 string dump
= r
.ReadString ();
1549 events
[i
] = new EventInfo (etype
, req_id
) { Dump = dump, Hash = hash}
;
1550 } else if (kind
== EventKind
.THREAD_START
) {
1551 events
[i
] = new EventInfo (etype
, req_id
) { ThreadId = thread_id, Id = thread_id }
;
1552 //EventHandler.ThreadStart (req_id, thread_id, thread_id);
1553 } else if (kind
== EventKind
.THREAD_DEATH
) {
1554 events
[i
] = new EventInfo (etype
, req_id
) { ThreadId = thread_id, Id = thread_id }
;
1555 //EventHandler.ThreadDeath (req_id, thread_id, thread_id);
1556 } else if (kind
== EventKind
.ASSEMBLY_LOAD
) {
1557 long id
= r
.ReadId ();
1558 events
[i
] = new EventInfo (etype
, req_id
) { ThreadId = thread_id, Id = id }
;
1559 //EventHandler.AssemblyLoad (req_id, thread_id, id);
1560 } else if (kind
== EventKind
.ASSEMBLY_UNLOAD
) {
1561 long id
= r
.ReadId ();
1562 events
[i
] = new EventInfo (etype
, req_id
) { ThreadId = thread_id, Id = id }
;
1563 //EventHandler.AssemblyUnload (req_id, thread_id, id);
1564 } else if (kind
== EventKind
.TYPE_LOAD
) {
1565 long id
= r
.ReadId ();
1566 events
[i
] = new EventInfo (etype
, req_id
) { ThreadId = thread_id, Id = id }
;
1567 //EventHandler.TypeLoad (req_id, thread_id, id);
1568 } else if (kind
== EventKind
.METHOD_ENTRY
) {
1569 long id
= r
.ReadId ();
1570 events
[i
] = new EventInfo (etype
, req_id
) { ThreadId = thread_id, Id = id }
;
1571 //EventHandler.MethodEntry (req_id, thread_id, id);
1572 } else if (kind
== EventKind
.METHOD_EXIT
) {
1573 long id
= r
.ReadId ();
1574 events
[i
] = new EventInfo (etype
, req_id
) { ThreadId = thread_id, Id = id }
;
1575 //EventHandler.MethodExit (req_id, thread_id, id);
1576 } else if (kind
== EventKind
.BREAKPOINT
) {
1577 long id
= r
.ReadId ();
1578 long loc
= r
.ReadLong ();
1579 events
[i
] = new EventInfo (etype
, req_id
) { ThreadId = thread_id, Id = id, Location = loc }
;
1580 //EventHandler.Breakpoint (req_id, thread_id, id, loc);
1581 } else if (kind
== EventKind
.STEP
) {
1582 long id
= r
.ReadId ();
1583 long loc
= r
.ReadLong ();
1584 events
[i
] = new EventInfo (etype
, req_id
) { ThreadId = thread_id, Id = id, Location = loc }
;
1585 //EventHandler.Step (req_id, thread_id, id, loc);
1586 } else if (kind
== EventKind
.EXCEPTION
) {
1587 long id
= r
.ReadId ();
1588 long loc
= 0; // FIXME
1589 events
[i
] = new EventInfo (etype
, req_id
) { ThreadId = thread_id, Id = id, Location = loc }
;
1590 //EventHandler.Exception (req_id, thread_id, id, loc);
1591 } else if (kind
== EventKind
.APPDOMAIN_CREATE
) {
1592 long id
= r
.ReadId ();
1593 events
[i
] = new EventInfo (etype
, req_id
) { ThreadId = thread_id, Id = id }
;
1594 //EventHandler.AppDomainCreate (req_id, thread_id, id);
1595 } else if (kind
== EventKind
.APPDOMAIN_UNLOAD
) {
1596 long id
= r
.ReadId ();
1597 events
[i
] = new EventInfo (etype
, req_id
) { ThreadId = thread_id, Id = id }
;
1598 //EventHandler.AppDomainUnload (req_id, thread_id, id);
1599 } else if (kind
== EventKind
.USER_BREAK
) {
1602 events
[i
] = new EventInfo (etype
, req_id
) { ThreadId = thread_id, Id = id, Location = loc }
;
1603 //EventHandler.Exception (req_id, thread_id, id, loc);
1604 } else if (kind
== EventKind
.USER_LOG
) {
1605 int level
= r
.ReadInt ();
1606 string category
= r
.ReadString ();
1607 string message
= r
.ReadString ();
1608 events
[i
] = new EventInfo (etype
, req_id
) { ThreadId = thread_id, Level = level, Category = category, Message = message }
;
1609 //EventHandler.Exception (req_id, thread_id, id, loc);
1610 } else if (kind
== EventKind
.KEEPALIVE
) {
1611 events
[i
] = new EventInfo (etype
, req_id
) { }
;
1613 throw new NotImplementedException ("Unknown event kind: " + kind
);
1617 EventHandler
.Events (suspend_policy
, events
);
1624 internal IEventHandler EventHandler
{
1628 static String
CommandString (CommandSet command_set
, int command
)
1631 switch (command_set
) {
1633 cmd
= ((CmdVM
)command
).ToString ();
1635 case CommandSet
.OBJECT_REF
:
1636 cmd
= ((CmdObjectRef
)command
).ToString ();
1638 case CommandSet
.STRING_REF
:
1639 cmd
= ((CmdStringRef
)command
).ToString ();
1641 case CommandSet
.THREAD
:
1642 cmd
= ((CmdThread
)command
).ToString ();
1644 case CommandSet
.ARRAY_REF
:
1645 cmd
= ((CmdArrayRef
)command
).ToString ();
1647 case CommandSet
.EVENT_REQUEST
:
1648 cmd
= ((CmdEventRequest
)command
).ToString ();
1650 case CommandSet
.STACK_FRAME
:
1651 cmd
= ((CmdStackFrame
)command
).ToString ();
1653 case CommandSet
.APPDOMAIN
:
1654 cmd
= ((CmdAppDomain
)command
).ToString ();
1656 case CommandSet
.ASSEMBLY
:
1657 cmd
= ((CmdAssembly
)command
).ToString ();
1659 case CommandSet
.METHOD
:
1660 cmd
= ((CmdMethod
)command
).ToString ();
1662 case CommandSet
.TYPE
:
1663 cmd
= ((CmdType
)command
).ToString ();
1665 case CommandSet
.MODULE
:
1666 cmd
= ((CmdModule
)command
).ToString ();
1668 case CommandSet
.FIELD
:
1669 cmd
= ((CmdField
)command
).ToString ();
1671 case CommandSet
.EVENT
:
1672 cmd
= ((CmdEvent
)command
).ToString ();
1675 cmd
= command
.ToString ();
1678 return string.Format ("[{0} {1}]", command_set
, cmd
);
1681 long total_protocol_ticks
;
1683 void LogPacket (int packet_id
, byte[] encoded_packet
, byte[] reply_packet
, CommandSet command_set
, int command
, Stopwatch watch
) {
1685 total_protocol_ticks
+= watch
.ElapsedTicks
;
1686 var ts
= TimeSpan
.FromTicks (total_protocol_ticks
);
1687 string msg
= string.Format ("Packet: {0} sent: {1} received: {2} ms: {3} total ms: {4} {5}",
1688 packet_id
, encoded_packet
.Length
, reply_packet
.Length
, watch
.ElapsedMilliseconds
,
1689 (ts
.Seconds
* 1000) + ts
.Milliseconds
,
1690 CommandString (command_set
, command
));
1692 LoggingStream
.WriteLine (msg
);
1693 LoggingStream
.Flush ();
1696 bool buffer_packets
;
1697 List
<byte[]> buffered_packets
= new List
<byte[]> ();
1700 // Start buffering request/response packets on both the client and the debuggee side.
1701 // Packets sent between StartBuffering ()/StopBuffering () must be async, i.e. sent
1702 // using Send () and not SendReceive ().
1704 public void StartBuffering () {
1705 buffer_packets
= true;
1706 if (Version
.AtLeast (2, 34))
1707 VM_StartBuffering ();
1710 public void StopBuffering () {
1711 if (Version
.AtLeast (2, 34))
1712 VM_StopBuffering ();
1713 buffer_packets
= false;
1715 WritePackets (buffered_packets
);
1716 if (EnableConnectionLogging
) {
1717 LoggingStream
.WriteLine (String
.Format ("Sent {0} packets.", buffered_packets
.Count
));
1718 LoggingStream
.Flush ();
1720 buffered_packets
.Clear ();
1723 /* Send a request and call cb when a result is received */
1724 int Send (CommandSet command_set
, int command
, PacketWriter packet
, Action
<PacketReader
> cb
, int count
) {
1725 int id
= IdGenerator
;
1727 Stopwatch watch
= null;
1728 if (EnableConnectionLogging
)
1729 watch
= Stopwatch
.StartNew ();
1731 byte[] encoded_packet
;
1733 encoded_packet
= EncodePacket (id
, (int)command_set
, command
, null, 0);
1735 encoded_packet
= EncodePacket (id
, (int)command_set
, command
, packet
.Data
, packet
.Offset
);
1738 lock (reply_packets_monitor
) {
1739 reply_cbs
[id
] = delegate (int packet_id
, byte[] p
) {
1740 if (EnableConnectionLogging
)
1741 LogPacket (packet_id
, encoded_packet
, p
, command_set
, command
, watch
);
1742 /* Run the callback on a tp thread to avoid blocking the receive thread */
1743 PacketReader r
= new PacketReader (this, p
);
1744 cb
.BeginInvoke (r
, null, null);
1746 reply_cb_counts
[id
] = count
;
1751 buffered_packets
.Add (encoded_packet
);
1753 WritePacket (encoded_packet
);
1758 // Send a request without waiting for an answer
1759 void Send (CommandSet command_set
, int command
) {
1760 Send (command_set
, command
, null, null, 0);
1763 PacketReader
SendReceive (CommandSet command_set
, int command
, PacketWriter packet
) {
1764 int id
= IdGenerator
;
1765 Stopwatch watch
= null;
1767 disconnected_check ();
1769 if (EnableConnectionLogging
)
1770 watch
= Stopwatch
.StartNew ();
1772 byte[] encoded_packet
;
1775 encoded_packet
= EncodePacket (id
, (int)command_set
, command
, null, 0);
1777 encoded_packet
= EncodePacket (id
, (int)command_set
, command
, packet
.Data
, packet
.Offset
);
1779 WritePacket (encoded_packet
);
1783 /* Wait for the reply packet */
1785 lock (reply_packets_monitor
) {
1787 if (reply_packets
.TryGetValue (packetId
, out reply
)) {
1788 reply_packets
.Remove (packetId
);
1789 PacketReader r
= new PacketReader (this, reply
);
1791 if (EnableConnectionLogging
)
1792 LogPacket (packetId
, encoded_packet
, reply
, command_set
, command
, watch
);
1793 if (r
.ErrorCode
!= 0) {
1794 if (ErrorHandler
!= null)
1795 ErrorHandler (this, new ErrorHandlerEventArgs () { ErrorCode = (ErrorCode)r.ErrorCode }
);
1796 throw new NotImplementedException ("No error handler set.");
1801 disconnected_check ();
1802 Monitor
.Wait (reply_packets_monitor
);
1808 PacketReader
SendReceive (CommandSet command_set
, int command
) {
1809 return SendReceive (command_set
, command
, null);
1812 int packet_id_generator
;
1816 return Interlocked
.Increment (ref packet_id_generator
);
1820 CattrInfo
[] ReadCattrs (PacketReader r
) {
1821 CattrInfo
[] res
= new CattrInfo
[r
.ReadInt ()];
1822 for (int i
= 0; i
< res
.Length
; ++i
) {
1823 CattrInfo info
= new CattrInfo ();
1824 info
.ctor_id
= r
.ReadId ();
1825 info
.ctor_args
= new ValueImpl
[r
.ReadInt ()];
1826 for (int j
= 0; j
< info
.ctor_args
.Length
; ++j
) {
1827 info
.ctor_args
[j
] = r
.ReadValue ();
1829 info
.named_args
= new CattrNamedArgInfo
[r
.ReadInt ()];
1830 for (int j
= 0; j
< info
.named_args
.Length
; ++j
) {
1831 CattrNamedArgInfo arg
= new CattrNamedArgInfo ();
1832 int arg_type
= r
.ReadByte ();
1833 arg
.is_property
= arg_type
== 0x54;
1835 // 2.12 is the only version we can guarantee the server will send a field id
1836 // It was added in https://github.com/mono/mono/commit/db0b932cd6c3c93976479ae3f6b5b2a885f681de
1837 // In between 2.11 and 2.12
1838 if (arg
.is_property
)
1839 arg
.id
= r
.ReadId ();
1840 else if (Version
.AtLeast (2, 12))
1841 arg
.id
= r
.ReadId ();
1843 arg
.value = r
.ReadValue ();
1844 info
.named_args
[j
] = arg
;
1851 static ElementType
TypeCodeToElementType (TypeCode c
, Type t
) {
1853 case TypeCode
.Boolean
:
1854 return ElementType
.Boolean
;
1856 return ElementType
.Char
;
1857 case TypeCode
.SByte
:
1858 return ElementType
.I1
;
1860 return ElementType
.U1
;
1861 case TypeCode
.Int16
:
1862 return ElementType
.I2
;
1863 case TypeCode
.UInt16
:
1864 return ElementType
.U2
;
1865 case TypeCode
.Int32
:
1866 return ElementType
.I4
;
1867 case TypeCode
.UInt32
:
1868 return ElementType
.U4
;
1869 case TypeCode
.Int64
:
1870 return ElementType
.I8
;
1871 case TypeCode
.UInt64
:
1872 return ElementType
.U8
;
1873 case TypeCode
.Single
:
1874 return ElementType
.R4
;
1875 case TypeCode
.Double
:
1876 return ElementType
.R8
;
1877 case TypeCode
.Object
:
1878 return TypeCodeToElementType(Type
.GetTypeCode (t
.GetElementType()), t
.GetElementType());
1880 throw new NotImplementedException ();
1885 * Implementation of debugger commands
1888 internal VersionInfo
VM_GetVersion () {
1889 var res
= SendReceive (CommandSet
.VM
, (int)CmdVM
.VERSION
, null);
1890 VersionInfo info
= new VersionInfo ();
1891 info
.VMVersion
= res
.ReadString ();
1892 info
.MajorVersion
= res
.ReadInt ();
1893 info
.MinorVersion
= res
.ReadInt ();
1897 internal void VM_SetProtocolVersion (int major
, int minor
) {
1898 SendReceive (CommandSet
.VM
, (int)CmdVM
.SET_PROTOCOL_VERSION
, new PacketWriter ().WriteInt (major
).WriteInt (minor
));
1901 internal void VM_GetThreads (Action
<long[]> resultCallaback
) {
1902 Send (CommandSet
.VM
, (int)CmdVM
.ALL_THREADS
, null, (res
) => {
1903 int len
= res
.ReadInt ();
1904 long[] arr
= new long [len
];
1905 for (int i
= 0; i
< len
; ++i
)
1906 arr
[i
] = res
.ReadId ();
1907 resultCallaback(arr
);
1911 internal void VM_Suspend () {
1912 SendReceive (CommandSet
.VM
, (int)CmdVM
.SUSPEND
);
1915 internal void VM_Resume () {
1916 SendReceive (CommandSet
.VM
, (int)CmdVM
.RESUME
);
1919 internal void VM_Exit (int exitCode
) {
1920 SendReceive (CommandSet
.VM
, (int)CmdVM
.EXIT
, new PacketWriter ().WriteInt (exitCode
));
1923 internal void VM_Dispose () {
1924 SendReceive (CommandSet
.VM
, (int)CmdVM
.DISPOSE
);
1927 internal ValueImpl
VM_InvokeMethod (long thread
, long method
, ValueImpl this_arg
, ValueImpl
[] arguments
, InvokeFlags flags
, out ValueImpl exc
) {
1929 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
));
1930 if (r
.ReadByte () == 0) {
1931 exc
= r
.ReadValue ();
1934 return r
.ReadValue ();
1938 internal delegate void InvokeMethodCallback (ValueImpl v
, ValueImpl exc
, ValueImpl out_this
, ValueImpl
[] out_args
, ErrorCode error
, object state
);
1940 void read_invoke_res (PacketReader r
, out ValueImpl v
, out ValueImpl exc
, out ValueImpl out_this
, out ValueImpl
[] out_args
) {
1941 int resflags
= r
.ReadByte ();
1946 if (resflags
== 0) {
1947 exc
= r
.ReadValue ();
1950 if ((resflags
& 2) != 0)
1951 out_this
= r
.ReadValue ();
1952 if ((resflags
& 4) != 0) {
1953 int nargs
= r
.ReadInt ();
1954 out_args
= new ValueImpl
[nargs
];
1955 for (int i
= 0; i
< nargs
; ++i
)
1956 out_args
[i
] = r
.ReadValue ();
1961 internal int VM_BeginInvokeMethod (long thread
, long method
, ValueImpl this_arg
, ValueImpl
[] arguments
, InvokeFlags flags
, InvokeMethodCallback callback
, object state
) {
1962 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
) {
1963 ValueImpl v
, exc
, out_this
= null;
1964 ValueImpl
[] out_args
= null;
1966 if (r
.ErrorCode
!= 0) {
1967 callback (null, null, null, null, (ErrorCode
)r
.ErrorCode
, state
);
1969 read_invoke_res (r
, out v
, out exc
, out out_this
, out out_args
);
1970 callback (v
, exc
, out_this
, out_args
, 0, state
);
1975 internal int VM_BeginInvokeMethods (long thread
, long[] methods
, ValueImpl this_arg
, List
<ValueImpl
[]> arguments
, InvokeFlags flags
, InvokeMethodCallback callback
, object state
) {
1976 // FIXME: Merge this with INVOKE_METHOD
1977 var w
= new PacketWriter ();
1979 w
.WriteInt ((int)flags
);
1980 w
.WriteInt (methods
.Length
);
1981 for (int i
= 0; i
< methods
.Length
; ++i
) {
1982 w
.WriteId (methods
[i
]);
1983 w
.WriteValue (this_arg
);
1984 w
.WriteInt (arguments
[i
].Length
);
1985 w
.WriteValues (arguments
[i
]);
1987 return Send (CommandSet
.VM
, (int)CmdVM
.INVOKE_METHODS
, w
, delegate (PacketReader r
) {
1988 ValueImpl v
, exc
, out_this
= null;
1989 ValueImpl
[] out_args
= null;
1991 if (r
.ErrorCode
!= 0) {
1992 callback (null, null, null, null, (ErrorCode
)r
.ErrorCode
, state
);
1994 read_invoke_res (r
, out v
, out exc
, out out_this
, out out_args
);
1995 callback (v
, exc
, out_this
, out_args
, 0, state
);
2000 internal void VM_AbortInvoke (long thread
, int id
)
2002 SendReceive (CommandSet
.VM
, (int)CmdVM
.ABORT_INVOKE
, new PacketWriter ().WriteId (thread
).WriteInt (id
));
2005 internal void SetSocketTimeouts (int send_timeout
, int receive_timeout
, int keepalive_interval
)
2007 TransportSetTimeouts (send_timeout
, receive_timeout
);
2008 SendReceive (CommandSet
.VM
, (int)CmdVM
.SET_KEEPALIVE
, new PacketWriter ().WriteId (keepalive_interval
));
2011 internal long[] VM_GetTypesForSourceFile (string fname
, bool ignoreCase
) {
2012 var res
= SendReceive (CommandSet
.VM
, (int)CmdVM
.GET_TYPES_FOR_SOURCE_FILE
, new PacketWriter ().WriteString (fname
).WriteBool (ignoreCase
));
2013 int count
= res
.ReadInt ();
2014 long[] types
= new long [count
];
2015 for (int i
= 0; i
< count
; ++i
)
2016 types
[i
] = res
.ReadId ();
2020 internal long[] VM_GetTypes (string name
, bool ignoreCase
) {
2021 var res
= SendReceive (CommandSet
.VM
, (int)CmdVM
.GET_TYPES
, new PacketWriter ().WriteString (name
).WriteBool (ignoreCase
));
2022 int count
= res
.ReadInt ();
2023 long[] types
= new long [count
];
2024 for (int i
= 0; i
< count
; ++i
)
2025 types
[i
] = res
.ReadId ();
2029 internal void VM_StartBuffering () {
2030 Send (CommandSet
.VM
, (int)CmdVM
.START_BUFFERING
);
2033 internal void VM_StopBuffering () {
2034 Send (CommandSet
.VM
, (int)CmdVM
.STOP_BUFFERING
);
2041 internal long RootDomain
{
2043 return SendReceive (CommandSet
.APPDOMAIN
, (int)CmdAppDomain
.GET_ROOT_DOMAIN
, null).ReadId ();
2047 internal string Domain_GetName (long id
) {
2048 return SendReceive (CommandSet
.APPDOMAIN
, (int)CmdAppDomain
.GET_FRIENDLY_NAME
, new PacketWriter ().WriteId (id
)).ReadString ();
2051 internal long[] Domain_GetAssemblies (long id
) {
2052 var res
= SendReceive (CommandSet
.APPDOMAIN
, (int)CmdAppDomain
.GET_ASSEMBLIES
, new PacketWriter ().WriteId (id
));
2053 int count
= res
.ReadInt ();
2054 long[] assemblies
= new long [count
];
2055 for (int i
= 0; i
< count
; ++i
)
2056 assemblies
[i
] = res
.ReadId ();
2060 internal long Domain_GetEntryAssembly (long id
) {
2061 return SendReceive (CommandSet
.APPDOMAIN
, (int)CmdAppDomain
.GET_ENTRY_ASSEMBLY
, new PacketWriter ().WriteId (id
)).ReadId ();
2064 internal long Domain_GetCorlib (long id
) {
2065 return SendReceive (CommandSet
.APPDOMAIN
, (int)CmdAppDomain
.GET_CORLIB
, new PacketWriter ().WriteId (id
)).ReadId ();
2068 internal long Domain_CreateString (long id
, string s
) {
2069 return SendReceive (CommandSet
.APPDOMAIN
, (int)CmdAppDomain
.CREATE_STRING
, new PacketWriter ().WriteId (id
).WriteString (s
)).ReadId ();
2072 internal long Domain_CreateByteArray (long id
, byte [] bytes
) {
2073 var w
= new PacketWriter ().WriteId (id
);
2074 w
.WriteBytes (bytes
);
2075 return SendReceive (CommandSet
.APPDOMAIN
, (int)CmdAppDomain
.CREATE_BYTE_ARRAY
, w
).ReadId ();
2078 internal long Domain_CreateBoxedValue (long id
, long type_id
, ValueImpl v
) {
2079 return SendReceive (CommandSet
.APPDOMAIN
, (int)CmdAppDomain
.CREATE_BOXED_VALUE
, new PacketWriter ().WriteId (id
).WriteId (type_id
).WriteValue (v
)).ReadId ();
2086 internal string Method_GetName (long id
) {
2087 return SendReceive (CommandSet
.METHOD
, (int)CmdMethod
.GET_NAME
, new PacketWriter ().WriteId (id
)).ReadString ();
2090 internal long Method_GetDeclaringType (long id
) {
2091 return SendReceive (CommandSet
.METHOD
, (int)CmdMethod
.GET_DECLARING_TYPE
, new PacketWriter ().WriteId (id
)).ReadId ();
2094 internal DebugInfo
Method_GetDebugInfo (long id
) {
2095 var res
= SendReceive (CommandSet
.METHOD
, (int)CmdMethod
.GET_DEBUG_INFO
, new PacketWriter ().WriteId (id
));
2097 DebugInfo info
= new DebugInfo ();
2098 info
.max_il_offset
= res
.ReadInt ();
2100 SourceInfo
[] sources
= null;
2101 if (Version
.AtLeast (2, 13)) {
2102 int n
= res
.ReadInt ();
2103 sources
= new SourceInfo
[n
];
2104 for (int i
= 0; i
< n
; ++i
) {
2105 sources
[i
].source_file
= res
.ReadString ();
2106 if (Version
.AtLeast (2, 14)) {
2107 sources
[i
].hash
= new byte [16];
2108 for (int j
= 0; j
< 16; ++j
)
2109 sources
[i
].hash
[j
] = (byte)res
.ReadByte ();
2113 sources
= new SourceInfo
[1];
2114 sources
[0].source_file
= res
.ReadString ();
2117 int n_il_offsets
= res
.ReadInt ();
2118 info
.il_offsets
= new int [n_il_offsets
];
2119 info
.line_numbers
= new int [n_il_offsets
];
2120 info
.source_files
= new SourceInfo
[n_il_offsets
];
2121 info
.column_numbers
= new int [n_il_offsets
];
2122 info
.end_line_numbers
= new int [n_il_offsets
];
2123 info
.end_column_numbers
= new int [n_il_offsets
];
2124 for (int i
= 0; i
< n_il_offsets
; ++i
) {
2125 info
.il_offsets
[i
] = res
.ReadInt ();
2126 info
.line_numbers
[i
] = res
.ReadInt ();
2127 if (Version
.AtLeast (2, 12)) {
2128 int idx
= res
.ReadInt ();
2129 info
.source_files
[i
] = idx
>= 0 ? sources
[idx
] : default (SourceInfo
);
2131 info
.source_files
[i
] = sources
[0];
2133 if (Version
.AtLeast (2, 19))
2134 info
.column_numbers
[i
] = res
.ReadInt ();
2136 info
.column_numbers
[i
] = 0;
2137 if (Version
.AtLeast (2, 32)) {
2138 info
.end_line_numbers
[i
] = res
.ReadInt ();
2139 info
.end_column_numbers
[i
] = res
.ReadInt ();
2141 info
.end_column_numbers
[i
] = -1;
2142 info
.end_column_numbers
[i
] = -1;
2149 internal ParamInfo
Method_GetParamInfo (long id
) {
2150 var res
= SendReceive (CommandSet
.METHOD
, (int)CmdMethod
.GET_PARAM_INFO
, new PacketWriter ().WriteId (id
));
2152 ParamInfo info
= new ParamInfo ();
2153 info
.call_conv
= res
.ReadInt ();
2154 info
.param_count
= res
.ReadInt ();
2155 info
.generic_param_count
= res
.ReadInt ();
2156 info
.ret_type
= res
.ReadId ();
2157 info
.param_types
= new long [info
.param_count
];
2158 for (int i
= 0; i
< info
.param_count
; ++i
)
2159 info
.param_types
[i
] = res
.ReadId ();
2160 info
.param_names
= new string [info
.param_count
];
2161 for (int i
= 0; i
< info
.param_count
; ++i
)
2162 info
.param_names
[i
] = res
.ReadString ();
2167 internal LocalsInfo
Method_GetLocalsInfo (long id
) {
2168 var res
= SendReceive (CommandSet
.METHOD
, (int)CmdMethod
.GET_LOCALS_INFO
, new PacketWriter ().WriteId (id
));
2170 LocalsInfo info
= new LocalsInfo ();
2172 if (Version
.AtLeast (2, 43)) {
2173 int nscopes
= res
.ReadInt ();
2174 info
.scopes_start
= new int [nscopes
];
2175 info
.scopes_end
= new int [nscopes
];
2177 for (int i
= 0; i
< nscopes
; ++i
) {
2178 info
.scopes_start
[i
] = last_start
+ res
.ReadInt ();
2179 info
.scopes_end
[i
] = info
.scopes_start
[i
] + res
.ReadInt ();
2180 last_start
= info
.scopes_start
[i
];
2184 int nlocals
= res
.ReadInt ();
2185 info
.types
= new long [nlocals
];
2186 for (int i
= 0; i
< nlocals
; ++i
)
2187 info
.types
[i
] = res
.ReadId ();
2188 info
.names
= new string [nlocals
];
2189 for (int i
= 0; i
< nlocals
; ++i
)
2190 info
.names
[i
] = res
.ReadString ();
2191 info
.live_range_start
= new int [nlocals
];
2192 info
.live_range_end
= new int [nlocals
];
2193 for (int i
= 0; i
< nlocals
; ++i
) {
2194 info
.live_range_start
[i
] = res
.ReadInt ();
2195 info
.live_range_end
[i
] = res
.ReadInt ();
2201 internal MethodInfo
Method_GetInfo (long id
) {
2202 var res
= SendReceive (CommandSet
.METHOD
, (int)CmdMethod
.GET_INFO
, new PacketWriter ().WriteId (id
));
2204 MethodInfo info
= new MethodInfo ();
2205 info
.attributes
= res
.ReadInt ();
2206 info
.iattributes
= res
.ReadInt ();
2207 info
.token
= res
.ReadInt ();
2208 if (Version
.AtLeast (2, 12)) {
2209 int attrs
= res
.ReadByte ();
2210 if ((attrs
& (1 << 0)) != 0)
2212 if ((attrs
& (1 << 1)) != 0)
2213 info
.is_generic_method
= true;
2214 info
.gmd
= res
.ReadId ();
2215 if (Version
.AtLeast (2, 15)) {
2216 if (info
.is_generic_method
) {
2217 int n
= res
.ReadInt ();
2218 info
.type_args
= res
.ReadIds (n
);
2225 internal MethodBodyInfo
Method_GetBody (long id
) {
2226 var res
= SendReceive (CommandSet
.METHOD
, (int)CmdMethod
.GET_BODY
, new PacketWriter ().WriteId (id
));
2228 MethodBodyInfo info
= new MethodBodyInfo ();
2229 info
.il
= new byte [res
.ReadInt ()];
2230 for (int i
= 0; i
< info
.il
.Length
; ++i
)
2231 info
.il
[i
] = (byte)res
.ReadByte ();
2233 if (Version
.AtLeast (2, 18)) {
2234 info
.clauses
= new ExceptionClauseInfo
[res
.ReadInt ()];
2236 for (int i
= 0; i
< info
.clauses
.Length
; ++i
) {
2237 var clause
= new ExceptionClauseInfo
{
2238 flags
= (ExceptionClauseFlags
) res
.ReadInt (),
2239 try_offset
= res
.ReadInt (),
2240 try_length
= res
.ReadInt (),
2241 handler_offset
= res
.ReadInt (),
2242 handler_length
= res
.ReadInt (),
2245 if (clause
.flags
== ExceptionClauseFlags
.None
)
2246 clause
.catch_type_id
= res
.ReadId ();
2247 else if (clause
.flags
== ExceptionClauseFlags
.Filter
)
2248 clause
.filter_offset
= res
.ReadInt ();
2250 info
.clauses
[i
] = clause
;
2253 info
.clauses
= new ExceptionClauseInfo
[0];
2258 internal ResolvedToken
Method_ResolveToken (long id
, int token
) {
2259 var res
= SendReceive (CommandSet
.METHOD
, (int)CmdMethod
.RESOLVE_TOKEN
, new PacketWriter ().WriteId (id
).WriteInt (token
));
2261 TokenType type
= (TokenType
)res
.ReadByte ();
2263 case TokenType
.STRING
:
2264 return new ResolvedToken () { Type = type, Str = res.ReadString () }
;
2265 case TokenType
.TYPE
:
2266 case TokenType
.METHOD
:
2267 case TokenType
.FIELD
:
2268 return new ResolvedToken () { Type = type, Id = res.ReadId () }
;
2269 case TokenType
.UNKNOWN
:
2270 return new ResolvedToken () { Type = type }
;
2272 throw new NotImplementedException ();
2276 internal CattrInfo
[] Method_GetCustomAttributes (long id
, long attr_type_id
, bool inherit
) {
2277 PacketReader r
= SendReceive (CommandSet
.METHOD
, (int)CmdMethod
.GET_CATTRS
, new PacketWriter ().WriteId (id
).WriteId (attr_type_id
));
2278 return ReadCattrs (r
);
2281 internal long Method_MakeGenericMethod (long id
, long[] args
) {
2282 PacketReader r
= SendReceive (CommandSet
.METHOD
, (int)CmdMethod
.MAKE_GENERIC_METHOD
, new PacketWriter ().WriteId (id
).WriteInt (args
.Length
).WriteIds (args
));
2290 internal string Thread_GetName (long id
) {
2291 return SendReceive (CommandSet
.THREAD
, (int)CmdThread
.GET_NAME
, new PacketWriter ().WriteId (id
)).ReadString ();
2294 internal long Thread_GetElapsedTime (long id
) {
2295 return SendReceive (CommandSet
.THREAD
, (int)CmdThread
.GET_ELAPSED_TIME
, new PacketWriter ().WriteId (id
)).ReadLong ();
2298 internal void Thread_GetFrameInfo (long id
, int start_frame
, int length
, Action
<FrameInfo
[]> resultCallaback
) {
2299 Send (CommandSet
.THREAD
, (int)CmdThread
.GET_FRAME_INFO
, new PacketWriter ().WriteId (id
).WriteInt (start_frame
).WriteInt (length
), (res
) => {
2300 int count
= res
.ReadInt ();
2301 var frames
= new FrameInfo
[count
];
2302 for (int i
= 0; i
< count
; ++i
) {
2303 var f
= new FrameInfo ();
2304 f
.id
= res
.ReadInt ();
2305 f
.method
= res
.ReadId ();
2306 f
.il_offset
= res
.ReadInt ();
2307 f
.flags
= (StackFrameFlags
)res
.ReadByte ();
2310 resultCallaback (frames
);
2314 internal int Thread_GetState (long id
) {
2315 return SendReceive (CommandSet
.THREAD
, (int)CmdThread
.GET_STATE
, new PacketWriter ().WriteId (id
)).ReadInt ();
2318 internal ThreadInfo
Thread_GetInfo (long id
) {
2319 PacketReader r
= SendReceive (CommandSet
.THREAD
, (int)CmdThread
.GET_INFO
, new PacketWriter ().WriteId (id
));
2321 ThreadInfo res
= new ThreadInfo () { is_thread_pool = r.ReadByte () > 0 ? true : false }
;
2326 internal long Thread_GetId (long id
) {
2327 return SendReceive (CommandSet
.THREAD
, (int)CmdThread
.GET_ID
, new PacketWriter ().WriteId (id
)).ReadLong ();
2330 internal long Thread_GetTID (long id
) {
2331 return SendReceive (CommandSet
.THREAD
, (int)CmdThread
.GET_TID
, new PacketWriter ().WriteId (id
)).ReadLong ();
2334 internal void Thread_SetIP (long id
, long method_id
, long il_offset
) {
2335 SendReceive (CommandSet
.THREAD
, (int)CmdThread
.SET_IP
, new PacketWriter ().WriteId (id
).WriteId (method_id
).WriteLong (il_offset
));
2342 internal ModuleInfo
Module_GetInfo (long id
) {
2343 PacketReader r
= SendReceive (CommandSet
.MODULE
, (int)CmdModule
.GET_INFO
, new PacketWriter ().WriteId (id
));
2344 ModuleInfo info
= new ModuleInfo { Name = r.ReadString (), ScopeName = r.ReadString (), FQName = r.ReadString (), Guid = r.ReadString (), Assembly = r.ReadId () }
;
2345 if (Version
.AtLeast (2, 48))
2346 info
.SourceLink
= r
.ReadString ();
2354 internal string Assembly_GetLocation (long id
) {
2355 return SendReceive (CommandSet
.ASSEMBLY
, (int)CmdAssembly
.GET_LOCATION
, new PacketWriter ().WriteId (id
)).ReadString ();
2358 internal long Assembly_GetEntryPoint (long id
) {
2359 return SendReceive (CommandSet
.ASSEMBLY
, (int)CmdAssembly
.GET_ENTRY_POINT
, new PacketWriter ().WriteId (id
)).ReadId ();
2362 internal long Assembly_GetManifestModule (long id
) {
2363 return SendReceive (CommandSet
.ASSEMBLY
, (int)CmdAssembly
.GET_MANIFEST_MODULE
, new PacketWriter ().WriteId (id
)).ReadId ();
2366 internal long Assembly_GetObject (long id
) {
2367 return SendReceive (CommandSet
.ASSEMBLY
, (int)CmdAssembly
.GET_OBJECT
, new PacketWriter ().WriteId (id
)).ReadId ();
2370 internal long Assembly_GetType (long id
, string name
, bool ignoreCase
) {
2371 return SendReceive (CommandSet
.ASSEMBLY
, (int)CmdAssembly
.GET_TYPE
, new PacketWriter ().WriteId (id
).WriteString (name
).WriteBool (ignoreCase
)).ReadId ();
2374 internal string Assembly_GetName (long id
) {
2375 return SendReceive (CommandSet
.ASSEMBLY
, (int)CmdAssembly
.GET_NAME
, new PacketWriter ().WriteId (id
)).ReadString ();
2378 internal long Assembly_GetIdDomain (long id
) {
2379 return SendReceive (CommandSet
.ASSEMBLY
, (int)CmdAssembly
.GET_DOMAIN
, new PacketWriter ().WriteId (id
)).ReadId ();
2382 internal byte[] Assembly_GetMetadataBlob (long id
) {
2383 return SendReceive (CommandSet
.ASSEMBLY
, (int)CmdAssembly
.GET_METADATA_BLOB
, new PacketWriter ().WriteId (id
)).ReadByteArray ();
2386 internal bool Assembly_IsDynamic (long id
) {
2387 return SendReceive (CommandSet
.ASSEMBLY
, (int) CmdAssembly
.GET_IS_DYNAMIC
, new PacketWriter ().WriteId (id
)).ReadBool ();
2390 internal byte[] Assembly_GetPdbBlob (long id
) {
2391 return SendReceive (CommandSet
.ASSEMBLY
, (int)CmdAssembly
.GET_PDB_BLOB
, new PacketWriter ().WriteId (id
)).ReadByteArray ();
2394 internal long Assembly_GetType (long id
, uint token
) {
2395 return SendReceive (CommandSet
.ASSEMBLY
, (int)CmdAssembly
.GET_TYPE_FROM_TOKEN
, new PacketWriter ().WriteId (id
).WriteInt ((int)token
)).ReadId ();
2398 internal long Assembly_GetMethod (long id
, uint token
) {
2399 return SendReceive (CommandSet
.ASSEMBLY
, (int)CmdAssembly
.GET_METHOD_FROM_TOKEN
, new PacketWriter ().WriteId (id
).WriteInt ((int)token
)).ReadId ();
2402 internal bool Assembly_HasDebugInfo (long id
) {
2403 return SendReceive (CommandSet
.ASSEMBLY
, (int)CmdAssembly
.HAS_DEBUG_INFO
, new PacketWriter ().WriteId (id
)).ReadBool ();
2410 internal TypeInfo
Type_GetInfo (long id
) {
2411 PacketReader r
= SendReceive (CommandSet
.TYPE
, (int)CmdType
.GET_INFO
, new PacketWriter ().WriteId (id
));
2412 TypeInfo res
= new TypeInfo ();
2414 res
.ns
= r
.ReadString ();
2415 res
.name
= r
.ReadString ();
2416 res
.full_name
= r
.ReadString ();
2417 res
.assembly
= r
.ReadId ();
2418 res
.module
= r
.ReadId ();
2419 res
.base_type
= r
.ReadId ();
2420 res
.element_type
= r
.ReadId ();
2421 res
.token
= r
.ReadInt ();
2422 res
.rank
= r
.ReadByte ();
2423 res
.attributes
= r
.ReadInt ();
2424 int b
= r
.ReadByte ();
2425 res
.is_byref
= (b
& 1) != 0;
2426 res
.is_pointer
= (b
& 2) != 0;
2427 res
.is_primitive
= (b
& 4) != 0;
2428 res
.is_valuetype
= (b
& 8) != 0;
2429 res
.is_enum
= (b
& 16) != 0;
2430 res
.is_gtd
= (b
& 32) != 0;
2431 res
.is_generic_type
= (b
& 64) != 0;
2433 int nested_len
= r
.ReadInt ();
2434 res
.nested
= new long [nested_len
];
2435 for (int i
= 0; i
< nested_len
; ++i
)
2436 res
.nested
[i
] = r
.ReadId ();
2438 if (Version
.AtLeast (2, 12))
2439 res
.gtd
= r
.ReadId ();
2440 if (Version
.AtLeast (2, 15) && res
.is_generic_type
) {
2441 int n
= r
.ReadInt ();
2442 res
.type_args
= r
.ReadIds (n
);
2448 internal long[] Type_GetMethods (long id
) {
2449 PacketReader r
= SendReceive (CommandSet
.TYPE
, (int)CmdType
.GET_METHODS
, new PacketWriter ().WriteId (id
));
2451 int n
= r
.ReadInt ();
2452 long[] res
= new long [n
];
2453 for (int i
= 0; i
< n
; ++i
)
2454 res
[i
] = r
.ReadId ();
2458 internal long[] Type_GetFields (long id
, out string[] names
, out long[] types
, out int[] attrs
) {
2459 PacketReader r
= SendReceive (CommandSet
.TYPE
, (int)CmdType
.GET_FIELDS
, new PacketWriter ().WriteId (id
));
2461 int n
= r
.ReadInt ();
2462 long[] res
= new long [n
];
2463 names
= new string [n
];
2464 types
= new long [n
];
2465 attrs
= new int [n
];
2466 for (int i
= 0; i
< n
; ++i
) {
2467 res
[i
] = r
.ReadId ();
2468 names
[i
] = r
.ReadString ();
2469 types
[i
] = r
.ReadId ();
2470 attrs
[i
] = r
.ReadInt ();
2475 internal PropInfo
[] Type_GetProperties (long id
) {
2476 PacketReader r
= SendReceive (CommandSet
.TYPE
, (int)CmdType
.GET_PROPERTIES
, new PacketWriter ().WriteId (id
));
2478 int n
= r
.ReadInt ();
2479 PropInfo
[] res
= new PropInfo
[n
];
2480 for (int i
= 0; i
< n
; ++i
) {
2481 res
[i
] = new PropInfo ();
2482 res
[i
].id
= r
.ReadId ();
2483 res
[i
].name
= r
.ReadString ();
2484 res
[i
].get_method
= r
.ReadId ();
2485 res
[i
].set_method
= r
.ReadId ();
2486 res
[i
].attrs
= r
.ReadInt ();
2492 internal long Type_GetObject (long id
) {
2493 return SendReceive (CommandSet
.TYPE
, (int)CmdType
.GET_OBJECT
, new PacketWriter ().WriteId (id
)).ReadId ();
2496 internal ValueImpl
[] Type_GetValues (long id
, long[] fields
, long thread_id
) {
2497 int len
= fields
.Length
;
2499 if (thread_id
!= 0 && Version
.AtLeast(2, 3))
2500 r
= SendReceive (CommandSet
.TYPE
, (int)CmdType
.GET_VALUES_2
, new PacketWriter ().WriteId (id
).WriteId (thread_id
).WriteInt (len
).WriteIds (fields
));
2502 r
= SendReceive (CommandSet
.TYPE
, (int)CmdType
.GET_VALUES
, new PacketWriter ().WriteId (id
).WriteInt (len
).WriteIds (fields
));
2504 ValueImpl
[] res
= new ValueImpl
[len
];
2505 for (int i
= 0; i
< len
; ++i
)
2506 res
[i
] = r
.ReadValue ();
2510 internal void Type_SetValues (long id
, long[] fields
, ValueImpl
[] values
) {
2511 SendReceive (CommandSet
.TYPE
, (int)CmdType
.SET_VALUES
, new PacketWriter ().WriteId (id
).WriteInt (fields
.Length
).WriteIds (fields
).WriteValues (values
));
2514 internal string[] Type_GetSourceFiles (long id
, bool return_full_paths
) {
2515 var r
= SendReceive (CommandSet
.TYPE
, return_full_paths
? (int)CmdType
.GET_SOURCE_FILES_2
: (int)CmdType
.GET_SOURCE_FILES
, new PacketWriter ().WriteId (id
));
2516 int len
= r
.ReadInt ();
2517 string[] res
= new string [len
];
2518 for (int i
= 0; i
< len
; ++i
)
2519 res
[i
] = r
.ReadString ();
2523 internal bool Type_IsAssignableFrom (long id
, long c_id
) {
2524 return SendReceive (CommandSet
.TYPE
, (int)CmdType
.IS_ASSIGNABLE_FROM
, new PacketWriter ().WriteId (id
).WriteId (c_id
)).ReadByte () > 0;
2527 internal CattrInfo
[] Type_GetCustomAttributes (long id
, long attr_type_id
, bool inherit
) {
2528 PacketReader r
= SendReceive (CommandSet
.TYPE
, (int)CmdType
.GET_CATTRS
, new PacketWriter ().WriteId (id
).WriteId (attr_type_id
));
2529 return ReadCattrs (r
);
2532 internal CattrInfo
[] Type_GetFieldCustomAttributes (long id
, long field_id
, long attr_type_id
, bool inherit
) {
2533 PacketReader r
= SendReceive (CommandSet
.TYPE
, (int)CmdType
.GET_FIELD_CATTRS
, new PacketWriter ().WriteId (id
).WriteId (field_id
).WriteId (attr_type_id
));
2534 return ReadCattrs (r
);
2537 internal CattrInfo
[] Type_GetPropertyCustomAttributes (long id
, long field_id
, long attr_type_id
, bool inherit
) {
2538 PacketReader r
= SendReceive (CommandSet
.TYPE
, (int)CmdType
.GET_PROPERTY_CATTRS
, new PacketWriter ().WriteId (id
).WriteId (field_id
).WriteId (attr_type_id
));
2539 return ReadCattrs (r
);
2542 public long[] Type_GetMethodsByNameFlags (long id
, string name
, int flags
, bool ignoreCase
) {
2543 flags
|= ignoreCase
? (int)BindingFlagsExtensions
.BINDING_FLAGS_IGNORE_CASE
: 0;
2544 int listType
= ignoreCase
? (int)MemberListTypeExtensions
.CaseInsensitive
: (int)MemberListTypeExtensions
.CaseSensitive
;
2545 var w
= new PacketWriter ().WriteId (id
).WriteString (name
).WriteInt (flags
);
2546 if (Version
.AtLeast (2, 48))
2547 w
.WriteInt (listType
);
2548 PacketReader r
= SendReceive (CommandSet
.TYPE
, (int)CmdType
.CMD_TYPE_GET_METHODS_BY_NAME_FLAGS
, w
);
2549 int len
= r
.ReadInt ();
2550 long[] res
= new long [len
];
2551 for (int i
= 0; i
< len
; ++i
)
2552 res
[i
] = r
.ReadId ();
2556 internal long[] Type_GetInterfaces (long id
) {
2557 PacketReader r
= SendReceive (CommandSet
.TYPE
, (int)CmdType
.GET_INTERFACES
, new PacketWriter ().WriteId (id
));
2558 int len
= r
.ReadInt ();
2559 return r
.ReadIds (len
);
2562 internal IfaceMapInfo
[] Type_GetInterfaceMap (long id
, long[] ids
) {
2563 PacketReader r
= SendReceive (CommandSet
.TYPE
, (int)CmdType
.GET_INTERFACE_MAP
, new PacketWriter ().WriteId (id
).WriteInt (ids
.Length
).WriteIds (ids
));
2564 var res
= new IfaceMapInfo
[ids
.Length
];
2565 for (int i
= 0; i
< ids
.Length
; ++i
) {
2566 int n
= r
.ReadInt ();
2568 res
[i
].iface_id
= ids
[i
];
2569 res
[i
].iface_methods
= r
.ReadIds (n
);
2570 res
[i
].target_methods
= r
.ReadIds (n
);
2576 internal bool Type_IsInitialized (long id
) {
2577 PacketReader r
= SendReceive (CommandSet
.TYPE
, (int)CmdType
.IS_INITIALIZED
, new PacketWriter ().WriteId (id
));
2578 return r
.ReadInt () == 1;
2581 internal long Type_CreateInstance (long id
) {
2582 PacketReader r
= SendReceive (CommandSet
.TYPE
, (int)CmdType
.CREATE_INSTANCE
, new PacketWriter ().WriteId (id
));
2586 internal int Type_GetValueSize (long id
) {
2587 PacketReader r
= SendReceive (CommandSet
.TYPE
, (int)CmdType
.GET_VALUE_SIZE
, new PacketWriter ().WriteId (id
));
2588 return r
.ReadInt ();
2595 internal FieldMirrorInfo
Field_GetInfo (long id
) {
2596 PacketReader r
= SendReceive (CommandSet
.FIELD
, (int)CmdField
.GET_INFO
, new PacketWriter ().WriteId (id
));
2597 FieldMirrorInfo info
= new FieldMirrorInfo { Name = r.ReadString (), Parent = r.ReadId (), TypeId = r.ReadId (), Attrs = r.ReadInt () }
;
2605 internal int EnableEvent (EventType etype
, SuspendPolicy suspend_policy
, List
<Modifier
> mods
) {
2606 var w
= new PacketWriter ().WriteByte ((byte)etype
).WriteByte ((byte)suspend_policy
);
2608 if (mods
.Count
> 255)
2609 throw new NotImplementedException ();
2610 w
.WriteByte ((byte)mods
.Count
);
2611 foreach (Modifier mod
in mods
) {
2612 if (mod
is CountModifier
) {
2613 w
.WriteByte ((byte)ModifierKind
.COUNT
);
2614 w
.WriteInt ((mod
as CountModifier
).Count
);
2615 } else if (mod
is LocationModifier
) {
2616 w
.WriteByte ((byte)ModifierKind
.LOCATION_ONLY
);
2617 w
.WriteId ((mod
as LocationModifier
).Method
);
2618 w
.WriteLong ((mod
as LocationModifier
).Location
);
2619 } else if (mod
is StepModifier
) {
2620 w
.WriteByte ((byte)ModifierKind
.STEP
);
2621 w
.WriteId ((mod
as StepModifier
).Thread
);
2622 w
.WriteInt ((mod
as StepModifier
).Size
);
2623 w
.WriteInt ((mod
as StepModifier
).Depth
);
2624 if (Version
.AtLeast (2, 16))
2625 w
.WriteInt ((mod
as StepModifier
).Filter
);
2626 } else if (mod
is ThreadModifier
) {
2627 w
.WriteByte ((byte)ModifierKind
.THREAD_ONLY
);
2628 w
.WriteId ((mod
as ThreadModifier
).Thread
);
2629 } else if (mod
is ExceptionModifier
) {
2630 var em
= mod
as ExceptionModifier
;
2631 w
.WriteByte ((byte)ModifierKind
.EXCEPTION_ONLY
);
2632 w
.WriteId (em
.Type
);
2633 if (Version
.MajorVersion
> 2 || Version
.MinorVersion
> 0) {
2634 /* This is only supported in protocol version 2.1 */
2635 w
.WriteBool (em
.Caught
);
2636 w
.WriteBool (em
.Uncaught
);
2637 } else if (!em
.Caught
|| !em
.Uncaught
) {
2638 throw new NotSupportedException ("This request is not supported by the protocol version implemented by the debuggee.");
2640 if (Version
.MajorVersion
> 2 || Version
.MinorVersion
> 24) {
2641 w
.WriteBool (em
.Subclasses
);
2642 } else if (!em
.Subclasses
) {
2643 throw new NotSupportedException ("This request is not supported by the protocol version implemented by the debuggee.");
2645 if (Version
.MajorVersion
> 2 || Version
.MinorVersion
>= 54) {
2646 w
.WriteBool (em
.NotFilteredFeature
);
2647 w
.WriteBool (em
.EverythingElse
);
2649 } else if (mod
is AssemblyModifier
) {
2650 w
.WriteByte ((byte)ModifierKind
.ASSEMBLY_ONLY
);
2651 var amod
= (mod
as AssemblyModifier
);
2652 w
.WriteInt (amod
.Assemblies
.Length
);
2653 foreach (var id
in amod
.Assemblies
)
2655 } else if (mod
is SourceFileModifier
) {
2656 w
.WriteByte ((byte)ModifierKind
.SOURCE_FILE_ONLY
);
2657 var smod
= (mod
as SourceFileModifier
);
2658 w
.WriteInt (smod
.SourceFiles
.Length
);
2659 foreach (var s
in smod
.SourceFiles
)
2661 } else if (mod
is TypeNameModifier
) {
2662 w
.WriteByte ((byte)ModifierKind
.TYPE_NAME_ONLY
);
2663 var tmod
= (mod
as TypeNameModifier
);
2664 w
.WriteInt (tmod
.TypeNames
.Length
);
2665 foreach (var s
in tmod
.TypeNames
)
2668 throw new NotImplementedException ();
2674 return SendReceive (CommandSet
.EVENT_REQUEST
, (int)CmdEventRequest
.SET
, w
).ReadInt ();
2677 internal void ClearEventRequest (EventType etype
, int req_id
) {
2678 SendReceive (CommandSet
.EVENT_REQUEST
, (int)CmdEventRequest
.CLEAR
, new PacketWriter ().WriteByte ((byte)etype
).WriteInt (req_id
));
2681 internal void ClearAllBreakpoints () {
2682 SendReceive (CommandSet
.EVENT_REQUEST
, (int)CmdEventRequest
.CLEAR_ALL_BREAKPOINTS
, new PacketWriter ());
2688 internal ValueImpl
StackFrame_GetThis (long thread_id
, long id
) {
2689 PacketReader r
= SendReceive (CommandSet
.STACK_FRAME
, (int)CmdStackFrame
.GET_THIS
, new PacketWriter ().WriteId (thread_id
).WriteId (id
));
2690 return r
.ReadValue ();
2693 internal ValueImpl
[] StackFrame_GetValues (long thread_id
, long id
, int[] pos
) {
2694 /* pos < 0 -> argument at pos (-pos) - 1 */
2695 /* pos >= 0 -> local at pos */
2696 int len
= pos
.Length
;
2697 PacketReader r
= SendReceive (CommandSet
.STACK_FRAME
, (int)CmdStackFrame
.GET_VALUES
, new PacketWriter ().WriteId (thread_id
).WriteId (id
).WriteInt (len
).WriteInts (pos
));
2699 ValueImpl
[] res
= new ValueImpl
[len
];
2700 for (int i
= 0; i
< len
; ++i
)
2701 res
[i
] = r
.ReadValue ();
2705 internal void StackFrame_SetValues (long thread_id
, long id
, int[] pos
, ValueImpl
[] values
) {
2706 /* pos < 0 -> argument at pos (-pos) - 1 */
2707 /* pos >= 0 -> local at pos */
2708 int len
= pos
.Length
;
2709 SendReceive (CommandSet
.STACK_FRAME
, (int)CmdStackFrame
.SET_VALUES
, new PacketWriter ().WriteId (thread_id
).WriteId (id
).WriteInt (len
).WriteInts (pos
).WriteValues (values
));
2712 internal long StackFrame_GetDomain (long thread_id
, long id
) {
2713 return SendReceive (CommandSet
.STACK_FRAME
, (int)CmdStackFrame
.GET_DOMAIN
, new PacketWriter ().WriteId (thread_id
).WriteId (id
)).ReadId ();
2716 internal void StackFrame_SetThis (long thread_id
, long id
, ValueImpl
value) {
2717 SendReceive (CommandSet
.STACK_FRAME
, (int)CmdStackFrame
.SET_THIS
, new PacketWriter ().WriteId (thread_id
).WriteId (id
).WriteValue (value));
2723 internal int[] Array_GetLength (long id
, out int rank
, out int[] lower_bounds
) {
2724 var r
= SendReceive (CommandSet
.ARRAY_REF
, (int)CmdArrayRef
.GET_LENGTH
, new PacketWriter ().WriteId (id
));
2725 rank
= r
.ReadInt ();
2726 int[] res
= new int [rank
];
2727 lower_bounds
= new int [rank
];
2728 for (int i
= 0; i
< rank
; ++i
) {
2729 res
[i
] = r
.ReadInt ();
2730 lower_bounds
[i
] = r
.ReadInt ();
2735 internal ValueImpl
[] Array_GetValues (long id
, int index
, int len
) {
2736 var r
= SendReceive (CommandSet
.ARRAY_REF
, (int)CmdArrayRef
.GET_VALUES
, new PacketWriter ().WriteId (id
).WriteInt (index
).WriteInt (len
));
2737 ValueImpl
[] res
= new ValueImpl
[len
];
2738 for (int i
= 0; i
< len
; ++i
)
2739 res
[i
] = r
.ReadValue ();
2743 internal void Array_SetValues (long id
, int index
, ValueImpl
[] values
) {
2744 SendReceive (CommandSet
.ARRAY_REF
, (int)CmdArrayRef
.SET_VALUES
, new PacketWriter ().WriteId (id
).WriteInt (index
).WriteInt (values
.Length
).WriteValues (values
));
2750 internal string String_GetValue (long id
) {
2751 var r
= SendReceive (CommandSet
.STRING_REF
, (int)CmdStringRef
.GET_VALUE
, new PacketWriter ().WriteId (id
));
2753 bool is_utf16
= false;
2754 if (Version
.AtLeast (2, 41))
2755 is_utf16
= r
.ReadByte () == 1;
2758 return r
.ReadUTF16String ();
2760 return r
.ReadString ();
2763 internal int String_GetLength (long id
) {
2764 return (int)SendReceive (CommandSet
.STRING_REF
, (int)CmdStringRef
.GET_LENGTH
, new PacketWriter ().WriteId (id
)).ReadLong ();
2767 internal char[] String_GetChars (long id
, int index
, int length
) {
2768 var r
= SendReceive (CommandSet
.STRING_REF
, (int)CmdStringRef
.GET_CHARS
, new PacketWriter ().WriteId (id
).WriteLong (index
).WriteLong (length
));
2769 var res
= new char [length
];
2770 for (int i
= 0; i
< length
; ++i
)
2771 res
[i
] = (char)r
.ReadShort ();
2779 internal ValueImpl
Pointer_GetValue (long address
, TypeMirror type
)
2781 return SendReceive (CommandSet
.POINTER
, (int)CmdPointer
.GET_VALUE
, new PacketWriter ().WriteLong (address
).WriteId (type
.Id
)).ReadValue ();
2787 internal long Object_GetType (long id
) {
2788 return SendReceive (CommandSet
.OBJECT_REF
, (int)CmdObjectRef
.GET_TYPE
, new PacketWriter ().WriteId (id
)).ReadId ();
2791 internal long Object_GetDomain (long id
) {
2792 return SendReceive (CommandSet
.OBJECT_REF
, (int)CmdObjectRef
.GET_DOMAIN
, new PacketWriter ().WriteId (id
)).ReadId ();
2795 internal ValueImpl
[] Object_GetValues (long id
, long[] fields
) {
2796 int len
= fields
.Length
;
2797 PacketReader r
= SendReceive (CommandSet
.OBJECT_REF
, (int)CmdObjectRef
.GET_VALUES
, new PacketWriter ().WriteId (id
).WriteInt (len
).WriteIds (fields
));
2799 ValueImpl
[] res
= new ValueImpl
[len
];
2800 for (int i
= 0; i
< len
; ++i
)
2801 res
[i
] = r
.ReadValue ();
2805 internal void Object_SetValues (long id
, long[] fields
, ValueImpl
[] values
) {
2806 SendReceive (CommandSet
.OBJECT_REF
, (int)CmdObjectRef
.SET_VALUES
, new PacketWriter ().WriteId (id
).WriteInt (fields
.Length
).WriteIds (fields
).WriteValues (values
));
2809 internal bool Object_IsCollected (long id
) {
2810 return SendReceive (CommandSet
.OBJECT_REF
, (int)CmdObjectRef
.IS_COLLECTED
, new PacketWriter ().WriteId (id
)).ReadInt () == 1;
2813 internal long Object_GetAddress (long id
) {
2814 return SendReceive (CommandSet
.OBJECT_REF
, (int)CmdObjectRef
.GET_ADDRESS
, new PacketWriter ().WriteId (id
)).ReadLong ();
2817 internal ObjectRefInfo
Object_GetInfo (long id
) {
2818 ObjectRefInfo res
= new ObjectRefInfo ();
2819 PacketReader r
= SendReceive (CommandSet
.OBJECT_REF
, (int)CmdObjectRef
.GET_INFO
, new PacketWriter ().WriteId (id
));
2821 res
.type_id
= r
.ReadId ();
2822 res
.domain_id
= r
.ReadId ();
2826 public void ForceDisconnect ()
2829 disconnected
= true;
2830 DisconnectedEvent
.Set ();
2835 class TcpConnection
: Connection
2839 internal TcpConnection (Socket socket
)
2841 this.socket
= socket
;
2842 //socket.SetSocketOption (SocketOptionLevel.IP, SocketOptionName.NoDelay, 1);
2845 internal EndPoint EndPoint
{
2847 return socket
.RemoteEndPoint
;
2851 protected override int TransportSend (byte[] buf
, int buf_offset
, int len
)
2853 return socket
.Send (buf
, buf_offset
, len
, SocketFlags
.None
);
2856 protected override int TransportReceive (byte[] buf
, int buf_offset
, int len
)
2858 return socket
.Receive (buf
, buf_offset
, len
, SocketFlags
.None
);
2861 protected override void TransportSetTimeouts (int send_timeout
, int receive_timeout
)
2863 socket
.SendTimeout
= send_timeout
;
2864 socket
.ReceiveTimeout
= receive_timeout
;
2867 protected override void TransportClose ()
2872 protected override void TransportShutdown ()
2874 socket
.Shutdown (SocketShutdown
.Both
);
2878 /* This is the interface exposed by the debugger towards the debugger agent */
2879 interface IEventHandler
2881 void Events (SuspendPolicy suspend_policy
, EventInfo
[] events
);
2883 void VMDisconnect (int req_id
, long thread_id
, string vm_uri
);