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
{
412 public string ErrorMessage
{
418 * Represents the connection to the debuggee
420 public abstract class Connection
423 * The protocol and the packet format is based on JDWP, the differences
424 * are in the set of supported events, and the commands.
426 internal const string HANDSHAKE_STRING
= "DWP-Handshake";
428 internal const int HEADER_LENGTH
= 11;
430 static readonly bool EnableConnectionLogging
= !String
.IsNullOrEmpty (Environment
.GetEnvironmentVariable ("MONO_SDB_LOG"));
431 static int ConnectionId
;
432 readonly StreamWriter LoggingStream
;
435 * Th version of the wire-protocol implemented by the library. The library
436 * and the debuggee can communicate if they implement the same major version.
437 * If they implement a different minor version, they can communicate, but some
438 * features might not be available. This allows older clients to communicate
439 * with newer runtimes, and vice versa.
441 internal const int MAJOR_VERSION
= 2;
442 internal const int MINOR_VERSION
= 56;
444 enum WPSuspendPolicy
{
473 APPDOMAIN_CREATE
= 4, // Not in JDI
474 APPDOMAIN_UNLOAD
= 5, // Not in JDI
496 SOURCE_FILE_ONLY
= 12,
508 SET_PROTOCOL_VERSION
= 8,
511 GET_TYPES_FOR_SOURCE_FILE
= 11,
514 START_BUFFERING
= 14,
527 /* FIXME: Merge into GET_INFO when the major protocol version is increased */
535 enum CmdEventRequest
{
538 CLEAR_ALL_BREAKPOINTS
= 3
543 GET_FRIENDLY_NAME
= 2,
545 GET_ENTRY_ASSEMBLY
= 4,
548 CREATE_BOXED_VALUE
= 7,
549 CREATE_BYTE_ARRAY
= 8,
555 GET_MANIFEST_MODULE
= 3,
560 GET_METADATA_BLOB
= 8,
563 GET_TYPE_FROM_TOKEN
= 11,
564 GET_METHOD_FROM_TOKEN
= 12,
574 GET_DECLARING_TYPE
= 2,
582 MAKE_GENERIC_METHOD
= 10
591 GET_SOURCE_FILES
= 6,
593 IS_ASSIGNABLE_FROM
= 8,
596 GET_FIELD_CATTRS
= 11,
597 GET_PROPERTY_CATTRS
= 12,
598 /* FIXME: Merge into GET_SOURCE_FILES when the major protocol version is increased */
599 GET_SOURCE_FILES_2
= 13,
600 /* FIXME: Merge into GET_VALUES when the major protocol version is increased */
602 CMD_TYPE_GET_METHODS_BY_NAME_FLAGS
= 15,
604 GET_INTERFACE_MAP
= 17,
606 CREATE_INSTANCE
= 19,
615 enum BindingFlagsExtensions
{
616 BINDING_FLAGS_IGNORE_CASE
= 0x70000000,
619 enum MemberListTypeExtensions
{
660 public int command_set
;
665 internal static int GetPacketLength (byte[] header
) {
667 return decode_int (header
, ref offset
);
670 internal static bool IsReplyPacket (byte[] packet
) {
672 return decode_byte (packet
, ref offset
) == 0x80;
675 internal static int GetPacketId (byte[] packet
) {
677 return decode_int (packet
, ref offset
);
680 static int decode_byte (byte[] packet
, ref int offset
) {
681 return packet
[offset
++];
684 static byte[] decode_bytes (byte[] packet
, ref int offset
, int length
)
686 if (length
+ offset
> packet
.Length
)
687 throw new ArgumentOutOfRangeException ();
689 var bytes
= new byte[length
];
690 Array
.Copy (packet
, offset
, bytes
, 0, length
);
695 static int decode_short (byte[] packet
, ref int offset
) {
696 int res
= ((int)packet
[offset
] << 8) | (int)packet
[offset
+ 1];
701 static int decode_int (byte[] packet
, ref int offset
) {
702 int res
= ((int)packet
[offset
] << 24) | ((int)packet
[offset
+ 1] << 16) | ((int)packet
[offset
+ 2] << 8) | (int)packet
[offset
+ 3];
707 static long decode_id (byte[] packet
, ref int offset
) {
708 return decode_int (packet
, ref offset
);
711 static long decode_long (byte[] packet
, ref int offset
) {
712 uint high
= (uint)decode_int (packet
, ref offset
);
713 uint low
= (uint)decode_int (packet
, ref offset
);
715 return (long)(((ulong)high
<< 32) | (ulong)low
);
718 internal static SuspendPolicy
decode_suspend_policy (int suspend_policy
) {
719 switch ((WPSuspendPolicy
)suspend_policy
) {
720 case WPSuspendPolicy
.NONE
:
721 return SuspendPolicy
.None
;
722 case WPSuspendPolicy
.EVENT_THREAD
:
723 return SuspendPolicy
.EventThread
;
724 case WPSuspendPolicy
.ALL
:
725 return SuspendPolicy
.All
;
727 throw new NotImplementedException ();
731 static Header
decode_command_header (byte[] packet
) {
733 Header res
= new Header ();
735 decode_int (packet
, ref offset
);
736 res
.id
= decode_int (packet
, ref offset
);
737 res
.flags
= decode_byte (packet
, ref offset
);
738 res
.command_set
= decode_byte (packet
, ref offset
);
739 res
.command
= decode_byte (packet
, ref offset
);
744 static void encode_byte (byte[] buf
, int b
, ref int offset
) {
745 buf
[offset
] = (byte)b
;
749 static void encode_int (byte[] buf
, int i
, ref int offset
) {
750 buf
[offset
] = (byte)((i
>> 24) & 0xff);
751 buf
[offset
+ 1] = (byte)((i
>> 16) & 0xff);
752 buf
[offset
+ 2] = (byte)((i
>> 8) & 0xff);
753 buf
[offset
+ 3] = (byte)((i
>> 0) & 0xff);
757 static void encode_id (byte[] buf
, long id
, ref int offset
) {
758 encode_int (buf
, (int)id
, ref offset
);
761 static void encode_long (byte[] buf
, long l
, ref int offset
) {
762 encode_int (buf
, (int)((l
>> 32) & 0xffffffff), ref offset
);
763 encode_int (buf
, (int)(l
& 0xffffffff), ref offset
);
766 internal static byte[] EncodePacket (int id
, int commandSet
, int command
, byte[] data
, int dataLen
) {
767 byte[] buf
= new byte [dataLen
+ 11];
770 encode_int (buf
, buf
.Length
, ref offset
);
771 encode_int (buf
, id
, ref offset
);
772 encode_byte (buf
, 0, ref offset
);
773 encode_byte (buf
, commandSet
, ref offset
);
774 encode_byte (buf
, command
, ref offset
);
776 for (int i
= 0; i
< dataLen
; ++i
)
777 buf
[offset
+ i
] = data
[i
];
783 Connection connection
;
787 public PacketReader (Connection connection
, byte[] packet
) {
788 this.connection
= connection
;
789 this.packet
= packet
;
792 Header header
= decode_command_header (packet
);
793 CommandSet
= (CommandSet
)header
.command_set
;
794 Command
= header
.command
;
798 var len
= ReadInt (); // length
800 ReadByte (); // flags
801 ErrorCode
= ReadShort ();
802 if (ErrorCode
== (int)Mono
.Debugger
.Soft
.ErrorCode
.INVALID_ARGUMENT
&& connection
.Version
.AtLeast (2, 56) && len
> offset
)
803 ErrorMsg
= ReadString ();
806 public CommandSet CommandSet
{
814 public int ErrorCode
{
818 public string ErrorMsg
{
828 public int ReadByte () {
829 return decode_byte (packet
, ref offset
);
832 public int ReadShort () {
833 return decode_short (packet
, ref offset
);
836 public int ReadInt () {
837 return decode_int (packet
, ref offset
);
840 public long ReadId () {
841 return decode_id (packet
, ref offset
);
844 public long ReadLong () {
845 return decode_long (packet
, ref offset
);
848 public float ReadFloat () {
849 float f
= DataConverter
.FloatFromBE (packet
, offset
);
854 public double ReadDouble () {
855 double d
= DataConverter
.DoubleFromBE (packet
, offset
);
860 public string ReadString () {
861 int len
= decode_int (packet
, ref offset
);
862 string res
= new String (Encoding
.UTF8
.GetChars (packet
, offset
, len
));
867 public string ReadUTF16String () {
868 int len
= decode_int (packet
, ref offset
);
869 string res
= new String (Encoding
.Unicode
.GetChars (packet
, offset
, len
));
874 public ValueImpl
ReadValue () {
875 ElementType etype
= (ElementType
)ReadByte ();
877 case ElementType
.Void
:
878 return new ValueImpl { Type = etype }
;
880 return new ValueImpl { Type = etype, Value = (sbyte)ReadInt () }
;
882 return new ValueImpl { Type = etype, Value = (byte)ReadInt () }
;
883 case ElementType
.Boolean
:
884 return new ValueImpl { Type = etype, Value = ReadInt () != 0 }
;
886 return new ValueImpl { Type = etype, Value = (short)ReadInt () }
;
888 return new ValueImpl { Type = etype, Value = (ushort)ReadInt () }
;
889 case ElementType
.Char
:
890 return new ValueImpl { Type = etype, Value = (char)ReadInt () }
;
892 return new ValueImpl { Type = etype, Value = ReadInt () }
;
894 return new ValueImpl { Type = etype, Value = (uint)ReadInt () }
;
896 return new ValueImpl { Type = etype, Value = ReadLong () }
;
898 return new ValueImpl { Type = etype, Value = (ulong)ReadLong () }
;
900 return new ValueImpl { Type = etype, Value = ReadFloat () }
;
902 return new ValueImpl { Type = etype, Value = ReadDouble () }
;
905 // FIXME: The client and the debuggee might have different word sizes
906 return new ValueImpl { Type = etype, Value = ReadLong () }
;
907 case ElementType
.Ptr
:
908 long value = ReadLong ();
909 if (connection
.Version
.AtLeast (2, 46)) {
910 long pointerClass
= ReadId ();
911 return new ValueImpl { Type = etype, Klass = pointerClass, Value = value }
;
913 return new ValueImpl { Type = etype, Value = value }
;
915 case ElementType
.String
:
916 case ElementType
.SzArray
:
917 case ElementType
.Class
:
918 case ElementType
.Array
:
919 case ElementType
.Object
:
920 long objid
= ReadId ();
921 return new ValueImpl () { Type = etype, Objid = objid }
;
922 case ElementType
.ValueType
:
923 bool is_enum
= ReadByte () == 1;
924 long klass
= ReadId ();
925 long nfields
= ReadInt ();
926 ValueImpl
[] fields
= new ValueImpl
[nfields
];
927 for (int i
= 0; i
< nfields
; ++i
)
928 fields
[i
] = ReadValue ();
929 return new ValueImpl () { Type = etype, Klass = klass, Fields = fields, IsEnum = is_enum }
;
930 case (ElementType
)ValueTypeId
.VALUE_TYPE_ID_NULL
:
931 return new ValueImpl { Type = etype }
;
932 case (ElementType
)ValueTypeId
.VALUE_TYPE_ID_TYPE
:
933 return new ValueImpl () { Type = etype, Id = ReadId () }
;
934 case (ElementType
)ValueTypeId
.VALUE_TYPE_ID_PARENT_VTYPE
:
935 return new ValueImpl () { Type = etype, Index = ReadInt () }
;
936 case (ElementType
)ValueTypeId
.VALUE_TYPE_ID_FIXED_ARRAY
:
937 return ReadValueFixedSize ();
939 throw new NotImplementedException ("Unable to handle type " + etype
);
943 ValueImpl
ReadValueFixedSize () {
944 var lenFixedSize
= 1;
945 ElementType etype
= (ElementType
)ReadByte ();
946 lenFixedSize
= ReadInt ();
948 case ElementType
.I1
: {
949 var val
= new sbyte[lenFixedSize
];
950 for (int i
= 0; i
< lenFixedSize
; i
++)
951 val
[i
] = (sbyte)ReadInt ();
952 return new ValueImpl { Type = etype, Value = val }
;
954 case ElementType
.U1
: {
955 var val
= new byte[lenFixedSize
];
956 for (int i
= 0; i
< lenFixedSize
; i
++)
957 val
[i
] = (byte)ReadInt ();
958 return new ValueImpl { Type = etype, Value = val }
;
960 case ElementType
.Boolean
: {
961 var val
= new bool[lenFixedSize
];
962 for (int i
= 0; i
< lenFixedSize
; i
++)
963 val
[i
] = (ReadInt () != 0);
964 return new ValueImpl { Type = etype, Value = val }
;
966 case ElementType
.I2
: {
967 var val
= new short[lenFixedSize
];
968 for (int i
= 0; i
< lenFixedSize
; i
++)
969 val
[i
] = (short)ReadInt ();
970 return new ValueImpl { Type = etype, Value = val }
;
972 case ElementType
.U2
: {
973 var val
= new ushort[lenFixedSize
];
974 for (int i
= 0; i
< lenFixedSize
; i
++)
975 val
[i
] = (ushort)ReadInt ();
976 return new ValueImpl { Type = etype, Value = val }
;
978 case ElementType
.Char
: {
979 var val
= new char[lenFixedSize
];
980 for (int i
= 0; i
< lenFixedSize
; i
++)
981 val
[i
] = (char)ReadInt ();
982 return new ValueImpl { Type = etype, Value = val }
;
984 case ElementType
.I4
: {
985 var val
= new int[lenFixedSize
];
986 for (int i
= 0; i
< lenFixedSize
; i
++)
988 return new ValueImpl { Type = etype, Value = val }
;
990 case ElementType
.U4
: {
991 var val
= new uint[lenFixedSize
];
992 for (int i
= 0; i
< lenFixedSize
; i
++)
993 val
[i
] = (uint)ReadInt ();
994 return new ValueImpl { Type = etype, Value = val }
;
996 case ElementType
.I8
: {
997 var val
= new long[lenFixedSize
];
998 for (int i
= 0; i
< lenFixedSize
; i
++)
999 val
[i
] = ReadLong ();
1000 return new ValueImpl { Type = etype, Value = val }
;
1002 case ElementType
.U8
: {
1003 var val
= new ulong[lenFixedSize
];
1004 for (int i
= 0; i
< lenFixedSize
; i
++)
1005 val
[i
] = (ulong) ReadLong ();
1006 return new ValueImpl { Type = etype, Value = val }
;
1008 case ElementType
.R4
: {
1009 var val
= new float[lenFixedSize
];
1010 for (int i
= 0; i
< lenFixedSize
; i
++)
1011 val
[i
] = ReadFloat ();
1012 return new ValueImpl { Type = etype, Value = val }
;
1014 case ElementType
.R8
: {
1015 var val
= new double[lenFixedSize
];
1016 for (int i
= 0; i
< lenFixedSize
; i
++)
1017 val
[i
] = ReadDouble ();
1018 return new ValueImpl { Type = etype, Value = val }
;
1021 throw new NotImplementedException ("Unable to handle type " + etype
);
1024 public long[] ReadIds (int n
) {
1025 long[] res
= new long [n
];
1026 for (int i
= 0; i
< n
; ++i
)
1027 res
[i
] = ReadId ();
1031 public byte[] ReadByteArray () {
1032 var length
= ReadInt ();
1033 return decode_bytes (packet
, ref offset
, length
);
1036 public bool ReadBool () {
1037 return ReadByte () != 0;
1041 class PacketWriter
{
1046 public PacketWriter () {
1047 data
= new byte [1024];
1051 void MakeRoom (int size
) {
1052 if (offset
+ size
>= data
.Length
) {
1053 int new_len
= data
.Length
* 2;
1054 while (new_len
< offset
+ size
) {
1057 byte[] new_data
= new byte [new_len
];
1058 Array
.Copy (data
, new_data
, data
.Length
);
1063 public PacketWriter
WriteByte (byte val
) {
1065 encode_byte (data
, val
, ref offset
);
1069 public PacketWriter
WriteInt (int val
) {
1071 encode_int (data
, val
, ref offset
);
1075 public PacketWriter
WriteId (long id
) {
1077 encode_id (data
, id
, ref offset
);
1081 public PacketWriter
WriteLong (long val
) {
1083 encode_long (data
, val
, ref offset
);
1087 public PacketWriter
WriteFloat (float f
) {
1089 byte[] b
= DataConverter
.GetBytesBE (f
);
1090 for (int i
= 0; i
< 4; ++i
)
1091 data
[offset
+ i
] = b
[i
];
1096 public PacketWriter
WriteDouble (double d
) {
1098 byte[] b
= DataConverter
.GetBytesBE (d
);
1099 for (int i
= 0; i
< 8; ++i
)
1100 data
[offset
+ i
] = b
[i
];
1105 public PacketWriter
WriteInts (int[] ids
) {
1106 for (int i
= 0; i
< ids
.Length
; ++i
)
1111 public PacketWriter
WriteIds (long[] ids
) {
1112 for (int i
= 0; i
< ids
.Length
; ++i
)
1117 public PacketWriter
WriteString (string s
) {
1119 return WriteInt (-1);
1121 byte[] b
= Encoding
.UTF8
.GetBytes (s
);
1123 encode_int (data
, b
.Length
, ref offset
);
1124 MakeRoom (b
.Length
);
1125 Buffer
.BlockCopy (b
, 0, data
, offset
, b
.Length
);
1129 public PacketWriter
WriteBytes (byte[] b
) {
1131 return WriteInt (-1);
1133 encode_int (data
, b
.Length
, ref offset
);
1134 MakeRoom (b
.Length
);
1135 Buffer
.BlockCopy (b
, 0, data
, offset
, b
.Length
);
1140 public PacketWriter
WriteBool (bool val
) {
1141 WriteByte (val
? (byte)1 : (byte)0);
1145 public PacketWriter
WriteValue (ValueImpl v
) {
1148 if (v
.Value
!= null)
1149 t
= TypeCodeToElementType (Type
.GetTypeCode (v
.Value
.GetType ()), v
.Value
.GetType ());
1152 if (v
.FixedSize
> 1 && t
!= ElementType
.ValueType
) {
1153 WriteFixedSizeValue (v
);
1156 WriteByte ((byte)t
);
1158 case ElementType
.Boolean
:
1159 WriteInt ((bool)v
.Value
? 1 : 0);
1161 case ElementType
.Char
:
1162 WriteInt ((int)(char)v
.Value
);
1164 case ElementType
.I1
:
1165 WriteInt ((int)(sbyte)v
.Value
);
1167 case ElementType
.U1
:
1168 WriteInt ((int)(byte)v
.Value
);
1170 case ElementType
.I2
:
1171 WriteInt ((int)(short)v
.Value
);
1173 case ElementType
.U2
:
1174 WriteInt ((int)(ushort)v
.Value
);
1176 case ElementType
.I4
:
1177 WriteInt ((int)(int)v
.Value
);
1179 case ElementType
.U4
:
1180 WriteInt ((int)(uint)v
.Value
);
1182 case ElementType
.I8
:
1183 WriteLong ((long)(long)v
.Value
);
1185 case ElementType
.U8
:
1186 WriteLong ((long)(ulong)v
.Value
);
1188 case ElementType
.R4
:
1189 WriteFloat ((float)v
.Value
);
1191 case ElementType
.R8
:
1192 WriteDouble ((double)v
.Value
);
1194 case ElementType
.String
:
1195 case ElementType
.SzArray
:
1196 case ElementType
.Class
:
1197 case ElementType
.Array
:
1198 case ElementType
.Object
:
1201 case ElementType
.ValueType
:
1204 throw new NotImplementedException ();
1207 WriteInt (v
.Fields
.Length
);
1208 for (int i
= 0; i
< v
.Fields
.Length
; ++i
)
1209 WriteValue (v
.Fields
[i
]);
1211 case (ElementType
)ValueTypeId
.VALUE_TYPE_ID_NULL
:
1214 throw new NotImplementedException ();
1220 PacketWriter
WriteFixedSizeValue (ValueImpl v
) {
1223 if (v
.Value
!= null)
1224 t
= TypeCodeToElementType (Type
.GetTypeCode (v
.Value
.GetType ()), v
.Value
.GetType ());
1227 WriteByte ((byte) ValueTypeId
.VALUE_TYPE_ID_FIXED_ARRAY
);
1228 WriteByte ((byte)t
);
1229 WriteInt (v
.FixedSize
);
1230 for (int j
= 0 ; j
< v
.FixedSize
; j
++) {
1232 case ElementType
.Boolean
:
1233 WriteInt (((bool[])v
.Value
)[j
]? 1 : 0);
1235 case ElementType
.Char
:
1236 WriteInt ((int)((char[])v
.Value
)[j
]);
1238 case ElementType
.I1
:
1239 WriteInt ((int)((sbyte[])v
.Value
)[j
]);
1241 case ElementType
.U1
:
1242 WriteInt ((int)((byte[])v
.Value
)[j
]);
1244 case ElementType
.I2
:
1245 WriteInt ((int)((short[])v
.Value
)[j
]);
1247 case ElementType
.U2
:
1248 WriteInt ((int)((ushort[])v
.Value
)[j
]);
1250 case ElementType
.I4
:
1251 WriteInt ((int)((int[])v
.Value
)[j
]);
1253 case ElementType
.U4
:
1254 WriteInt ((int)((uint[])v
.Value
)[j
]);
1256 case ElementType
.I8
:
1257 WriteLong ((long)((long[])v
.Value
)[j
]);
1259 case ElementType
.U8
:
1260 WriteLong ((long)((ulong[])v
.Value
)[j
]);
1262 case ElementType
.R4
:
1263 WriteFloat (((float[])v
.Value
)[j
]);
1265 case ElementType
.R8
:
1266 WriteDouble (((double[])v
.Value
)[j
]);
1269 throw new NotImplementedException ();
1275 public PacketWriter
WriteValues (ValueImpl
[] values
) {
1276 for (int i
= 0; i
< values
.Length
; ++i
)
1277 WriteValue (values
[i
]);
1281 public byte[] Data
{
1294 delegate void ReplyCallback (int packet_id
, byte[] packet
);
1297 Thread receiver_thread
;
1298 Dictionary
<int, byte[]> reply_packets
;
1299 Dictionary
<int, ReplyCallback
> reply_cbs
;
1300 Dictionary
<int, int> reply_cb_counts
;
1301 object reply_packets_monitor
;
1303 internal event EventHandler
<ErrorHandlerEventArgs
> ErrorHandler
;
1305 protected Connection () {
1307 reply_packets
= new Dictionary
<int, byte[]> ();
1308 reply_cbs
= new Dictionary
<int, ReplyCallback
> ();
1309 reply_cb_counts
= new Dictionary
<int, int> ();
1310 reply_packets_monitor
= new Object ();
1311 if (EnableConnectionLogging
) {
1312 var path
= Environment
.GetEnvironmentVariable ("MONO_SDB_LOG");
1313 if (path
.Contains ("{0}")) {
1314 //C:\SomeDir\sdbLog{0}.txt -> C:\SomeDir\sdbLog1.txt
1315 LoggingStream
= new StreamWriter (string.Format (path
, ConnectionId
++), false);
1316 } else if (Path
.HasExtension (path
)) {
1317 //C:\SomeDir\sdbLog.txt -> C:\SomeDir\sdbLog1.txt
1318 LoggingStream
= new StreamWriter (Path
.GetDirectoryName (path
) + Path
.DirectorySeparatorChar
+ Path
.GetFileNameWithoutExtension (path
) + ConnectionId
++ + "." + Path
.GetExtension (path
), false);
1320 //C:\SomeDir\sdbLog -> C:\SomeDir\sdbLog1
1321 LoggingStream
= new StreamWriter (path
+ ConnectionId
++, false);
1326 protected abstract int TransportReceive (byte[] buf
, int buf_offset
, int len
);
1327 protected abstract int TransportSend (byte[] buf
, int buf_offset
, int len
);
1328 protected abstract void TransportSetTimeouts (int send_timeout
, int receive_timeout
);
1329 protected abstract void TransportClose ();
1330 // Shutdown breaks all communication, resuming blocking waits
1331 protected abstract void TransportShutdown ();
1333 internal VersionInfo Version
;
1335 int Receive (byte[] buf
, int buf_offset
, int len
) {
1338 while (offset
< len
) {
1339 int n
= TransportReceive (buf
, buf_offset
+ offset
, len
- offset
);
1349 // Do the wire protocol handshake
1350 internal void Connect () {
1351 byte[] buf
= new byte [HANDSHAKE_STRING
.Length
];
1352 char[] cbuf
= new char [buf
.Length
];
1354 // FIXME: Add a timeout
1355 int n
= Receive (buf
, 0, buf
.Length
);
1357 throw new IOException ("DWP Handshake failed.");
1358 for (int i
= 0; i
< buf
.Length
; ++i
)
1359 cbuf
[i
] = (char)buf
[i
];
1361 if (new String (cbuf
) != HANDSHAKE_STRING
)
1362 throw new IOException ("DWP Handshake failed.");
1364 TransportSend (buf
, 0, buf
.Length
);
1366 receiver_thread
= new Thread (new ThreadStart (receiver_thread_main
));
1367 receiver_thread
.Name
= "SDB Receiver";
1368 receiver_thread
.IsBackground
= true;
1369 receiver_thread
.Start ();
1371 Version
= VM_GetVersion ();
1374 // Tell the debuggee our protocol version, so newer debuggees can work
1375 // with older clients
1379 // Older debuggees might not support this request
1380 EventHandler
<ErrorHandlerEventArgs
> OrigErrorHandler
= ErrorHandler
;
1381 ErrorHandler
= null;
1382 ErrorHandler
+= delegate (object sender
, ErrorHandlerEventArgs args
) {
1383 throw new NotSupportedException ();
1386 VM_SetProtocolVersion (MAJOR_VERSION
, MINOR_VERSION
);
1387 } catch (NotSupportedException
) {
1389 ErrorHandler
= OrigErrorHandler
;
1392 internal byte[] ReadPacket () {
1393 // FIXME: Throw ClosedConnectionException () if the connection is closed
1394 // FIXME: Throw ClosedConnectionException () if another thread closes the connection
1396 byte[] header
= new byte [HEADER_LENGTH
];
1398 int len
= Receive (header
, 0, header
.Length
);
1400 return new byte [0];
1401 if (len
!= HEADER_LENGTH
) {
1403 throw new IOException ("Packet of length " + len
+ " is read.");
1406 int packetLength
= GetPacketLength (header
);
1407 if (packetLength
< 11)
1408 throw new IOException ("Invalid packet length.");
1410 if (packetLength
== 11) {
1413 byte[] buf
= new byte [packetLength
];
1414 for (int i
= 0; i
< header
.Length
; ++i
)
1415 buf
[i
] = header
[i
];
1416 len
= Receive (buf
, header
.Length
, packetLength
- header
.Length
);
1417 if (len
!= packetLength
- header
.Length
)
1418 throw new IOException ();
1423 internal void WritePacket (byte[] packet
) {
1424 // FIXME: Throw ClosedConnectionException () if the connection is closed
1425 // FIXME: Throw ClosedConnectionException () if another thread closes the connection
1427 TransportSend (packet
, 0, packet
.Length
);
1430 internal void WritePackets (List
<byte[]> packets
) {
1431 // FIXME: Throw ClosedConnectionException () if the connection is closed
1432 // FIXME: Throw ClosedConnectionException () if another thread closes the connection
1435 for (int i
= 0; i
< packets
.Count
; ++i
)
1436 len
+= packets
[i
].Length
;
1437 byte[] data
= new byte [len
];
1439 for (int i
= 0; i
< packets
.Count
; ++i
) {
1440 Buffer
.BlockCopy (packets
[i
], 0, data
, pos
, packets
[i
].Length
);
1441 pos
+= packets
[i
].Length
;
1443 TransportSend (data
, 0, data
.Length
);
1446 internal void Close () {
1448 TransportShutdown ();
1451 internal bool IsClosed
{
1458 VMCrashException crashed
;
1460 internal ManualResetEvent DisconnectedEvent
= new ManualResetEvent (false);
1462 void receiver_thread_main () {
1465 bool res
= ReceivePacket ();
1469 } catch (ThreadAbortException
) {
1471 } catch (VMCrashException ex
) {
1474 } catch (Exception ex
) {
1476 Console
.WriteLine (ex
);
1482 lock (reply_packets_monitor
) {
1483 disconnected
= true;
1484 DisconnectedEvent
.Set ();
1485 Monitor
.PulseAll (reply_packets_monitor
);
1488 EventHandler
.VMDisconnect (0, 0, null);
1491 void disconnected_check () {
1494 else if (crashed
!= null)
1497 throw new VMDisconnectedException ();
1500 bool ReceivePacket () {
1501 byte[] packet
= ReadPacket ();
1503 if (packet
.Length
== 0) {
1507 if (IsReplyPacket (packet
)) {
1508 int id
= GetPacketId (packet
);
1509 ReplyCallback cb
= null;
1510 lock (reply_packets_monitor
) {
1511 reply_cbs
.TryGetValue (id
, out cb
);
1513 reply_packets
[id
] = packet
;
1514 Monitor
.PulseAll (reply_packets_monitor
);
1516 int c
= reply_cb_counts
[id
];
1519 reply_cbs
.Remove (id
);
1520 reply_cb_counts
.Remove (id
);
1526 cb
.Invoke (id
, packet
);
1528 PacketReader r
= new PacketReader (this, packet
);
1530 if (r
.CommandSet
== CommandSet
.EVENT
&& r
.Command
== (int)CmdEvent
.COMPOSITE
) {
1531 int spolicy
= r
.ReadByte ();
1532 int nevents
= r
.ReadInt ();
1534 SuspendPolicy suspend_policy
= decode_suspend_policy (spolicy
);
1536 EventInfo
[] events
= new EventInfo
[nevents
];
1538 for (int i
= 0; i
< nevents
; ++i
) {
1539 EventKind kind
= (EventKind
)r
.ReadByte ();
1540 int req_id
= r
.ReadInt ();
1542 EventType etype
= (EventType
)kind
;
1544 long thread_id
= r
.ReadId ();
1545 if (kind
== EventKind
.VM_START
) {
1546 events
[i
] = new EventInfo (etype
, req_id
) { ThreadId = thread_id }
;
1547 //EventHandler.VMStart (req_id, thread_id, null);
1548 } else if (kind
== EventKind
.VM_DEATH
) {
1550 if (Version
.AtLeast (2, 27))
1551 exit_code
= r
.ReadInt ();
1552 //EventHandler.VMDeath (req_id, 0, null);
1553 events
[i
] = new EventInfo (etype
, req_id
) { ExitCode = exit_code }
;
1554 } else if (kind
== EventKind
.CRASH
) {
1555 ulong hash
= (ulong) r
.ReadLong ();
1556 string dump
= r
.ReadString ();
1558 events
[i
] = new EventInfo (etype
, req_id
) { Dump = dump, Hash = hash}
;
1559 } else if (kind
== EventKind
.THREAD_START
) {
1560 events
[i
] = new EventInfo (etype
, req_id
) { ThreadId = thread_id, Id = thread_id }
;
1561 //EventHandler.ThreadStart (req_id, thread_id, thread_id);
1562 } else if (kind
== EventKind
.THREAD_DEATH
) {
1563 events
[i
] = new EventInfo (etype
, req_id
) { ThreadId = thread_id, Id = thread_id }
;
1564 //EventHandler.ThreadDeath (req_id, thread_id, thread_id);
1565 } else if (kind
== EventKind
.ASSEMBLY_LOAD
) {
1566 long id
= r
.ReadId ();
1567 events
[i
] = new EventInfo (etype
, req_id
) { ThreadId = thread_id, Id = id }
;
1568 //EventHandler.AssemblyLoad (req_id, thread_id, id);
1569 } else if (kind
== EventKind
.ASSEMBLY_UNLOAD
) {
1570 long id
= r
.ReadId ();
1571 events
[i
] = new EventInfo (etype
, req_id
) { ThreadId = thread_id, Id = id }
;
1572 //EventHandler.AssemblyUnload (req_id, thread_id, id);
1573 } else if (kind
== EventKind
.TYPE_LOAD
) {
1574 long id
= r
.ReadId ();
1575 events
[i
] = new EventInfo (etype
, req_id
) { ThreadId = thread_id, Id = id }
;
1576 //EventHandler.TypeLoad (req_id, thread_id, id);
1577 } else if (kind
== EventKind
.METHOD_ENTRY
) {
1578 long id
= r
.ReadId ();
1579 events
[i
] = new EventInfo (etype
, req_id
) { ThreadId = thread_id, Id = id }
;
1580 //EventHandler.MethodEntry (req_id, thread_id, id);
1581 } else if (kind
== EventKind
.METHOD_EXIT
) {
1582 long id
= r
.ReadId ();
1583 events
[i
] = new EventInfo (etype
, req_id
) { ThreadId = thread_id, Id = id }
;
1584 //EventHandler.MethodExit (req_id, thread_id, id);
1585 } else if (kind
== EventKind
.BREAKPOINT
) {
1586 long id
= r
.ReadId ();
1587 long loc
= r
.ReadLong ();
1588 events
[i
] = new EventInfo (etype
, req_id
) { ThreadId = thread_id, Id = id, Location = loc }
;
1589 //EventHandler.Breakpoint (req_id, thread_id, id, loc);
1590 } else if (kind
== EventKind
.STEP
) {
1591 long id
= r
.ReadId ();
1592 long loc
= r
.ReadLong ();
1593 events
[i
] = new EventInfo (etype
, req_id
) { ThreadId = thread_id, Id = id, Location = loc }
;
1594 //EventHandler.Step (req_id, thread_id, id, loc);
1595 } else if (kind
== EventKind
.EXCEPTION
) {
1596 long id
= r
.ReadId ();
1597 long loc
= 0; // FIXME
1598 events
[i
] = new EventInfo (etype
, req_id
) { ThreadId = thread_id, Id = id, Location = loc }
;
1599 //EventHandler.Exception (req_id, thread_id, id, loc);
1600 } else if (kind
== EventKind
.APPDOMAIN_CREATE
) {
1601 long id
= r
.ReadId ();
1602 events
[i
] = new EventInfo (etype
, req_id
) { ThreadId = thread_id, Id = id }
;
1603 //EventHandler.AppDomainCreate (req_id, thread_id, id);
1604 } else if (kind
== EventKind
.APPDOMAIN_UNLOAD
) {
1605 long id
= r
.ReadId ();
1606 events
[i
] = new EventInfo (etype
, req_id
) { ThreadId = thread_id, Id = id }
;
1607 //EventHandler.AppDomainUnload (req_id, thread_id, id);
1608 } else if (kind
== EventKind
.USER_BREAK
) {
1611 events
[i
] = new EventInfo (etype
, req_id
) { ThreadId = thread_id, Id = id, Location = loc }
;
1612 //EventHandler.Exception (req_id, thread_id, id, loc);
1613 } else if (kind
== EventKind
.USER_LOG
) {
1614 int level
= r
.ReadInt ();
1615 string category
= r
.ReadString ();
1616 string message
= r
.ReadString ();
1617 events
[i
] = new EventInfo (etype
, req_id
) { ThreadId = thread_id, Level = level, Category = category, Message = message }
;
1618 //EventHandler.Exception (req_id, thread_id, id, loc);
1619 } else if (kind
== EventKind
.KEEPALIVE
) {
1620 events
[i
] = new EventInfo (etype
, req_id
) { }
;
1622 throw new NotImplementedException ("Unknown event kind: " + kind
);
1626 EventHandler
.Events (suspend_policy
, events
);
1633 internal IEventHandler EventHandler
{
1637 static String
CommandString (CommandSet command_set
, int command
)
1640 switch (command_set
) {
1642 cmd
= ((CmdVM
)command
).ToString ();
1644 case CommandSet
.OBJECT_REF
:
1645 cmd
= ((CmdObjectRef
)command
).ToString ();
1647 case CommandSet
.STRING_REF
:
1648 cmd
= ((CmdStringRef
)command
).ToString ();
1650 case CommandSet
.THREAD
:
1651 cmd
= ((CmdThread
)command
).ToString ();
1653 case CommandSet
.ARRAY_REF
:
1654 cmd
= ((CmdArrayRef
)command
).ToString ();
1656 case CommandSet
.EVENT_REQUEST
:
1657 cmd
= ((CmdEventRequest
)command
).ToString ();
1659 case CommandSet
.STACK_FRAME
:
1660 cmd
= ((CmdStackFrame
)command
).ToString ();
1662 case CommandSet
.APPDOMAIN
:
1663 cmd
= ((CmdAppDomain
)command
).ToString ();
1665 case CommandSet
.ASSEMBLY
:
1666 cmd
= ((CmdAssembly
)command
).ToString ();
1668 case CommandSet
.METHOD
:
1669 cmd
= ((CmdMethod
)command
).ToString ();
1671 case CommandSet
.TYPE
:
1672 cmd
= ((CmdType
)command
).ToString ();
1674 case CommandSet
.MODULE
:
1675 cmd
= ((CmdModule
)command
).ToString ();
1677 case CommandSet
.FIELD
:
1678 cmd
= ((CmdField
)command
).ToString ();
1680 case CommandSet
.EVENT
:
1681 cmd
= ((CmdEvent
)command
).ToString ();
1684 cmd
= command
.ToString ();
1687 return string.Format ("[{0} {1}]", command_set
, cmd
);
1690 long total_protocol_ticks
;
1692 void LogPacket (int packet_id
, byte[] encoded_packet
, byte[] reply_packet
, CommandSet command_set
, int command
, Stopwatch watch
) {
1694 total_protocol_ticks
+= watch
.ElapsedTicks
;
1695 var ts
= TimeSpan
.FromTicks (total_protocol_ticks
);
1696 string msg
= string.Format ("Packet: {0} sent: {1} received: {2} ms: {3} total ms: {4} {5}",
1697 packet_id
, encoded_packet
.Length
, reply_packet
.Length
, watch
.ElapsedMilliseconds
,
1698 (ts
.Seconds
* 1000) + ts
.Milliseconds
,
1699 CommandString (command_set
, command
));
1701 LoggingStream
.WriteLine (msg
);
1702 LoggingStream
.Flush ();
1705 bool buffer_packets
;
1706 List
<byte[]> buffered_packets
= new List
<byte[]> ();
1709 // Start buffering request/response packets on both the client and the debuggee side.
1710 // Packets sent between StartBuffering ()/StopBuffering () must be async, i.e. sent
1711 // using Send () and not SendReceive ().
1713 public void StartBuffering () {
1714 buffer_packets
= true;
1715 if (Version
.AtLeast (2, 34))
1716 VM_StartBuffering ();
1719 public void StopBuffering () {
1720 if (Version
.AtLeast (2, 34))
1721 VM_StopBuffering ();
1722 buffer_packets
= false;
1724 WritePackets (buffered_packets
);
1725 if (EnableConnectionLogging
) {
1726 LoggingStream
.WriteLine (String
.Format ("Sent {0} packets.", buffered_packets
.Count
));
1727 LoggingStream
.Flush ();
1729 buffered_packets
.Clear ();
1732 /* Send a request and call cb when a result is received */
1733 int Send (CommandSet command_set
, int command
, PacketWriter packet
, Action
<PacketReader
> cb
, int count
) {
1734 int id
= IdGenerator
;
1736 Stopwatch watch
= null;
1737 if (EnableConnectionLogging
)
1738 watch
= Stopwatch
.StartNew ();
1740 byte[] encoded_packet
;
1742 encoded_packet
= EncodePacket (id
, (int)command_set
, command
, null, 0);
1744 encoded_packet
= EncodePacket (id
, (int)command_set
, command
, packet
.Data
, packet
.Offset
);
1747 lock (reply_packets_monitor
) {
1748 reply_cbs
[id
] = delegate (int packet_id
, byte[] p
) {
1749 if (EnableConnectionLogging
)
1750 LogPacket (packet_id
, encoded_packet
, p
, command_set
, command
, watch
);
1751 /* Run the callback on a tp thread to avoid blocking the receive thread */
1752 PacketReader r
= new PacketReader (this, p
);
1753 cb
.BeginInvoke (r
, null, null);
1755 reply_cb_counts
[id
] = count
;
1760 buffered_packets
.Add (encoded_packet
);
1762 WritePacket (encoded_packet
);
1767 // Send a request without waiting for an answer
1768 void Send (CommandSet command_set
, int command
) {
1769 Send (command_set
, command
, null, null, 0);
1772 PacketReader
SendReceive (CommandSet command_set
, int command
, PacketWriter packet
) {
1773 int id
= IdGenerator
;
1774 Stopwatch watch
= null;
1776 disconnected_check ();
1778 if (EnableConnectionLogging
)
1779 watch
= Stopwatch
.StartNew ();
1781 byte[] encoded_packet
;
1784 encoded_packet
= EncodePacket (id
, (int)command_set
, command
, null, 0);
1786 encoded_packet
= EncodePacket (id
, (int)command_set
, command
, packet
.Data
, packet
.Offset
);
1788 WritePacket (encoded_packet
);
1792 /* Wait for the reply packet */
1794 lock (reply_packets_monitor
) {
1796 if (reply_packets
.TryGetValue (packetId
, out reply
)) {
1797 reply_packets
.Remove (packetId
);
1798 PacketReader r
= new PacketReader (this, reply
);
1800 if (EnableConnectionLogging
)
1801 LogPacket (packetId
, encoded_packet
, reply
, command_set
, command
, watch
);
1802 if (r
.ErrorCode
!= 0) {
1803 if (ErrorHandler
!= null)
1804 ErrorHandler (this, new ErrorHandlerEventArgs () { ErrorCode = (ErrorCode)r.ErrorCode, ErrorMessage = r.ErrorMsg}
);
1805 throw new NotImplementedException ("No error handler set.");
1810 disconnected_check ();
1811 Monitor
.Wait (reply_packets_monitor
);
1817 PacketReader
SendReceive (CommandSet command_set
, int command
) {
1818 return SendReceive (command_set
, command
, null);
1821 int packet_id_generator
;
1825 return Interlocked
.Increment (ref packet_id_generator
);
1829 CattrInfo
[] ReadCattrs (PacketReader r
) {
1830 CattrInfo
[] res
= new CattrInfo
[r
.ReadInt ()];
1831 for (int i
= 0; i
< res
.Length
; ++i
) {
1832 CattrInfo info
= new CattrInfo ();
1833 info
.ctor_id
= r
.ReadId ();
1834 info
.ctor_args
= new ValueImpl
[r
.ReadInt ()];
1835 for (int j
= 0; j
< info
.ctor_args
.Length
; ++j
) {
1836 info
.ctor_args
[j
] = r
.ReadValue ();
1838 info
.named_args
= new CattrNamedArgInfo
[r
.ReadInt ()];
1839 for (int j
= 0; j
< info
.named_args
.Length
; ++j
) {
1840 CattrNamedArgInfo arg
= new CattrNamedArgInfo ();
1841 int arg_type
= r
.ReadByte ();
1842 arg
.is_property
= arg_type
== 0x54;
1844 // 2.12 is the only version we can guarantee the server will send a field id
1845 // It was added in https://github.com/mono/mono/commit/db0b932cd6c3c93976479ae3f6b5b2a885f681de
1846 // In between 2.11 and 2.12
1847 if (arg
.is_property
)
1848 arg
.id
= r
.ReadId ();
1849 else if (Version
.AtLeast (2, 12))
1850 arg
.id
= r
.ReadId ();
1852 arg
.value = r
.ReadValue ();
1853 info
.named_args
[j
] = arg
;
1860 static ElementType
TypeCodeToElementType (TypeCode c
, Type t
) {
1862 case TypeCode
.Boolean
:
1863 return ElementType
.Boolean
;
1865 return ElementType
.Char
;
1866 case TypeCode
.SByte
:
1867 return ElementType
.I1
;
1869 return ElementType
.U1
;
1870 case TypeCode
.Int16
:
1871 return ElementType
.I2
;
1872 case TypeCode
.UInt16
:
1873 return ElementType
.U2
;
1874 case TypeCode
.Int32
:
1875 return ElementType
.I4
;
1876 case TypeCode
.UInt32
:
1877 return ElementType
.U4
;
1878 case TypeCode
.Int64
:
1879 return ElementType
.I8
;
1880 case TypeCode
.UInt64
:
1881 return ElementType
.U8
;
1882 case TypeCode
.Single
:
1883 return ElementType
.R4
;
1884 case TypeCode
.Double
:
1885 return ElementType
.R8
;
1886 case TypeCode
.Object
:
1887 return TypeCodeToElementType(Type
.GetTypeCode (t
.GetElementType()), t
.GetElementType());
1889 throw new NotImplementedException ();
1894 * Implementation of debugger commands
1897 internal VersionInfo
VM_GetVersion () {
1898 var res
= SendReceive (CommandSet
.VM
, (int)CmdVM
.VERSION
, null);
1899 VersionInfo info
= new VersionInfo ();
1900 info
.VMVersion
= res
.ReadString ();
1901 info
.MajorVersion
= res
.ReadInt ();
1902 info
.MinorVersion
= res
.ReadInt ();
1906 internal void VM_SetProtocolVersion (int major
, int minor
) {
1907 SendReceive (CommandSet
.VM
, (int)CmdVM
.SET_PROTOCOL_VERSION
, new PacketWriter ().WriteInt (major
).WriteInt (minor
));
1910 internal void VM_GetThreads (Action
<long[]> resultCallaback
) {
1911 Send (CommandSet
.VM
, (int)CmdVM
.ALL_THREADS
, null, (res
) => {
1912 int len
= res
.ReadInt ();
1913 long[] arr
= new long [len
];
1914 for (int i
= 0; i
< len
; ++i
)
1915 arr
[i
] = res
.ReadId ();
1916 resultCallaback(arr
);
1920 internal void VM_Suspend () {
1921 SendReceive (CommandSet
.VM
, (int)CmdVM
.SUSPEND
);
1924 internal void VM_Resume () {
1925 SendReceive (CommandSet
.VM
, (int)CmdVM
.RESUME
);
1928 internal void VM_Exit (int exitCode
) {
1929 SendReceive (CommandSet
.VM
, (int)CmdVM
.EXIT
, new PacketWriter ().WriteInt (exitCode
));
1932 internal void VM_Dispose () {
1933 SendReceive (CommandSet
.VM
, (int)CmdVM
.DISPOSE
);
1936 internal ValueImpl
VM_InvokeMethod (long thread
, long method
, ValueImpl this_arg
, ValueImpl
[] arguments
, InvokeFlags flags
, out ValueImpl exc
) {
1938 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
));
1939 if (r
.ReadByte () == 0) {
1940 exc
= r
.ReadValue ();
1943 return r
.ReadValue ();
1947 internal delegate void InvokeMethodCallback (ValueImpl v
, ValueImpl exc
, ValueImpl out_this
, ValueImpl
[] out_args
, ErrorCode error
, object state
);
1949 void read_invoke_res (PacketReader r
, out ValueImpl v
, out ValueImpl exc
, out ValueImpl out_this
, out ValueImpl
[] out_args
) {
1950 int resflags
= r
.ReadByte ();
1955 if (resflags
== 0) {
1956 exc
= r
.ReadValue ();
1959 if ((resflags
& 2) != 0)
1960 out_this
= r
.ReadValue ();
1961 if ((resflags
& 4) != 0) {
1962 int nargs
= r
.ReadInt ();
1963 out_args
= new ValueImpl
[nargs
];
1964 for (int i
= 0; i
< nargs
; ++i
)
1965 out_args
[i
] = r
.ReadValue ();
1970 internal int VM_BeginInvokeMethod (long thread
, long method
, ValueImpl this_arg
, ValueImpl
[] arguments
, InvokeFlags flags
, InvokeMethodCallback callback
, object state
) {
1971 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
) {
1972 ValueImpl v
, exc
, out_this
= null;
1973 ValueImpl
[] out_args
= null;
1975 if (r
.ErrorCode
!= 0) {
1976 callback (null, null, null, null, (ErrorCode
)r
.ErrorCode
, state
);
1978 read_invoke_res (r
, out v
, out exc
, out out_this
, out out_args
);
1979 callback (v
, exc
, out_this
, out_args
, 0, state
);
1984 internal int VM_BeginInvokeMethods (long thread
, long[] methods
, ValueImpl this_arg
, List
<ValueImpl
[]> arguments
, InvokeFlags flags
, InvokeMethodCallback callback
, object state
) {
1985 // FIXME: Merge this with INVOKE_METHOD
1986 var w
= new PacketWriter ();
1988 w
.WriteInt ((int)flags
);
1989 w
.WriteInt (methods
.Length
);
1990 for (int i
= 0; i
< methods
.Length
; ++i
) {
1991 w
.WriteId (methods
[i
]);
1992 w
.WriteValue (this_arg
);
1993 w
.WriteInt (arguments
[i
].Length
);
1994 w
.WriteValues (arguments
[i
]);
1996 return Send (CommandSet
.VM
, (int)CmdVM
.INVOKE_METHODS
, w
, delegate (PacketReader r
) {
1997 ValueImpl v
, exc
, out_this
= null;
1998 ValueImpl
[] out_args
= null;
2000 if (r
.ErrorCode
!= 0) {
2001 callback (null, null, null, null, (ErrorCode
)r
.ErrorCode
, state
);
2003 read_invoke_res (r
, out v
, out exc
, out out_this
, out out_args
);
2004 callback (v
, exc
, out_this
, out_args
, 0, state
);
2009 internal void VM_AbortInvoke (long thread
, int id
)
2011 SendReceive (CommandSet
.VM
, (int)CmdVM
.ABORT_INVOKE
, new PacketWriter ().WriteId (thread
).WriteInt (id
));
2014 internal void SetSocketTimeouts (int send_timeout
, int receive_timeout
, int keepalive_interval
)
2016 TransportSetTimeouts (send_timeout
, receive_timeout
);
2017 SendReceive (CommandSet
.VM
, (int)CmdVM
.SET_KEEPALIVE
, new PacketWriter ().WriteId (keepalive_interval
));
2020 internal long[] VM_GetTypesForSourceFile (string fname
, bool ignoreCase
) {
2021 var res
= SendReceive (CommandSet
.VM
, (int)CmdVM
.GET_TYPES_FOR_SOURCE_FILE
, new PacketWriter ().WriteString (fname
).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 long[] VM_GetTypes (string name
, bool ignoreCase
) {
2030 var res
= SendReceive (CommandSet
.VM
, (int)CmdVM
.GET_TYPES
, new PacketWriter ().WriteString (name
).WriteBool (ignoreCase
));
2031 int count
= res
.ReadInt ();
2032 long[] types
= new long [count
];
2033 for (int i
= 0; i
< count
; ++i
)
2034 types
[i
] = res
.ReadId ();
2038 internal void VM_StartBuffering () {
2039 Send (CommandSet
.VM
, (int)CmdVM
.START_BUFFERING
);
2042 internal void VM_StopBuffering () {
2043 Send (CommandSet
.VM
, (int)CmdVM
.STOP_BUFFERING
);
2050 internal long RootDomain
{
2052 return SendReceive (CommandSet
.APPDOMAIN
, (int)CmdAppDomain
.GET_ROOT_DOMAIN
, null).ReadId ();
2056 internal string Domain_GetName (long id
) {
2057 return SendReceive (CommandSet
.APPDOMAIN
, (int)CmdAppDomain
.GET_FRIENDLY_NAME
, new PacketWriter ().WriteId (id
)).ReadString ();
2060 internal long[] Domain_GetAssemblies (long id
) {
2061 var res
= SendReceive (CommandSet
.APPDOMAIN
, (int)CmdAppDomain
.GET_ASSEMBLIES
, new PacketWriter ().WriteId (id
));
2062 int count
= res
.ReadInt ();
2063 long[] assemblies
= new long [count
];
2064 for (int i
= 0; i
< count
; ++i
)
2065 assemblies
[i
] = res
.ReadId ();
2069 internal long Domain_GetEntryAssembly (long id
) {
2070 return SendReceive (CommandSet
.APPDOMAIN
, (int)CmdAppDomain
.GET_ENTRY_ASSEMBLY
, new PacketWriter ().WriteId (id
)).ReadId ();
2073 internal long Domain_GetCorlib (long id
) {
2074 return SendReceive (CommandSet
.APPDOMAIN
, (int)CmdAppDomain
.GET_CORLIB
, new PacketWriter ().WriteId (id
)).ReadId ();
2077 internal long Domain_CreateString (long id
, string s
) {
2078 return SendReceive (CommandSet
.APPDOMAIN
, (int)CmdAppDomain
.CREATE_STRING
, new PacketWriter ().WriteId (id
).WriteString (s
)).ReadId ();
2081 internal long Domain_CreateByteArray (long id
, byte [] bytes
) {
2082 var w
= new PacketWriter ().WriteId (id
);
2083 w
.WriteBytes (bytes
);
2084 return SendReceive (CommandSet
.APPDOMAIN
, (int)CmdAppDomain
.CREATE_BYTE_ARRAY
, w
).ReadId ();
2087 internal long Domain_CreateBoxedValue (long id
, long type_id
, ValueImpl v
) {
2088 return SendReceive (CommandSet
.APPDOMAIN
, (int)CmdAppDomain
.CREATE_BOXED_VALUE
, new PacketWriter ().WriteId (id
).WriteId (type_id
).WriteValue (v
)).ReadId ();
2095 internal string Method_GetName (long id
) {
2096 return SendReceive (CommandSet
.METHOD
, (int)CmdMethod
.GET_NAME
, new PacketWriter ().WriteId (id
)).ReadString ();
2099 internal long Method_GetDeclaringType (long id
) {
2100 return SendReceive (CommandSet
.METHOD
, (int)CmdMethod
.GET_DECLARING_TYPE
, new PacketWriter ().WriteId (id
)).ReadId ();
2103 internal DebugInfo
Method_GetDebugInfo (long id
) {
2104 var res
= SendReceive (CommandSet
.METHOD
, (int)CmdMethod
.GET_DEBUG_INFO
, new PacketWriter ().WriteId (id
));
2106 DebugInfo info
= new DebugInfo ();
2107 info
.max_il_offset
= res
.ReadInt ();
2109 SourceInfo
[] sources
= null;
2110 if (Version
.AtLeast (2, 13)) {
2111 int n
= res
.ReadInt ();
2112 sources
= new SourceInfo
[n
];
2113 for (int i
= 0; i
< n
; ++i
) {
2114 sources
[i
].source_file
= res
.ReadString ();
2115 if (Version
.AtLeast (2, 14)) {
2116 sources
[i
].hash
= new byte [16];
2117 for (int j
= 0; j
< 16; ++j
)
2118 sources
[i
].hash
[j
] = (byte)res
.ReadByte ();
2122 sources
= new SourceInfo
[1];
2123 sources
[0].source_file
= res
.ReadString ();
2126 int n_il_offsets
= res
.ReadInt ();
2127 info
.il_offsets
= new int [n_il_offsets
];
2128 info
.line_numbers
= new int [n_il_offsets
];
2129 info
.source_files
= new SourceInfo
[n_il_offsets
];
2130 info
.column_numbers
= new int [n_il_offsets
];
2131 info
.end_line_numbers
= new int [n_il_offsets
];
2132 info
.end_column_numbers
= new int [n_il_offsets
];
2133 for (int i
= 0; i
< n_il_offsets
; ++i
) {
2134 info
.il_offsets
[i
] = res
.ReadInt ();
2135 info
.line_numbers
[i
] = res
.ReadInt ();
2136 if (Version
.AtLeast (2, 12)) {
2137 int idx
= res
.ReadInt ();
2138 info
.source_files
[i
] = idx
>= 0 ? sources
[idx
] : default (SourceInfo
);
2140 info
.source_files
[i
] = sources
[0];
2142 if (Version
.AtLeast (2, 19))
2143 info
.column_numbers
[i
] = res
.ReadInt ();
2145 info
.column_numbers
[i
] = 0;
2146 if (Version
.AtLeast (2, 32)) {
2147 info
.end_line_numbers
[i
] = res
.ReadInt ();
2148 info
.end_column_numbers
[i
] = res
.ReadInt ();
2150 info
.end_column_numbers
[i
] = -1;
2151 info
.end_column_numbers
[i
] = -1;
2158 internal ParamInfo
Method_GetParamInfo (long id
) {
2159 var res
= SendReceive (CommandSet
.METHOD
, (int)CmdMethod
.GET_PARAM_INFO
, new PacketWriter ().WriteId (id
));
2161 ParamInfo info
= new ParamInfo ();
2162 info
.call_conv
= res
.ReadInt ();
2163 info
.param_count
= res
.ReadInt ();
2164 info
.generic_param_count
= res
.ReadInt ();
2165 info
.ret_type
= res
.ReadId ();
2166 info
.param_types
= new long [info
.param_count
];
2167 for (int i
= 0; i
< info
.param_count
; ++i
)
2168 info
.param_types
[i
] = res
.ReadId ();
2169 info
.param_names
= new string [info
.param_count
];
2170 for (int i
= 0; i
< info
.param_count
; ++i
)
2171 info
.param_names
[i
] = res
.ReadString ();
2176 internal LocalsInfo
Method_GetLocalsInfo (long id
) {
2177 var res
= SendReceive (CommandSet
.METHOD
, (int)CmdMethod
.GET_LOCALS_INFO
, new PacketWriter ().WriteId (id
));
2179 LocalsInfo info
= new LocalsInfo ();
2181 if (Version
.AtLeast (2, 43)) {
2182 int nscopes
= res
.ReadInt ();
2183 info
.scopes_start
= new int [nscopes
];
2184 info
.scopes_end
= new int [nscopes
];
2186 for (int i
= 0; i
< nscopes
; ++i
) {
2187 info
.scopes_start
[i
] = last_start
+ res
.ReadInt ();
2188 info
.scopes_end
[i
] = info
.scopes_start
[i
] + res
.ReadInt ();
2189 last_start
= info
.scopes_start
[i
];
2193 int nlocals
= res
.ReadInt ();
2194 info
.types
= new long [nlocals
];
2195 for (int i
= 0; i
< nlocals
; ++i
)
2196 info
.types
[i
] = res
.ReadId ();
2197 info
.names
= new string [nlocals
];
2198 for (int i
= 0; i
< nlocals
; ++i
)
2199 info
.names
[i
] = res
.ReadString ();
2200 info
.live_range_start
= new int [nlocals
];
2201 info
.live_range_end
= new int [nlocals
];
2202 for (int i
= 0; i
< nlocals
; ++i
) {
2203 info
.live_range_start
[i
] = res
.ReadInt ();
2204 info
.live_range_end
[i
] = res
.ReadInt ();
2210 internal MethodInfo
Method_GetInfo (long id
) {
2211 var res
= SendReceive (CommandSet
.METHOD
, (int)CmdMethod
.GET_INFO
, new PacketWriter ().WriteId (id
));
2213 MethodInfo info
= new MethodInfo ();
2214 info
.attributes
= res
.ReadInt ();
2215 info
.iattributes
= res
.ReadInt ();
2216 info
.token
= res
.ReadInt ();
2217 if (Version
.AtLeast (2, 12)) {
2218 int attrs
= res
.ReadByte ();
2219 if ((attrs
& (1 << 0)) != 0)
2221 if ((attrs
& (1 << 1)) != 0)
2222 info
.is_generic_method
= true;
2223 info
.gmd
= res
.ReadId ();
2224 if (Version
.AtLeast (2, 15)) {
2225 if (info
.is_generic_method
) {
2226 int n
= res
.ReadInt ();
2227 info
.type_args
= res
.ReadIds (n
);
2234 internal MethodBodyInfo
Method_GetBody (long id
) {
2235 var res
= SendReceive (CommandSet
.METHOD
, (int)CmdMethod
.GET_BODY
, new PacketWriter ().WriteId (id
));
2237 MethodBodyInfo info
= new MethodBodyInfo ();
2238 info
.il
= new byte [res
.ReadInt ()];
2239 for (int i
= 0; i
< info
.il
.Length
; ++i
)
2240 info
.il
[i
] = (byte)res
.ReadByte ();
2242 if (Version
.AtLeast (2, 18)) {
2243 info
.clauses
= new ExceptionClauseInfo
[res
.ReadInt ()];
2245 for (int i
= 0; i
< info
.clauses
.Length
; ++i
) {
2246 var clause
= new ExceptionClauseInfo
{
2247 flags
= (ExceptionClauseFlags
) res
.ReadInt (),
2248 try_offset
= res
.ReadInt (),
2249 try_length
= res
.ReadInt (),
2250 handler_offset
= res
.ReadInt (),
2251 handler_length
= res
.ReadInt (),
2254 if (clause
.flags
== ExceptionClauseFlags
.None
)
2255 clause
.catch_type_id
= res
.ReadId ();
2256 else if (clause
.flags
== ExceptionClauseFlags
.Filter
)
2257 clause
.filter_offset
= res
.ReadInt ();
2259 info
.clauses
[i
] = clause
;
2262 info
.clauses
= new ExceptionClauseInfo
[0];
2267 internal ResolvedToken
Method_ResolveToken (long id
, int token
) {
2268 var res
= SendReceive (CommandSet
.METHOD
, (int)CmdMethod
.RESOLVE_TOKEN
, new PacketWriter ().WriteId (id
).WriteInt (token
));
2270 TokenType type
= (TokenType
)res
.ReadByte ();
2272 case TokenType
.STRING
:
2273 return new ResolvedToken () { Type = type, Str = res.ReadString () }
;
2274 case TokenType
.TYPE
:
2275 case TokenType
.METHOD
:
2276 case TokenType
.FIELD
:
2277 return new ResolvedToken () { Type = type, Id = res.ReadId () }
;
2278 case TokenType
.UNKNOWN
:
2279 return new ResolvedToken () { Type = type }
;
2281 throw new NotImplementedException ();
2285 internal CattrInfo
[] Method_GetCustomAttributes (long id
, long attr_type_id
, bool inherit
) {
2286 PacketReader r
= SendReceive (CommandSet
.METHOD
, (int)CmdMethod
.GET_CATTRS
, new PacketWriter ().WriteId (id
).WriteId (attr_type_id
));
2287 return ReadCattrs (r
);
2290 internal long Method_MakeGenericMethod (long id
, long[] args
) {
2291 PacketReader r
= SendReceive (CommandSet
.METHOD
, (int)CmdMethod
.MAKE_GENERIC_METHOD
, new PacketWriter ().WriteId (id
).WriteInt (args
.Length
).WriteIds (args
));
2299 internal string Thread_GetName (long id
) {
2300 return SendReceive (CommandSet
.THREAD
, (int)CmdThread
.GET_NAME
, new PacketWriter ().WriteId (id
)).ReadString ();
2303 internal long Thread_GetElapsedTime (long id
) {
2304 return SendReceive (CommandSet
.THREAD
, (int)CmdThread
.GET_ELAPSED_TIME
, new PacketWriter ().WriteId (id
)).ReadLong ();
2307 internal void Thread_GetFrameInfo (long id
, int start_frame
, int length
, Action
<FrameInfo
[]> resultCallaback
) {
2308 Send (CommandSet
.THREAD
, (int)CmdThread
.GET_FRAME_INFO
, new PacketWriter ().WriteId (id
).WriteInt (start_frame
).WriteInt (length
), (res
) => {
2309 int count
= res
.ReadInt ();
2310 var frames
= new FrameInfo
[count
];
2311 for (int i
= 0; i
< count
; ++i
) {
2312 var f
= new FrameInfo ();
2313 f
.id
= res
.ReadInt ();
2314 f
.method
= res
.ReadId ();
2315 f
.il_offset
= res
.ReadInt ();
2316 f
.flags
= (StackFrameFlags
)res
.ReadByte ();
2319 resultCallaback (frames
);
2323 internal int Thread_GetState (long id
) {
2324 return SendReceive (CommandSet
.THREAD
, (int)CmdThread
.GET_STATE
, new PacketWriter ().WriteId (id
)).ReadInt ();
2327 internal ThreadInfo
Thread_GetInfo (long id
) {
2328 PacketReader r
= SendReceive (CommandSet
.THREAD
, (int)CmdThread
.GET_INFO
, new PacketWriter ().WriteId (id
));
2330 ThreadInfo res
= new ThreadInfo () { is_thread_pool = r.ReadByte () > 0 ? true : false }
;
2335 internal long Thread_GetId (long id
) {
2336 return SendReceive (CommandSet
.THREAD
, (int)CmdThread
.GET_ID
, new PacketWriter ().WriteId (id
)).ReadLong ();
2339 internal long Thread_GetTID (long id
) {
2340 return SendReceive (CommandSet
.THREAD
, (int)CmdThread
.GET_TID
, new PacketWriter ().WriteId (id
)).ReadLong ();
2343 internal void Thread_SetIP (long id
, long method_id
, long il_offset
) {
2344 SendReceive (CommandSet
.THREAD
, (int)CmdThread
.SET_IP
, new PacketWriter ().WriteId (id
).WriteId (method_id
).WriteLong (il_offset
));
2351 internal ModuleInfo
Module_GetInfo (long id
) {
2352 PacketReader r
= SendReceive (CommandSet
.MODULE
, (int)CmdModule
.GET_INFO
, new PacketWriter ().WriteId (id
));
2353 ModuleInfo info
= new ModuleInfo { Name = r.ReadString (), ScopeName = r.ReadString (), FQName = r.ReadString (), Guid = r.ReadString (), Assembly = r.ReadId () }
;
2354 if (Version
.AtLeast (2, 48))
2355 info
.SourceLink
= r
.ReadString ();
2363 internal string Assembly_GetLocation (long id
) {
2364 return SendReceive (CommandSet
.ASSEMBLY
, (int)CmdAssembly
.GET_LOCATION
, new PacketWriter ().WriteId (id
)).ReadString ();
2367 internal long Assembly_GetEntryPoint (long id
) {
2368 return SendReceive (CommandSet
.ASSEMBLY
, (int)CmdAssembly
.GET_ENTRY_POINT
, new PacketWriter ().WriteId (id
)).ReadId ();
2371 internal long Assembly_GetManifestModule (long id
) {
2372 return SendReceive (CommandSet
.ASSEMBLY
, (int)CmdAssembly
.GET_MANIFEST_MODULE
, new PacketWriter ().WriteId (id
)).ReadId ();
2375 internal long Assembly_GetObject (long id
) {
2376 return SendReceive (CommandSet
.ASSEMBLY
, (int)CmdAssembly
.GET_OBJECT
, new PacketWriter ().WriteId (id
)).ReadId ();
2379 internal long Assembly_GetType (long id
, string name
, bool ignoreCase
) {
2380 return SendReceive (CommandSet
.ASSEMBLY
, (int)CmdAssembly
.GET_TYPE
, new PacketWriter ().WriteId (id
).WriteString (name
).WriteBool (ignoreCase
)).ReadId ();
2383 internal string Assembly_GetName (long id
) {
2384 return SendReceive (CommandSet
.ASSEMBLY
, (int)CmdAssembly
.GET_NAME
, new PacketWriter ().WriteId (id
)).ReadString ();
2387 internal long Assembly_GetIdDomain (long id
) {
2388 return SendReceive (CommandSet
.ASSEMBLY
, (int)CmdAssembly
.GET_DOMAIN
, new PacketWriter ().WriteId (id
)).ReadId ();
2391 internal byte[] Assembly_GetMetadataBlob (long id
) {
2392 return SendReceive (CommandSet
.ASSEMBLY
, (int)CmdAssembly
.GET_METADATA_BLOB
, new PacketWriter ().WriteId (id
)).ReadByteArray ();
2395 internal bool Assembly_IsDynamic (long id
) {
2396 return SendReceive (CommandSet
.ASSEMBLY
, (int) CmdAssembly
.GET_IS_DYNAMIC
, new PacketWriter ().WriteId (id
)).ReadBool ();
2399 internal byte[] Assembly_GetPdbBlob (long id
) {
2400 return SendReceive (CommandSet
.ASSEMBLY
, (int)CmdAssembly
.GET_PDB_BLOB
, new PacketWriter ().WriteId (id
)).ReadByteArray ();
2403 internal long Assembly_GetType (long id
, uint token
) {
2404 return SendReceive (CommandSet
.ASSEMBLY
, (int)CmdAssembly
.GET_TYPE_FROM_TOKEN
, new PacketWriter ().WriteId (id
).WriteInt ((int)token
)).ReadId ();
2407 internal long Assembly_GetMethod (long id
, uint token
) {
2408 return SendReceive (CommandSet
.ASSEMBLY
, (int)CmdAssembly
.GET_METHOD_FROM_TOKEN
, new PacketWriter ().WriteId (id
).WriteInt ((int)token
)).ReadId ();
2411 internal bool Assembly_HasDebugInfo (long id
) {
2412 return SendReceive (CommandSet
.ASSEMBLY
, (int)CmdAssembly
.HAS_DEBUG_INFO
, new PacketWriter ().WriteId (id
)).ReadBool ();
2419 internal TypeInfo
Type_GetInfo (long id
) {
2420 PacketReader r
= SendReceive (CommandSet
.TYPE
, (int)CmdType
.GET_INFO
, new PacketWriter ().WriteId (id
));
2421 TypeInfo res
= new TypeInfo ();
2423 res
.ns
= r
.ReadString ();
2424 res
.name
= r
.ReadString ();
2425 res
.full_name
= r
.ReadString ();
2426 res
.assembly
= r
.ReadId ();
2427 res
.module
= r
.ReadId ();
2428 res
.base_type
= r
.ReadId ();
2429 res
.element_type
= r
.ReadId ();
2430 res
.token
= r
.ReadInt ();
2431 res
.rank
= r
.ReadByte ();
2432 res
.attributes
= r
.ReadInt ();
2433 int b
= r
.ReadByte ();
2434 res
.is_byref
= (b
& 1) != 0;
2435 res
.is_pointer
= (b
& 2) != 0;
2436 res
.is_primitive
= (b
& 4) != 0;
2437 res
.is_valuetype
= (b
& 8) != 0;
2438 res
.is_enum
= (b
& 16) != 0;
2439 res
.is_gtd
= (b
& 32) != 0;
2440 res
.is_generic_type
= (b
& 64) != 0;
2442 int nested_len
= r
.ReadInt ();
2443 res
.nested
= new long [nested_len
];
2444 for (int i
= 0; i
< nested_len
; ++i
)
2445 res
.nested
[i
] = r
.ReadId ();
2447 if (Version
.AtLeast (2, 12))
2448 res
.gtd
= r
.ReadId ();
2449 if (Version
.AtLeast (2, 15) && res
.is_generic_type
) {
2450 int n
= r
.ReadInt ();
2451 res
.type_args
= r
.ReadIds (n
);
2457 internal long[] Type_GetMethods (long id
) {
2458 PacketReader r
= SendReceive (CommandSet
.TYPE
, (int)CmdType
.GET_METHODS
, new PacketWriter ().WriteId (id
));
2460 int n
= r
.ReadInt ();
2461 long[] res
= new long [n
];
2462 for (int i
= 0; i
< n
; ++i
)
2463 res
[i
] = r
.ReadId ();
2467 internal long[] Type_GetFields (long id
, out string[] names
, out long[] types
, out int[] attrs
) {
2468 PacketReader r
= SendReceive (CommandSet
.TYPE
, (int)CmdType
.GET_FIELDS
, new PacketWriter ().WriteId (id
));
2470 int n
= r
.ReadInt ();
2471 long[] res
= new long [n
];
2472 names
= new string [n
];
2473 types
= new long [n
];
2474 attrs
= new int [n
];
2475 for (int i
= 0; i
< n
; ++i
) {
2476 res
[i
] = r
.ReadId ();
2477 names
[i
] = r
.ReadString ();
2478 types
[i
] = r
.ReadId ();
2479 attrs
[i
] = r
.ReadInt ();
2484 internal PropInfo
[] Type_GetProperties (long id
) {
2485 PacketReader r
= SendReceive (CommandSet
.TYPE
, (int)CmdType
.GET_PROPERTIES
, new PacketWriter ().WriteId (id
));
2487 int n
= r
.ReadInt ();
2488 PropInfo
[] res
= new PropInfo
[n
];
2489 for (int i
= 0; i
< n
; ++i
) {
2490 res
[i
] = new PropInfo ();
2491 res
[i
].id
= r
.ReadId ();
2492 res
[i
].name
= r
.ReadString ();
2493 res
[i
].get_method
= r
.ReadId ();
2494 res
[i
].set_method
= r
.ReadId ();
2495 res
[i
].attrs
= r
.ReadInt ();
2501 internal long Type_GetObject (long id
) {
2502 return SendReceive (CommandSet
.TYPE
, (int)CmdType
.GET_OBJECT
, new PacketWriter ().WriteId (id
)).ReadId ();
2505 internal ValueImpl
[] Type_GetValues (long id
, long[] fields
, long thread_id
) {
2506 int len
= fields
.Length
;
2508 if (thread_id
!= 0 && Version
.AtLeast(2, 3))
2509 r
= SendReceive (CommandSet
.TYPE
, (int)CmdType
.GET_VALUES_2
, new PacketWriter ().WriteId (id
).WriteId (thread_id
).WriteInt (len
).WriteIds (fields
));
2511 r
= SendReceive (CommandSet
.TYPE
, (int)CmdType
.GET_VALUES
, new PacketWriter ().WriteId (id
).WriteInt (len
).WriteIds (fields
));
2513 ValueImpl
[] res
= new ValueImpl
[len
];
2514 for (int i
= 0; i
< len
; ++i
)
2515 res
[i
] = r
.ReadValue ();
2519 internal void Type_SetValues (long id
, long[] fields
, ValueImpl
[] values
) {
2520 SendReceive (CommandSet
.TYPE
, (int)CmdType
.SET_VALUES
, new PacketWriter ().WriteId (id
).WriteInt (fields
.Length
).WriteIds (fields
).WriteValues (values
));
2523 internal string[] Type_GetSourceFiles (long id
, bool return_full_paths
) {
2524 var r
= SendReceive (CommandSet
.TYPE
, return_full_paths
? (int)CmdType
.GET_SOURCE_FILES_2
: (int)CmdType
.GET_SOURCE_FILES
, new PacketWriter ().WriteId (id
));
2525 int len
= r
.ReadInt ();
2526 string[] res
= new string [len
];
2527 for (int i
= 0; i
< len
; ++i
)
2528 res
[i
] = r
.ReadString ();
2532 internal bool Type_IsAssignableFrom (long id
, long c_id
) {
2533 return SendReceive (CommandSet
.TYPE
, (int)CmdType
.IS_ASSIGNABLE_FROM
, new PacketWriter ().WriteId (id
).WriteId (c_id
)).ReadByte () > 0;
2536 internal CattrInfo
[] Type_GetCustomAttributes (long id
, long attr_type_id
, bool inherit
) {
2537 PacketReader r
= SendReceive (CommandSet
.TYPE
, (int)CmdType
.GET_CATTRS
, new PacketWriter ().WriteId (id
).WriteId (attr_type_id
));
2538 return ReadCattrs (r
);
2541 internal CattrInfo
[] Type_GetFieldCustomAttributes (long id
, long field_id
, long attr_type_id
, bool inherit
) {
2542 PacketReader r
= SendReceive (CommandSet
.TYPE
, (int)CmdType
.GET_FIELD_CATTRS
, new PacketWriter ().WriteId (id
).WriteId (field_id
).WriteId (attr_type_id
));
2543 return ReadCattrs (r
);
2546 internal CattrInfo
[] Type_GetPropertyCustomAttributes (long id
, long field_id
, long attr_type_id
, bool inherit
) {
2547 PacketReader r
= SendReceive (CommandSet
.TYPE
, (int)CmdType
.GET_PROPERTY_CATTRS
, new PacketWriter ().WriteId (id
).WriteId (field_id
).WriteId (attr_type_id
));
2548 return ReadCattrs (r
);
2551 public long[] Type_GetMethodsByNameFlags (long id
, string name
, int flags
, bool ignoreCase
) {
2552 flags
|= ignoreCase
? (int)BindingFlagsExtensions
.BINDING_FLAGS_IGNORE_CASE
: 0;
2553 int listType
= ignoreCase
? (int)MemberListTypeExtensions
.CaseInsensitive
: (int)MemberListTypeExtensions
.CaseSensitive
;
2554 var w
= new PacketWriter ().WriteId (id
).WriteString (name
).WriteInt (flags
);
2555 if (Version
.AtLeast (2, 48))
2556 w
.WriteInt (listType
);
2557 PacketReader r
= SendReceive (CommandSet
.TYPE
, (int)CmdType
.CMD_TYPE_GET_METHODS_BY_NAME_FLAGS
, w
);
2558 int len
= r
.ReadInt ();
2559 long[] res
= new long [len
];
2560 for (int i
= 0; i
< len
; ++i
)
2561 res
[i
] = r
.ReadId ();
2565 internal long[] Type_GetInterfaces (long id
) {
2566 PacketReader r
= SendReceive (CommandSet
.TYPE
, (int)CmdType
.GET_INTERFACES
, new PacketWriter ().WriteId (id
));
2567 int len
= r
.ReadInt ();
2568 return r
.ReadIds (len
);
2571 internal IfaceMapInfo
[] Type_GetInterfaceMap (long id
, long[] ids
) {
2572 PacketReader r
= SendReceive (CommandSet
.TYPE
, (int)CmdType
.GET_INTERFACE_MAP
, new PacketWriter ().WriteId (id
).WriteInt (ids
.Length
).WriteIds (ids
));
2573 var res
= new IfaceMapInfo
[ids
.Length
];
2574 for (int i
= 0; i
< ids
.Length
; ++i
) {
2575 int n
= r
.ReadInt ();
2577 res
[i
].iface_id
= ids
[i
];
2578 res
[i
].iface_methods
= r
.ReadIds (n
);
2579 res
[i
].target_methods
= r
.ReadIds (n
);
2585 internal bool Type_IsInitialized (long id
) {
2586 PacketReader r
= SendReceive (CommandSet
.TYPE
, (int)CmdType
.IS_INITIALIZED
, new PacketWriter ().WriteId (id
));
2587 return r
.ReadInt () == 1;
2590 internal long Type_CreateInstance (long id
) {
2591 PacketReader r
= SendReceive (CommandSet
.TYPE
, (int)CmdType
.CREATE_INSTANCE
, new PacketWriter ().WriteId (id
));
2595 internal int Type_GetValueSize (long id
) {
2596 PacketReader r
= SendReceive (CommandSet
.TYPE
, (int)CmdType
.GET_VALUE_SIZE
, new PacketWriter ().WriteId (id
));
2597 return r
.ReadInt ();
2604 internal FieldMirrorInfo
Field_GetInfo (long id
) {
2605 PacketReader r
= SendReceive (CommandSet
.FIELD
, (int)CmdField
.GET_INFO
, new PacketWriter ().WriteId (id
));
2606 FieldMirrorInfo info
= new FieldMirrorInfo { Name = r.ReadString (), Parent = r.ReadId (), TypeId = r.ReadId (), Attrs = r.ReadInt () }
;
2614 internal int EnableEvent (EventType etype
, SuspendPolicy suspend_policy
, List
<Modifier
> mods
) {
2615 var w
= new PacketWriter ().WriteByte ((byte)etype
).WriteByte ((byte)suspend_policy
);
2617 if (mods
.Count
> 255)
2618 throw new NotImplementedException ();
2619 w
.WriteByte ((byte)mods
.Count
);
2620 foreach (Modifier mod
in mods
) {
2621 if (mod
is CountModifier
) {
2622 w
.WriteByte ((byte)ModifierKind
.COUNT
);
2623 w
.WriteInt ((mod
as CountModifier
).Count
);
2624 } else if (mod
is LocationModifier
) {
2625 w
.WriteByte ((byte)ModifierKind
.LOCATION_ONLY
);
2626 w
.WriteId ((mod
as LocationModifier
).Method
);
2627 w
.WriteLong ((mod
as LocationModifier
).Location
);
2628 } else if (mod
is StepModifier
) {
2629 w
.WriteByte ((byte)ModifierKind
.STEP
);
2630 w
.WriteId ((mod
as StepModifier
).Thread
);
2631 w
.WriteInt ((mod
as StepModifier
).Size
);
2632 w
.WriteInt ((mod
as StepModifier
).Depth
);
2633 if (Version
.AtLeast (2, 16))
2634 w
.WriteInt ((mod
as StepModifier
).Filter
);
2635 } else if (mod
is ThreadModifier
) {
2636 w
.WriteByte ((byte)ModifierKind
.THREAD_ONLY
);
2637 w
.WriteId ((mod
as ThreadModifier
).Thread
);
2638 } else if (mod
is ExceptionModifier
) {
2639 var em
= mod
as ExceptionModifier
;
2640 w
.WriteByte ((byte)ModifierKind
.EXCEPTION_ONLY
);
2641 w
.WriteId (em
.Type
);
2642 if (Version
.MajorVersion
> 2 || Version
.MinorVersion
> 0) {
2643 /* This is only supported in protocol version 2.1 */
2644 w
.WriteBool (em
.Caught
);
2645 w
.WriteBool (em
.Uncaught
);
2646 } else if (!em
.Caught
|| !em
.Uncaught
) {
2647 throw new NotSupportedException ("This request is not supported by the protocol version implemented by the debuggee.");
2649 if (Version
.MajorVersion
> 2 || Version
.MinorVersion
> 24) {
2650 w
.WriteBool (em
.Subclasses
);
2651 } else if (!em
.Subclasses
) {
2652 throw new NotSupportedException ("This request is not supported by the protocol version implemented by the debuggee.");
2654 if (Version
.MajorVersion
> 2 || Version
.MinorVersion
>= 54) {
2655 w
.WriteBool (em
.NotFilteredFeature
);
2656 w
.WriteBool (em
.EverythingElse
);
2658 } else if (mod
is AssemblyModifier
) {
2659 w
.WriteByte ((byte)ModifierKind
.ASSEMBLY_ONLY
);
2660 var amod
= (mod
as AssemblyModifier
);
2661 w
.WriteInt (amod
.Assemblies
.Length
);
2662 foreach (var id
in amod
.Assemblies
)
2664 } else if (mod
is SourceFileModifier
) {
2665 w
.WriteByte ((byte)ModifierKind
.SOURCE_FILE_ONLY
);
2666 var smod
= (mod
as SourceFileModifier
);
2667 w
.WriteInt (smod
.SourceFiles
.Length
);
2668 foreach (var s
in smod
.SourceFiles
)
2670 } else if (mod
is TypeNameModifier
) {
2671 w
.WriteByte ((byte)ModifierKind
.TYPE_NAME_ONLY
);
2672 var tmod
= (mod
as TypeNameModifier
);
2673 w
.WriteInt (tmod
.TypeNames
.Length
);
2674 foreach (var s
in tmod
.TypeNames
)
2677 throw new NotImplementedException ();
2683 return SendReceive (CommandSet
.EVENT_REQUEST
, (int)CmdEventRequest
.SET
, w
).ReadInt ();
2686 internal void ClearEventRequest (EventType etype
, int req_id
) {
2687 SendReceive (CommandSet
.EVENT_REQUEST
, (int)CmdEventRequest
.CLEAR
, new PacketWriter ().WriteByte ((byte)etype
).WriteInt (req_id
));
2690 internal void ClearAllBreakpoints () {
2691 SendReceive (CommandSet
.EVENT_REQUEST
, (int)CmdEventRequest
.CLEAR_ALL_BREAKPOINTS
, new PacketWriter ());
2697 internal ValueImpl
StackFrame_GetThis (long thread_id
, long id
) {
2698 PacketReader r
= SendReceive (CommandSet
.STACK_FRAME
, (int)CmdStackFrame
.GET_THIS
, new PacketWriter ().WriteId (thread_id
).WriteId (id
));
2699 return r
.ReadValue ();
2702 internal ValueImpl
[] StackFrame_GetValues (long thread_id
, long id
, int[] pos
) {
2703 /* pos < 0 -> argument at pos (-pos) - 1 */
2704 /* pos >= 0 -> local at pos */
2705 int len
= pos
.Length
;
2706 PacketReader r
= SendReceive (CommandSet
.STACK_FRAME
, (int)CmdStackFrame
.GET_VALUES
, new PacketWriter ().WriteId (thread_id
).WriteId (id
).WriteInt (len
).WriteInts (pos
));
2708 ValueImpl
[] res
= new ValueImpl
[len
];
2709 for (int i
= 0; i
< len
; ++i
)
2710 res
[i
] = r
.ReadValue ();
2714 internal void StackFrame_SetValues (long thread_id
, long id
, int[] pos
, ValueImpl
[] values
) {
2715 /* pos < 0 -> argument at pos (-pos) - 1 */
2716 /* pos >= 0 -> local at pos */
2717 int len
= pos
.Length
;
2718 SendReceive (CommandSet
.STACK_FRAME
, (int)CmdStackFrame
.SET_VALUES
, new PacketWriter ().WriteId (thread_id
).WriteId (id
).WriteInt (len
).WriteInts (pos
).WriteValues (values
));
2721 internal long StackFrame_GetDomain (long thread_id
, long id
) {
2722 return SendReceive (CommandSet
.STACK_FRAME
, (int)CmdStackFrame
.GET_DOMAIN
, new PacketWriter ().WriteId (thread_id
).WriteId (id
)).ReadId ();
2725 internal void StackFrame_SetThis (long thread_id
, long id
, ValueImpl
value) {
2726 SendReceive (CommandSet
.STACK_FRAME
, (int)CmdStackFrame
.SET_THIS
, new PacketWriter ().WriteId (thread_id
).WriteId (id
).WriteValue (value));
2732 internal int[] Array_GetLength (long id
, out int rank
, out int[] lower_bounds
) {
2733 var r
= SendReceive (CommandSet
.ARRAY_REF
, (int)CmdArrayRef
.GET_LENGTH
, new PacketWriter ().WriteId (id
));
2734 rank
= r
.ReadInt ();
2735 int[] res
= new int [rank
];
2736 lower_bounds
= new int [rank
];
2737 for (int i
= 0; i
< rank
; ++i
) {
2738 res
[i
] = r
.ReadInt ();
2739 lower_bounds
[i
] = r
.ReadInt ();
2744 internal ValueImpl
[] Array_GetValues (long id
, int index
, int len
) {
2745 var r
= SendReceive (CommandSet
.ARRAY_REF
, (int)CmdArrayRef
.GET_VALUES
, new PacketWriter ().WriteId (id
).WriteInt (index
).WriteInt (len
));
2746 ValueImpl
[] res
= new ValueImpl
[len
];
2747 for (int i
= 0; i
< len
; ++i
)
2748 res
[i
] = r
.ReadValue ();
2752 internal void Array_SetValues (long id
, int index
, ValueImpl
[] values
) {
2753 SendReceive (CommandSet
.ARRAY_REF
, (int)CmdArrayRef
.SET_VALUES
, new PacketWriter ().WriteId (id
).WriteInt (index
).WriteInt (values
.Length
).WriteValues (values
));
2759 internal string String_GetValue (long id
) {
2760 var r
= SendReceive (CommandSet
.STRING_REF
, (int)CmdStringRef
.GET_VALUE
, new PacketWriter ().WriteId (id
));
2762 bool is_utf16
= false;
2763 if (Version
.AtLeast (2, 41))
2764 is_utf16
= r
.ReadByte () == 1;
2767 return r
.ReadUTF16String ();
2769 return r
.ReadString ();
2772 internal int String_GetLength (long id
) {
2773 return (int)SendReceive (CommandSet
.STRING_REF
, (int)CmdStringRef
.GET_LENGTH
, new PacketWriter ().WriteId (id
)).ReadLong ();
2776 internal char[] String_GetChars (long id
, int index
, int length
) {
2777 var r
= SendReceive (CommandSet
.STRING_REF
, (int)CmdStringRef
.GET_CHARS
, new PacketWriter ().WriteId (id
).WriteLong (index
).WriteLong (length
));
2778 var res
= new char [length
];
2779 for (int i
= 0; i
< length
; ++i
)
2780 res
[i
] = (char)r
.ReadShort ();
2788 internal ValueImpl
Pointer_GetValue (long address
, TypeMirror type
)
2790 return SendReceive (CommandSet
.POINTER
, (int)CmdPointer
.GET_VALUE
, new PacketWriter ().WriteLong (address
).WriteId (type
.Id
)).ReadValue ();
2796 internal long Object_GetType (long id
) {
2797 return SendReceive (CommandSet
.OBJECT_REF
, (int)CmdObjectRef
.GET_TYPE
, new PacketWriter ().WriteId (id
)).ReadId ();
2800 internal long Object_GetDomain (long id
) {
2801 return SendReceive (CommandSet
.OBJECT_REF
, (int)CmdObjectRef
.GET_DOMAIN
, new PacketWriter ().WriteId (id
)).ReadId ();
2804 internal ValueImpl
[] Object_GetValues (long id
, long[] fields
) {
2805 int len
= fields
.Length
;
2806 PacketReader r
= SendReceive (CommandSet
.OBJECT_REF
, (int)CmdObjectRef
.GET_VALUES
, new PacketWriter ().WriteId (id
).WriteInt (len
).WriteIds (fields
));
2808 ValueImpl
[] res
= new ValueImpl
[len
];
2809 for (int i
= 0; i
< len
; ++i
)
2810 res
[i
] = r
.ReadValue ();
2814 internal void Object_SetValues (long id
, long[] fields
, ValueImpl
[] values
) {
2815 SendReceive (CommandSet
.OBJECT_REF
, (int)CmdObjectRef
.SET_VALUES
, new PacketWriter ().WriteId (id
).WriteInt (fields
.Length
).WriteIds (fields
).WriteValues (values
));
2818 internal bool Object_IsCollected (long id
) {
2819 return SendReceive (CommandSet
.OBJECT_REF
, (int)CmdObjectRef
.IS_COLLECTED
, new PacketWriter ().WriteId (id
)).ReadInt () == 1;
2822 internal long Object_GetAddress (long id
) {
2823 return SendReceive (CommandSet
.OBJECT_REF
, (int)CmdObjectRef
.GET_ADDRESS
, new PacketWriter ().WriteId (id
)).ReadLong ();
2826 internal ObjectRefInfo
Object_GetInfo (long id
) {
2827 ObjectRefInfo res
= new ObjectRefInfo ();
2828 PacketReader r
= SendReceive (CommandSet
.OBJECT_REF
, (int)CmdObjectRef
.GET_INFO
, new PacketWriter ().WriteId (id
));
2830 res
.type_id
= r
.ReadId ();
2831 res
.domain_id
= r
.ReadId ();
2835 public void ForceDisconnect ()
2838 disconnected
= true;
2839 DisconnectedEvent
.Set ();
2844 class TcpConnection
: Connection
2848 internal TcpConnection (Socket socket
)
2850 this.socket
= socket
;
2851 //socket.SetSocketOption (SocketOptionLevel.IP, SocketOptionName.NoDelay, 1);
2854 internal EndPoint EndPoint
{
2856 return socket
.RemoteEndPoint
;
2860 protected override int TransportSend (byte[] buf
, int buf_offset
, int len
)
2862 return socket
.Send (buf
, buf_offset
, len
, SocketFlags
.None
);
2865 protected override int TransportReceive (byte[] buf
, int buf_offset
, int len
)
2867 return socket
.Receive (buf
, buf_offset
, len
, SocketFlags
.None
);
2870 protected override void TransportSetTimeouts (int send_timeout
, int receive_timeout
)
2872 socket
.SendTimeout
= send_timeout
;
2873 socket
.ReceiveTimeout
= receive_timeout
;
2876 protected override void TransportClose ()
2881 protected override void TransportShutdown ()
2883 socket
.Shutdown (SocketShutdown
.Both
);
2887 /* This is the interface exposed by the debugger towards the debugger agent */
2888 interface IEventHandler
2890 void Events (SuspendPolicy suspend_policy
, EventInfo
[] events
);
2892 void VMDisconnect (int req_id
, long thread_id
, string vm_uri
);