1 using System;
2 using System.IO;
3 using System.Net;
4 using System.Net.Sockets;
5 using System.Threading;
6 using System.Collections.Generic;
7 using System.Text;
8 using System.Diagnostics;
9 using Mono.Cecil.Metadata;
10 
11 namespace Mono.Debugger.Soft
12 {
13 	public class VersionInfo {
14 		public string VMVersion {
15 			get; set;
16 		}
17 
18 		public int MajorVersion {
19 			get; set;
20 		}
21 
22 		public int MinorVersion {
23 			get; set;
24 		}
25 
26 		/*
27 		 * Check that this version is at least major:minor
28 		 */
AtLeast(int major, int minor)29 		public bool AtLeast (int major, int minor) {
30 			if ((MajorVersion > major) || ((MajorVersion == major && MinorVersion >= minor)))
31 				return true;
32 			else
33 				return false;
34 		}
35 	}
36 
37 	struct SourceInfo {
38 		public string source_file;
39 		public byte[] hash;
40 	}
41 
42 	class DebugInfo {
43 		public int max_il_offset;
44 		public int[] il_offsets;
45 		public int[] line_numbers;
46 		public int[] column_numbers;
47 		public int[] end_line_numbers;
48 		public int[] end_column_numbers;
49 		public SourceInfo[] source_files;
50 	}
51 
52 	struct FrameInfo {
53 		public long id;
54 		public long method;
55 		public int il_offset;
56 		public StackFrameFlags flags;
57 	}
58 
59 	class TypeInfo {
60 		public string ns, name, full_name;
61 		public long assembly, module, base_type, element_type;
62 		public int token, rank, attributes;
63 		public bool is_byref, is_pointer, is_primitive, is_valuetype, is_enum;
64 		public bool is_gtd, is_generic_type;
65 		public long[] nested;
66 		public long gtd;
67 		public long[] type_args;
68 	}
69 
70 	struct IfaceMapInfo {
71 		public long iface_id;
72 		public long[] iface_methods;
73 		public long[] target_methods;
74 	}
75 
76 	class MethodInfo {
77 		public int attributes, iattributes, token;
78 		public bool is_gmd, is_generic_method;
79 		public long gmd;
80 		public long[] type_args;
81 	}
82 
83 	class MethodBodyInfo {
84 		public byte[] il;
85 		public ExceptionClauseInfo[] clauses;
86 	}
87 
88 	struct ExceptionClauseInfo {
89 		public ExceptionClauseFlags flags;
90 		public int try_offset;
91 		public int try_length;
92 		public int handler_offset;
93 		public int handler_length;
94 		public int filter_offset;
95 		public long catch_type_id;
96 	}
97 
98 	[Flags]
99 	enum ExceptionClauseFlags {
100 		None = 0x0,
101 		Filter = 0x1,
102 		Finally = 0x2,
103 		Fault = 0x4,
104 	}
105 
106 	struct ParamInfo {
107 		public int call_conv;
108 		public int param_count;
109 		public int generic_param_count;
110 		public long ret_type;
111 		public long[] param_types;
112 		public string[] param_names;
113 	}
114 
115 	struct LocalsInfo {
116 		public long[] types;
117 		public string[] names;
118 		public int[] live_range_start;
119 		public int[] live_range_end;
120 		public int[] scopes_start;
121 		public int[] scopes_end;
122 	}
123 
124 	struct PropInfo {
125 		public long id;
126 		public string name;
127 		public long get_method, set_method;
128 		public int attrs;
129 	}
130 
131 	class CattrNamedArgInfo {
132 		public bool is_property;
133 		public long id;
134 		public ValueImpl value;
135 	}
136 
137 	class CattrInfo {
138 		public long ctor_id;
139 		public ValueImpl[] ctor_args;
140 		public CattrNamedArgInfo[] named_args;
141 	}
142 
143 	class ThreadInfo {
144 		public bool is_thread_pool;
145 	}
146 
147 	struct ObjectRefInfo {
148 		public long type_id;
149 		public long domain_id;
150 	}
151 
152 	enum ValueTypeId {
153 		VALUE_TYPE_ID_NULL = 0xf0,
154 		VALUE_TYPE_ID_TYPE = 0xf1,
155 		VALUE_TYPE_ID_PARENT_VTYPE = 0xf2
156 	}
157 
158 	[Flags]
159 	enum InvokeFlags {
160 		NONE = 0,
161 		DISABLE_BREAKPOINTS = 1,
162 		SINGLE_THREADED = 2,
163 		OUT_THIS = 4,
164 		OUT_ARGS = 8,
165 		VIRTUAL = 16,
166 	}
167 
168 	enum ElementType {
169 		End		 = 0x00,
170 		Void		= 0x01,
171 		Boolean	 = 0x02,
172 		Char		= 0x03,
173 		I1		  = 0x04,
174 		U1		  = 0x05,
175 		I2		  = 0x06,
176 		U2		  = 0x07,
177 		I4		  = 0x08,
178 		U4		  = 0x09,
179 		I8		  = 0x0a,
180 		U8		  = 0x0b,
181 		R4		  = 0x0c,
182 		R8		  = 0x0d,
183 		String	  = 0x0e,
184 		Ptr		 = 0x0f,
185 		ByRef	   = 0x10,
186 		ValueType   = 0x11,
187 		Class	   = 0x12,
188 		Var        = 0x13,
189 		Array	   = 0x14,
190 		GenericInst = 0x15,
191 		TypedByRef  = 0x16,
192 		I		   = 0x18,
193 		U		   = 0x19,
194 		FnPtr	   = 0x1b,
195 		Object	  = 0x1c,
196 		SzArray	 = 0x1d,
197 		MVar       = 0x1e,
198 		CModReqD	= 0x1f,
199 		CModOpt	 = 0x20,
200 		Internal	= 0x21,
201 		Modifier	= 0x40,
202 		Sentinel	= 0x41,
203 		Pinned	  = 0x45,
204 
205 		Type		= 0x50,
206 		Boxed	   = 0x51,
207 		Enum		= 0x55
208 	}
209 
210 	class ValueImpl {
211 		public ElementType Type; /* or one of the VALUE_TYPE_ID constants */
212 		public long Objid;
213 		public object Value;
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 	}
220 
221 	class ModuleInfo {
222 		public string Name, ScopeName, FQName, Guid;
223 		public long Assembly;
224 	}
225 
226 	class FieldMirrorInfo {
227 		public string Name;
228 		public long Parent, TypeId;
229 		public int Attrs;
230 	}
231 
232 	enum TokenType {
233 		STRING = 0,
234 		TYPE = 1,
235 		FIELD = 2,
236 		METHOD = 3,
237 		UNKNOWN = 4
238 	}
239 
240 	[Flags]
241 	enum StackFrameFlags {
242 		NONE = 0,
243 		DEBUGGER_INVOKE = 1,
244 		NATIVE_TRANSITION = 2
245 	}
246 
247 	class ResolvedToken {
248 		public TokenType Type;
249 		public string Str;
250 		public long Id;
251 	}
252 
253 	class Modifier {
254 	}
255 
256 	class CountModifier : Modifier {
257 		public int Count {
258 			get; set;
259 		}
260 	}
261 
262 	class LocationModifier : Modifier {
263 		public long Method {
264 			get; set;
265 		}
266 
267 		public long Location {
268 			get; set;
269 		}
270 	}
271 
272 	class StepModifier : Modifier {
273 		public long Thread {
274 			get; set;
275 		}
276 
277 		public int Depth {
278 			get; set;
279 		}
280 
281 		public int Size {
282 			get; set;
283 		}
284 
285 		public int Filter {
286 			get; set;
287 		}
288 	}
289 
290 	class ThreadModifier : Modifier {
291 		public long Thread {
292 			get; set;
293 		}
294 	}
295 
296 	class ExceptionModifier : Modifier {
297 		public long Type {
298 			get; set;
299 		}
300 		public bool Caught {
301 			get; set;
302 		}
303 		public bool Uncaught {
304 			get; set;
305 		}
306 		public bool Subclasses {
307 			get; set;
308 		}
309 	}
310 
311 	class AssemblyModifier : Modifier {
312 		public long[] Assemblies {
313 			get; set;
314 		}
315 	}
316 
317 	class SourceFileModifier : Modifier {
318 		public string[] SourceFiles {
319 			get; set;
320 		}
321 	}
322 
323 	class TypeNameModifier : Modifier {
324 		public string[] TypeNames {
325 			get; set;
326 		}
327 	}
328 
329 	class EventInfo {
330 		public EventType EventType {
331 			get; set;
332 		}
333 
334 		public int ReqId {
335 			get; set;
336 		}
337 
338 		public SuspendPolicy SuspendPolicy {
339 			get; set;
340 		}
341 
342 		public long ThreadId {
343 			get; set;
344 		}
345 
346 		public long Id {
347 			get; set;
348 		}
349 
350 		public long Location {
351 			get; set;
352 		}
353 
354 		public int Level {
355 			get; set;
356 		}
357 
358 		public string Category {
359 			get; set;
360 		}
361 
362 		public string Message {
363 			get; set;
364 		}
365 
366 		public int ExitCode {
367 			get; set;
368 		}
369 
EventInfo(EventType type, int req_id)370 		public EventInfo (EventType type, int req_id) {
371 			EventType = type;
372 			ReqId = req_id;
373 		}
374 	}
375 
376 	public enum ErrorCode {
377 		NONE = 0,
378 		INVALID_OBJECT = 20,
379 		INVALID_FIELDID = 25,
380 		INVALID_FRAMEID = 30,
381 		NOT_IMPLEMENTED = 100,
382 		NOT_SUSPENDED = 101,
383 		INVALID_ARGUMENT = 102,
384 		ERR_UNLOADED = 103,
385 		ERR_NO_INVOCATION = 104,
386 		ABSENT_INFORMATION = 105,
387 		NO_SEQ_POINT_AT_IL_OFFSET = 106,
388 		INVOKE_ABORTED = 107
389 	}
390 
391 	public class ErrorHandlerEventArgs : EventArgs {
392 
393 		public ErrorCode ErrorCode {
394 			get; set;
395 		}
396 	}
397 
398 	/*
399 	 * Represents the connection to the debuggee
400 	 */
401 	public abstract class Connection
402 	{
403 		/*
404 		 * The protocol and the packet format is based on JDWP, the differences
405 		 * are in the set of supported events, and the commands.
406 		 */
407 		internal const string HANDSHAKE_STRING = "DWP-Handshake";
408 
409 		internal const int HEADER_LENGTH = 11;
410 
411 		static readonly bool EnableConnectionLogging = !String.IsNullOrEmpty (Environment.GetEnvironmentVariable ("MONO_SDB_LOG"));
412 		static int ConnectionId;
413 		readonly StreamWriter LoggingStream;
414 
415 		/*
416 		 * Th version of the wire-protocol implemented by the library. The library
417 		 * and the debuggee can communicate if they implement the same major version.
418 		 * If they implement a different minor version, they can communicate, but some
419 		 * features might not be available. This allows older clients to communicate
420 		 * with newer runtimes, and vice versa.
421 		 */
422 		internal const int MAJOR_VERSION = 2;
423 		internal const int MINOR_VERSION = 45;
424 
425 		enum WPSuspendPolicy {
426 			NONE = 0,
427 			EVENT_THREAD = 1,
428 			ALL = 2
429 		}
430 
431 		enum CommandSet {
432 			VM = 1,
433 			OBJECT_REF = 9,
434 			STRING_REF = 10,
435 			THREAD = 11,
436 			ARRAY_REF = 13,
437 			EVENT_REQUEST = 15,
438 			STACK_FRAME = 16,
439 			APPDOMAIN = 20,
440 			ASSEMBLY = 21,
441 			METHOD = 22,
442 			TYPE = 23,
443 			MODULE = 24,
444 			FIELD = 25,
445 			EVENT = 64
446 		}
447 
448 		enum EventKind {
449 			VM_START = 0,
450 			VM_DEATH = 1,
451 			THREAD_START = 2,
452 			THREAD_DEATH = 3,
453 			APPDOMAIN_CREATE = 4, // Not in JDI
454 			APPDOMAIN_UNLOAD = 5, // Not in JDI
455 			METHOD_ENTRY = 6,
456 			METHOD_EXIT = 7,
457 			ASSEMBLY_LOAD = 8,
458 			ASSEMBLY_UNLOAD = 9,
459 			BREAKPOINT = 10,
460 			STEP = 11,
461 			TYPE_LOAD = 12,
462 			EXCEPTION = 13,
463 			KEEPALIVE = 14,
464 			USER_BREAK = 15,
465 			USER_LOG = 16
466 		}
467 
468 		enum ModifierKind {
469 			COUNT = 1,
470 			THREAD_ONLY = 3,
471 			LOCATION_ONLY = 7,
472 			EXCEPTION_ONLY = 8,
473 			STEP = 10,
474 			ASSEMBLY_ONLY = 11,
475 			SOURCE_FILE_ONLY = 12,
476 			TYPE_NAME_ONLY = 13
477 		}
478 
479 		enum CmdVM {
480 			VERSION = 1,
481 			ALL_THREADS = 2,
482 			SUSPEND = 3,
483 			RESUME = 4,
484 			EXIT = 5,
485 			DISPOSE = 6,
486 			INVOKE_METHOD = 7,
487 			SET_PROTOCOL_VERSION = 8,
488 			ABORT_INVOKE = 9,
489 			SET_KEEPALIVE = 10,
490 			GET_TYPES_FOR_SOURCE_FILE = 11,
491 			GET_TYPES = 12,
492 			INVOKE_METHODS = 13,
493 			START_BUFFERING = 14,
494 			STOP_BUFFERING = 15
495 		}
496 
497 		enum CmdEvent {
498 			COMPOSITE = 100
499 		}
500 
501 		enum CmdThread {
502 			GET_FRAME_INFO = 1,
503 			GET_NAME = 2,
504 			GET_STATE = 3,
505 			GET_INFO = 4,
506 			/* FIXME: Merge into GET_INFO when the major protocol version is increased */
507 			GET_ID = 5,
508 			/* Ditto */
509 			GET_TID = 6,
510 			SET_IP = 7
511 		}
512 
513 		enum CmdEventRequest {
514 			SET = 1,
515 			CLEAR = 2,
516 			CLEAR_ALL_BREAKPOINTS = 3
517 		}
518 
519 		enum CmdAppDomain {
520 			GET_ROOT_DOMAIN = 1,
521 			GET_FRIENDLY_NAME = 2,
522 			GET_ASSEMBLIES = 3,
523 			GET_ENTRY_ASSEMBLY = 4,
524 			CREATE_STRING = 5,
525 			GET_CORLIB = 6,
526 			CREATE_BOXED_VALUE = 7
527 		}
528 
529 		enum CmdAssembly {
530 			GET_LOCATION = 1,
531 			GET_ENTRY_POINT = 2,
532 			GET_MANIFEST_MODULE = 3,
533 			GET_OBJECT = 4,
534 			GET_TYPE = 5,
535 			GET_NAME = 6,
536 			GET_DOMAIN = 7
537 		}
538 
539 		enum CmdModule {
540 			GET_INFO = 1,
541 		}
542 
543 		enum CmdMethod {
544 			GET_NAME = 1,
545 			GET_DECLARING_TYPE = 2,
546 			GET_DEBUG_INFO = 3,
547 			GET_PARAM_INFO = 4,
548 			GET_LOCALS_INFO = 5,
549 			GET_INFO = 6,
550 			GET_BODY = 7,
551 			RESOLVE_TOKEN = 8,
552 			GET_CATTRS = 9,
553 			MAKE_GENERIC_METHOD = 10
554 		}
555 
556 		enum CmdType {
557 			GET_INFO = 1,
558 			GET_METHODS = 2,
559 			GET_FIELDS = 3,
560 			GET_VALUES = 4,
561 			GET_OBJECT = 5,
562 			GET_SOURCE_FILES = 6,
563 			SET_VALUES = 7,
564 			IS_ASSIGNABLE_FROM = 8,
565 			GET_PROPERTIES = 9,
566 			GET_CATTRS = 10,
567 			GET_FIELD_CATTRS = 11,
568 			GET_PROPERTY_CATTRS = 12,
569 			/* FIXME: Merge into GET_SOURCE_FILES when the major protocol version is increased */
570 			GET_SOURCE_FILES_2 = 13,
571 			/* FIXME: Merge into GET_VALUES when the major protocol version is increased */
572 			GET_VALUES_2 = 14,
573 			CMD_TYPE_GET_METHODS_BY_NAME_FLAGS = 15,
574 			GET_INTERFACES = 16,
575 			GET_INTERFACE_MAP = 17,
576 			IS_INITIALIZED = 18,
577 			CREATE_INSTANCE = 19
578 		}
579 
580 		enum CmdField {
581 			GET_INFO = 1
582 		}
583 
584 		[Flags]
585 		enum BindingFlagsExtensions {
586 			BINDING_FLAGS_IGNORE_CASE = 0x70000000,
587 		}
588 
589 		enum CmdStackFrame {
590 			GET_VALUES = 1,
591 			GET_THIS = 2,
592 			SET_VALUES = 3,
593 			GET_DOMAIN = 4,
594 			SET_THIS = 5,
595 		}
596 
597 		enum CmdArrayRef {
598 			GET_LENGTH = 1,
599 			GET_VALUES = 2,
600 			SET_VALUES = 3
601 		}
602 
603 		enum CmdStringRef {
604 			GET_VALUE = 1,
605 			GET_LENGTH = 2,
606 			GET_CHARS = 3
607 		}
608 
609 		enum CmdObjectRef {
610 			GET_TYPE = 1,
611 			GET_VALUES = 2,
612 			IS_COLLECTED = 3,
613 			GET_ADDRESS = 4,
614 			GET_DOMAIN = 5,
615 			SET_VALUES = 6,
616 			GET_INFO = 7,
617 		}
618 
619 		class Header {
620 			public int id;
621 			public int command_set;
622 			public int command;
623 			public int flags;
624 		}
625 
GetPacketLength(byte[] header)626 		internal static int GetPacketLength (byte[] header) {
627 			int offset = 0;
628 			return decode_int (header, ref offset);
629 		}
630 
IsReplyPacket(byte[] packet)631 		internal static bool IsReplyPacket (byte[] packet) {
632 			int offset = 8;
633 			return decode_byte (packet, ref offset) == 0x80;
634 		}
635 
GetPacketId(byte[] packet)636 		internal static int GetPacketId (byte[] packet) {
637 			int offset = 4;
638 			return decode_int (packet, ref offset);
639 		}
640 
decode_byte(byte[] packet, ref int offset)641 		static int decode_byte (byte[] packet, ref int offset) {
642 			return packet [offset++];
643 		}
644 
decode_short(byte[] packet, ref int offset)645 		static int decode_short (byte[] packet, ref int offset) {
646 			int res = ((int)packet [offset] << 8) | (int)packet [offset + 1];
647 			offset += 2;
648 			return res;
649 		}
650 
decode_int(byte[] packet, ref int offset)651 		static int decode_int (byte[] packet, ref int offset) {
652 			int res = ((int)packet [offset] << 24) | ((int)packet [offset + 1] << 16) | ((int)packet [offset + 2] << 8) | (int)packet [offset + 3];
653 			offset += 4;
654 			return res;
655 		}
656 
decode_id(byte[] packet, ref int offset)657 		static long decode_id (byte[] packet, ref int offset) {
658 			return decode_int (packet, ref offset);
659 		}
660 
decode_long(byte[] packet, ref int offset)661 		static long decode_long (byte[] packet, ref int offset) {
662 			uint high = (uint)decode_int (packet, ref offset);
663 			uint low = (uint)decode_int (packet, ref offset);
664 
665 			return (long)(((ulong)high << 32) | (ulong)low);
666 		}
667 
decode_suspend_policy(int suspend_policy)668 		internal static SuspendPolicy decode_suspend_policy (int suspend_policy) {
669 			switch ((WPSuspendPolicy)suspend_policy) {
670 			case WPSuspendPolicy.NONE:
671 				return SuspendPolicy.None;
672 			case WPSuspendPolicy.EVENT_THREAD:
673 				return SuspendPolicy.EventThread;
674 			case WPSuspendPolicy.ALL:
675 				return SuspendPolicy.All;
676 			default:
677 				throw new NotImplementedException ();
678 			}
679 		}
680 
decode_command_header(byte[] packet)681 		static Header decode_command_header (byte[] packet) {
682 			int offset = 0;
683 			Header res = new Header ();
684 
685 			decode_int (packet, ref offset);
686 			res.id = decode_int (packet, ref offset);
687 			res.flags = decode_byte (packet, ref offset);
688 			res.command_set = decode_byte (packet, ref offset);
689 			res.command = decode_byte (packet, ref offset);
690 
691 			return res;
692 		}
693 
encode_byte(byte[] buf, int b, ref int offset)694 		static void encode_byte (byte[] buf, int b, ref int offset) {
695 			buf [offset] = (byte)b;
696 			offset ++;
697 		}
698 
encode_int(byte[] buf, int i, ref int offset)699 		static void encode_int (byte[] buf, int i, ref int offset) {
700 			buf [offset] = (byte)((i >> 24) & 0xff);
701 			buf [offset + 1] = (byte)((i >> 16) & 0xff);
702 			buf [offset + 2] = (byte)((i >> 8) & 0xff);
703 			buf [offset + 3] = (byte)((i >> 0) & 0xff);
704 			offset += 4;
705 		}
706 
encode_id(byte[] buf, long id, ref int offset)707 		static void encode_id (byte[] buf, long id, ref int offset) {
708 			encode_int (buf, (int)id, ref offset);
709 		}
710 
encode_long(byte[] buf, long l, ref int offset)711 		static void encode_long (byte[] buf, long l, ref int offset) {
712 			encode_int (buf, (int)((l >> 32) & 0xffffffff), ref offset);
713 			encode_int (buf, (int)(l & 0xffffffff), ref offset);
714 		}
715 
EncodePacket(int id, int commandSet, int command, byte[] data, int dataLen)716 		internal static byte[] EncodePacket (int id, int commandSet, int command, byte[] data, int dataLen) {
717 			byte[] buf = new byte [dataLen + 11];
718 			int offset = 0;
719 
720 			encode_int (buf, buf.Length, ref offset);
721 			encode_int (buf, id, ref offset);
722 			encode_byte (buf, 0, ref offset);
723 			encode_byte (buf, commandSet, ref offset);
724 			encode_byte (buf, command, ref offset);
725 
726 			for (int i = 0; i < dataLen; ++i)
727 				buf [offset + i] = data [i];
728 
729 			return buf;
730 		}
731 
732 		class PacketReader {
733 			byte[] packet;
734 			int offset;
735 
PacketReader(byte[] packet)736 			public PacketReader (byte[] packet) {
737 				this.packet = packet;
738 
739 				// For event packets
740 				Header header = decode_command_header (packet);
741 				CommandSet = (CommandSet)header.command_set;
742 				Command = header.command;
743 
744 				// For reply packets
745 				offset = 0;
746 				ReadInt (); // length
747 				ReadInt (); // id
748 				ReadByte (); // flags
749 				ErrorCode = ReadShort ();
750 			}
751 
752 			public CommandSet CommandSet {
753 				get; set;
754 			}
755 
756 			public int Command {
757 				get; set;
758 			}
759 
760 			public int ErrorCode {
761 				get; set;
762 			}
763 
764 			public int Offset {
765 				get {
766 					return offset;
767 				}
768 			}
769 
ReadByte()770 			public int ReadByte () {
771 				return decode_byte (packet, ref offset);
772 			}
773 
ReadShort()774 			public int ReadShort () {
775 				return decode_short (packet, ref offset);
776 			}
777 
ReadInt()778 			public int ReadInt () {
779 				return decode_int (packet, ref offset);
780 			}
781 
ReadId()782 			public long ReadId () {
783 				return decode_id (packet, ref offset);
784 			}
785 
ReadLong()786 			public long ReadLong () {
787 				return decode_long (packet, ref offset);
788 			}
789 
ReadFloat()790 			public float ReadFloat () {
791 				float f = DataConverter.FloatFromBE (packet, offset);
792 				offset += 4;
793 				return f;
794 			}
795 
ReadDouble()796 			public double ReadDouble () {
797 				double d = DataConverter.DoubleFromBE (packet, offset);
798 				offset += 8;
799 				return d;
800 			}
801 
ReadString()802 			public string ReadString () {
803 				int len = decode_int (packet, ref offset);
804 				string res = new String (Encoding.UTF8.GetChars (packet, offset, len));
805 				offset += len;
806 				return res;
807 			}
808 
ReadUTF16String()809 			public string ReadUTF16String () {
810 				int len = decode_int (packet, ref offset);
811 				string res = new String (Encoding.Unicode.GetChars (packet, offset, len));
812 				offset += len;
813 				return res;
814 			}
815 
ReadValue()816 			public ValueImpl ReadValue () {
817 				ElementType etype = (ElementType)ReadByte ();
818 
819 				switch (etype) {
820 				case ElementType.Void:
821 					return new ValueImpl { Type = etype };
822 				case ElementType.I1:
823 					return new ValueImpl { Type = etype, Value = (sbyte)ReadInt () };
824 				case ElementType.U1:
825 					return new ValueImpl { Type = etype, Value = (byte)ReadInt () };
826 				case ElementType.Boolean:
827 					return new ValueImpl { Type = etype, Value = ReadInt () != 0 };
828 				case ElementType.I2:
829 					return new ValueImpl { Type = etype, Value = (short)ReadInt () };
830 				case ElementType.U2:
831 					return new ValueImpl { Type = etype, Value = (ushort)ReadInt () };
832 				case ElementType.Char:
833 					return new ValueImpl { Type = etype, Value = (char)ReadInt () };
834 				case ElementType.I4:
835 					return new ValueImpl { Type = etype, Value = ReadInt () };
836 				case ElementType.U4:
837 					return new ValueImpl { Type = etype, Value = (uint)ReadInt () };
838 				case ElementType.I8:
839 					return new ValueImpl { Type = etype, Value = ReadLong () };
840 				case ElementType.U8:
841 					return new ValueImpl { Type = etype, Value = (ulong)ReadLong () };
842 				case ElementType.R4:
843 					return new ValueImpl { Type = etype, Value = ReadFloat () };
844 				case ElementType.R8:
845 					return new ValueImpl { Type = etype, Value = ReadDouble () };
846 				case ElementType.I:
847 				case ElementType.U:
848 				case ElementType.Ptr:
849 					// FIXME: The client and the debuggee might have different word sizes
850 					return new ValueImpl { Type = etype, Value = ReadLong () };
851 				case ElementType.String:
852 				case ElementType.SzArray:
853 				case ElementType.Class:
854 				case ElementType.Array:
855 				case ElementType.Object:
856 					long objid = ReadId ();
857 					return new ValueImpl () { Type = etype, Objid = objid };
858 				case ElementType.ValueType:
859 					bool is_enum = ReadByte () == 1;
860 					long klass = ReadId ();
861 					long nfields = ReadInt ();
862 					ValueImpl[] fields = new ValueImpl [nfields];
863 					for (int i = 0; i < nfields; ++i)
864 						fields [i] = ReadValue ();
865 					return new ValueImpl () { Type = etype, Klass = klass, Fields = fields, IsEnum = is_enum };
866 				case (ElementType)ValueTypeId.VALUE_TYPE_ID_NULL:
867 					return new ValueImpl { Type = etype };
868 				case (ElementType)ValueTypeId.VALUE_TYPE_ID_TYPE:
869 					return new ValueImpl () { Type = etype, Id = ReadId () };
870 				case (ElementType)ValueTypeId.VALUE_TYPE_ID_PARENT_VTYPE:
871 					return new ValueImpl () { Type = etype, Index = ReadInt () };
872 				default:
873 					throw new NotImplementedException ("Unable to handle type " + etype);
874 				}
875 			}
876 
ReadIds(int n)877 			public long[] ReadIds (int n) {
878 				long[] res = new long [n];
879 				for (int i = 0; i < n; ++i)
880 					res [i] = ReadId ();
881 				return res;
882 			}
883 		}
884 
885 		class PacketWriter {
886 
887 			byte[] data;
888 			int offset;
889 
PacketWriter()890 			public PacketWriter () {
891 				data = new byte [1024];
892 				offset = 0;
893 			}
894 
MakeRoom(int size)895 			void MakeRoom (int size) {
896 				if (offset + size >= data.Length) {
897 					int new_len = data.Length * 2;
898 					while (new_len < offset + size) {
899 						new_len *= 2;
900 					}
901 					byte[] new_data = new byte [new_len];
902 					Array.Copy (data, new_data, data.Length);
903 					data = new_data;
904 				}
905 			}
906 
WriteByte(byte val)907 			public PacketWriter WriteByte (byte val) {
908 				MakeRoom (1);
909 				encode_byte (data, val, ref offset);
910 				return this;
911 			}
912 
WriteInt(int val)913 			public PacketWriter WriteInt (int val) {
914 				MakeRoom (4);
915 				encode_int (data, val, ref offset);
916 				return this;
917 			}
918 
WriteId(long id)919 			public PacketWriter WriteId (long id) {
920 				MakeRoom (8);
921 				encode_id (data, id, ref offset);
922 				return this;
923 			}
924 
WriteLong(long val)925 			public PacketWriter WriteLong (long val) {
926 				MakeRoom (8);
927 				encode_long (data, val, ref offset);
928 				return this;
929 			}
930 
WriteFloat(float f)931 			public PacketWriter WriteFloat (float f) {
932 				MakeRoom (8);
933 				byte[] b = DataConverter.GetBytesBE (f);
934 				for (int i = 0; i < 4; ++i)
935 					data [offset + i] = b [i];
936 				offset += 4;
937 				return this;
938 			}
939 
WriteDouble(double d)940 			public PacketWriter WriteDouble (double d) {
941 				MakeRoom (8);
942 				byte[] b = DataConverter.GetBytesBE (d);
943 				for (int i = 0; i < 8; ++i)
944 					data [offset + i] = b [i];
945 				offset += 8;
946 				return this;
947 			}
948 
WriteInts(int[] ids)949 			public PacketWriter WriteInts (int[] ids) {
950 				for (int i = 0; i < ids.Length; ++i)
951 					WriteInt (ids [i]);
952 				return this;
953 			}
954 
WriteIds(long[] ids)955 			public PacketWriter WriteIds (long[] ids) {
956 				for (int i = 0; i < ids.Length; ++i)
957 					WriteId (ids [i]);
958 				return this;
959 			}
960 
WriteString(string s)961 			public PacketWriter WriteString (string s) {
962 				if (s == null)
963 					return WriteInt (-1);
964 
965 				byte[] b = Encoding.UTF8.GetBytes (s);
966 				MakeRoom (4);
967 				encode_int (data, b.Length, ref offset);
968 				MakeRoom (b.Length);
969 				Buffer.BlockCopy (b, 0, data, offset, b.Length);
970 				offset += b.Length;
971 				return this;
972 			}
973 
WriteBool(bool val)974 			public PacketWriter WriteBool (bool val) {
975 				WriteByte (val ? (byte)1 : (byte)0);
976 				return this;
977 			}
978 
WriteValue(ValueImpl v)979 			public PacketWriter WriteValue (ValueImpl v) {
980 				ElementType t;
981 
982 				if (v.Value != null)
983 					t = TypeCodeToElementType (Type.GetTypeCode (v.Value.GetType ()));
984 				else
985 					t = v.Type;
986 				WriteByte ((byte)t);
987 				switch (t) {
988 				case ElementType.Boolean:
989 					WriteInt ((bool)v.Value ? 1 : 0);
990 					break;
991 				case ElementType.Char:
992 					WriteInt ((int)(char)v.Value);
993 					break;
994 				case ElementType.I1:
995 					WriteInt ((int)(sbyte)v.Value);
996 					break;
997 				case ElementType.U1:
998 					WriteInt ((int)(byte)v.Value);
999 					break;
1000 				case ElementType.I2:
1001 					WriteInt ((int)(short)v.Value);
1002 					break;
1003 				case ElementType.U2:
1004 					WriteInt ((int)(ushort)v.Value);
1005 					break;
1006 				case ElementType.I4:
1007 					WriteInt ((int)(int)v.Value);
1008 					break;
1009 				case ElementType.U4:
1010 					WriteInt ((int)(uint)v.Value);
1011 					break;
1012 				case ElementType.I8:
1013 					WriteLong ((long)(long)v.Value);
1014 					break;
1015 				case ElementType.U8:
1016 					WriteLong ((long)(ulong)v.Value);
1017 					break;
1018 				case ElementType.R4:
1019 					WriteFloat ((float)v.Value);
1020 					break;
1021 				case ElementType.R8:
1022 					WriteDouble ((double)v.Value);
1023 					break;
1024 				case ElementType.String:
1025 				case ElementType.SzArray:
1026 				case ElementType.Class:
1027 				case ElementType.Array:
1028 				case ElementType.Object:
1029 					WriteId (v.Objid);
1030 					break;
1031 				case ElementType.ValueType:
1032 					// FIXME:
1033 					if (v.IsEnum)
1034 						throw new NotImplementedException ();
1035 					WriteByte (0);
1036 					WriteId (v.Klass);
1037 					WriteInt (v.Fields.Length);
1038 					for (int i = 0; i < v.Fields.Length; ++i)
1039 						WriteValue (v.Fields [i]);
1040 					break;
1041 				case (ElementType)ValueTypeId.VALUE_TYPE_ID_NULL:
1042 					break;
1043 				default:
1044 					throw new NotImplementedException ();
1045 				}
1046 
1047 				return this;
1048 			}
1049 
WriteValues(ValueImpl[] values)1050 			public PacketWriter WriteValues (ValueImpl[] values) {
1051 				for (int i = 0; i < values.Length; ++i)
1052 					WriteValue (values [i]);
1053 				return this;
1054 			}
1055 
1056 			public byte[] Data {
1057 				get {
1058 					return data;
1059 				}
1060 			}
1061 
1062 			public int Offset {
1063 				get {
1064 					return offset;
1065 				}
1066 			}
1067 		}
1068 
ReplyCallback(int packet_id, byte[] packet)1069 		delegate void ReplyCallback (int packet_id, byte[] packet);
1070 
1071 		bool closed;
1072 		Thread receiver_thread;
1073 		Dictionary<int, byte[]> reply_packets;
1074 		Dictionary<int, ReplyCallback> reply_cbs;
1075 		Dictionary<int, int> reply_cb_counts;
1076 		object reply_packets_monitor;
1077 
1078 		internal event EventHandler<ErrorHandlerEventArgs> ErrorHandler;
1079 
Connection()1080 		protected Connection () {
1081 			closed = false;
1082 			reply_packets = new Dictionary<int, byte[]> ();
1083 			reply_cbs = new Dictionary<int, ReplyCallback> ();
1084 			reply_cb_counts = new Dictionary<int, int> ();
1085 			reply_packets_monitor = new Object ();
1086 			if (EnableConnectionLogging) {
1087 				var path = Environment.GetEnvironmentVariable ("MONO_SDB_LOG");
1088 				if (path.Contains ("{0}")) {
1089 					//C:\SomeDir\sdbLog{0}.txt -> C:\SomeDir\sdbLog1.txt
1090 					LoggingStream = new StreamWriter (string.Format (path, ConnectionId++), false);
1091 				} else if (Path.HasExtension (path)) {
1092 					//C:\SomeDir\sdbLog.txt -> C:\SomeDir\sdbLog1.txt
1093 					LoggingStream = new StreamWriter (Path.GetDirectoryName (path) + Path.DirectorySeparatorChar + Path.GetFileNameWithoutExtension (path) + ConnectionId++ + "." + Path.GetExtension (path), false);
1094 				} else {
1095 					//C:\SomeDir\sdbLog -> C:\SomeDir\sdbLog1
1096 					LoggingStream = new StreamWriter (path + ConnectionId++, false);
1097 				}
1098 			}
1099 		}
1100 
TransportReceive(byte[] buf, int buf_offset, int len)1101 		protected abstract int TransportReceive (byte[] buf, int buf_offset, int len);
TransportSend(byte[] buf, int buf_offset, int len)1102 		protected abstract int TransportSend (byte[] buf, int buf_offset, int len);
TransportSetTimeouts(int send_timeout, int receive_timeout)1103 		protected abstract void TransportSetTimeouts (int send_timeout, int receive_timeout);
TransportClose()1104 		protected abstract void TransportClose ();
1105 
1106 		internal VersionInfo Version;
1107 
Receive(byte[] buf, int buf_offset, int len)1108 		int Receive (byte[] buf, int buf_offset, int len) {
1109 			int offset = 0;
1110 
1111 			while (offset < len) {
1112 				int n = TransportReceive (buf, buf_offset + offset, len - offset);
1113 
1114 				if (n == 0)
1115 					return offset;
1116 				offset += n;
1117 			}
1118 
1119 			return offset;
1120 		}
1121 
1122 		// Do the wire protocol handshake
Connect()1123 		internal void Connect () {
1124 			byte[] buf = new byte [HANDSHAKE_STRING.Length];
1125 			char[] cbuf = new char [buf.Length];
1126 
1127 			// FIXME: Add a timeout
1128 			int n = Receive (buf, 0, buf.Length);
1129 			if (n == 0)
1130 				throw new IOException ("DWP Handshake failed.");
1131 			for (int i = 0; i < buf.Length; ++i)
1132 				cbuf [i] = (char)buf [i];
1133 
1134 			if (new String (cbuf) != HANDSHAKE_STRING)
1135 				throw new IOException ("DWP Handshake failed.");
1136 
1137 			TransportSend (buf, 0, buf.Length);
1138 
1139 			receiver_thread = new Thread (new ThreadStart (receiver_thread_main));
1140 			receiver_thread.Name = "SDB Receiver";
1141 			receiver_thread.IsBackground = true;
1142 			receiver_thread.Start ();
1143 
1144 			Version = VM_GetVersion ();
1145 
1146 			//
1147 			// Tell the debuggee our protocol version, so newer debuggees can work
1148 			// with older clients
1149 			//
1150 
1151 			//
1152 			// Older debuggees might not support this request
1153 			EventHandler<ErrorHandlerEventArgs> OrigErrorHandler = ErrorHandler;
1154 			ErrorHandler = null;
1155 			ErrorHandler += delegate (object sender, ErrorHandlerEventArgs args) {
1156 				throw new NotSupportedException ();
1157 			};
1158 			try {
1159 				VM_SetProtocolVersion (MAJOR_VERSION, MINOR_VERSION);
1160 			} catch (NotSupportedException) {
1161 			}
1162 			ErrorHandler = OrigErrorHandler;
1163 		}
1164 
ReadPacket()1165 		internal byte[] ReadPacket () {
1166 			// FIXME: Throw ClosedConnectionException () if the connection is closed
1167 			// FIXME: Throw ClosedConnectionException () if another thread closes the connection
1168 			// FIXME: Locking
1169 			byte[] header = new byte [HEADER_LENGTH];
1170 
1171 			int len = Receive (header, 0, header.Length);
1172 			if (len == 0)
1173 				return new byte [0];
1174 			if (len != HEADER_LENGTH) {
1175 				// FIXME:
1176 				throw new IOException ("Packet of length " + len + " is read.");
1177 			}
1178 
1179 			int packetLength = GetPacketLength (header);
1180 			if (packetLength < 11)
1181 				throw new IOException ("Invalid packet length.");
1182 
1183 			if (packetLength == 11) {
1184 				return header;
1185 			} else {
1186 				byte[] buf = new byte [packetLength];
1187 				for (int i = 0; i < header.Length; ++i)
1188 					buf [i] = header [i];
1189 				len = Receive (buf, header.Length, packetLength - header.Length);
1190 				if (len != packetLength - header.Length)
1191 					throw new IOException ();
1192 				return buf;
1193 			}
1194 		}
1195 
WritePacket(byte[] packet)1196 		internal void WritePacket (byte[] packet) {
1197 			// FIXME: Throw ClosedConnectionException () if the connection is closed
1198 			// FIXME: Throw ClosedConnectionException () if another thread closes the connection
1199 			// FIXME: Locking
1200 			TransportSend (packet, 0, packet.Length);
1201 		}
1202 
WritePackets(List<byte[]> packets)1203 		internal void WritePackets (List<byte[]> packets) {
1204 			// FIXME: Throw ClosedConnectionException () if the connection is closed
1205 			// FIXME: Throw ClosedConnectionException () if another thread closes the connection
1206 			// FIXME: Locking
1207 			int len = 0;
1208 			for (int i = 0; i < packets.Count; ++i)
1209 				len += packets [i].Length;
1210 			byte[] data = new byte [len];
1211 			int pos = 0;
1212 			for (int i = 0; i < packets.Count; ++i) {
1213 				Buffer.BlockCopy (packets [i], 0, data, pos, packets [i].Length);
1214 				pos += packets [i].Length;
1215 			}
1216 			TransportSend (data, 0, data.Length);
1217 		}
1218 
Close()1219 		internal void Close () {
1220 			closed = true;
1221 		}
1222 
1223 		internal bool IsClosed {
1224 			get {
1225 				return closed;
1226 			}
1227 		}
1228 
1229 		bool disconnected;
1230 
1231 		internal ManualResetEvent DisconnectedEvent = new ManualResetEvent (false);
1232 
receiver_thread_main()1233 		void receiver_thread_main () {
1234 			while (!closed) {
1235 				try {
1236 					bool res = ReceivePacket ();
1237 					if (!res)
1238 						break;
1239 				} catch (ThreadAbortException) {
1240 					break;
1241 				} catch (Exception ex) {
1242 					if (!closed) {
1243 						Console.WriteLine (ex);
1244 					}
1245 					break;
1246 				}
1247 			}
1248 
1249 			lock (reply_packets_monitor) {
1250 				disconnected = true;
1251 				DisconnectedEvent.Set ();
1252 				Monitor.PulseAll (reply_packets_monitor);
1253 				TransportClose ();
1254 			}
1255 			EventHandler.VMDisconnect (0, 0, null);
1256 		}
1257 
ReceivePacket()1258 		bool ReceivePacket () {
1259 				byte[] packet = ReadPacket ();
1260 
1261 				if (packet.Length == 0) {
1262 					return false;
1263 				}
1264 
1265 				if (IsReplyPacket (packet)) {
1266 					int id = GetPacketId (packet);
1267 					ReplyCallback cb = null;
1268 					lock (reply_packets_monitor) {
1269 						reply_cbs.TryGetValue (id, out cb);
1270 						if (cb == null) {
1271 							reply_packets [id] = packet;
1272 							Monitor.PulseAll (reply_packets_monitor);
1273 						} else {
1274 							int c = reply_cb_counts [id];
1275 							c --;
1276 							if (c == 0) {
1277 								reply_cbs.Remove (id);
1278 								reply_cb_counts.Remove (id);
1279 							}
1280 						}
1281 					}
1282 
1283 					if (cb != null)
1284 						cb.Invoke (id, packet);
1285 				} else {
1286 					PacketReader r = new PacketReader (packet);
1287 
1288 					if (r.CommandSet == CommandSet.EVENT && r.Command == (int)CmdEvent.COMPOSITE) {
1289 						int spolicy = r.ReadByte ();
1290 						int nevents = r.ReadInt ();
1291 
1292 						SuspendPolicy suspend_policy = decode_suspend_policy (spolicy);
1293 
1294 						EventInfo[] events = new EventInfo [nevents];
1295 
1296 						for (int i = 0; i < nevents; ++i) {
1297 							EventKind kind = (EventKind)r.ReadByte ();
1298 							int req_id = r.ReadInt ();
1299 
1300 							EventType etype = (EventType)kind;
1301 
1302 							long thread_id = r.ReadId ();
1303 							if (kind == EventKind.VM_START) {
1304 								events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id };
1305 								//EventHandler.VMStart (req_id, thread_id, null);
1306 							} else if (kind == EventKind.VM_DEATH) {
1307 								int exit_code = 0;
1308 								if (Version.AtLeast (2, 27))
1309 									exit_code = r.ReadInt ();
1310 								//EventHandler.VMDeath (req_id, 0, null);
1311 								events [i] = new EventInfo (etype, req_id) { ExitCode = exit_code };
1312 							} else if (kind == EventKind.THREAD_START) {
1313 								events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = thread_id };
1314 								//EventHandler.ThreadStart (req_id, thread_id, thread_id);
1315 							} else if (kind == EventKind.THREAD_DEATH) {
1316 								events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = thread_id };
1317 								//EventHandler.ThreadDeath (req_id, thread_id, thread_id);
1318 							} else if (kind == EventKind.ASSEMBLY_LOAD) {
1319 								long id = r.ReadId ();
1320 								events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id };
1321 								//EventHandler.AssemblyLoad (req_id, thread_id, id);
1322 							} else if (kind == EventKind.ASSEMBLY_UNLOAD) {
1323 								long id = r.ReadId ();
1324 								events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id };
1325 								//EventHandler.AssemblyUnload (req_id, thread_id, id);
1326 							} else if (kind == EventKind.TYPE_LOAD) {
1327 								long id = r.ReadId ();
1328 								events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id };
1329 								//EventHandler.TypeLoad (req_id, thread_id, id);
1330 							} else if (kind == EventKind.METHOD_ENTRY) {
1331 								long id = r.ReadId ();
1332 								events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id };
1333 								//EventHandler.MethodEntry (req_id, thread_id, id);
1334 							} else if (kind == EventKind.METHOD_EXIT) {
1335 								long id = r.ReadId ();
1336 								events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id };
1337 								//EventHandler.MethodExit (req_id, thread_id, id);
1338 							} else if (kind == EventKind.BREAKPOINT) {
1339 								long id = r.ReadId ();
1340 								long loc = r.ReadLong ();
1341 								events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id, Location = loc };
1342 								//EventHandler.Breakpoint (req_id, thread_id, id, loc);
1343 							} else if (kind == EventKind.STEP) {
1344 								long id = r.ReadId ();
1345 								long loc = r.ReadLong ();
1346 								events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id, Location = loc };
1347 								//EventHandler.Step (req_id, thread_id, id, loc);
1348 							} else if (kind == EventKind.EXCEPTION) {
1349 								long id = r.ReadId ();
1350 								long loc = 0; // FIXME
1351 								events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id, Location = loc };
1352 								//EventHandler.Exception (req_id, thread_id, id, loc);
1353 							} else if (kind == EventKind.APPDOMAIN_CREATE) {
1354 								long id = r.ReadId ();
1355 								events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id };
1356 								//EventHandler.AppDomainCreate (req_id, thread_id, id);
1357 							} else if (kind == EventKind.APPDOMAIN_UNLOAD) {
1358 								long id = r.ReadId ();
1359 								events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id };
1360 								//EventHandler.AppDomainUnload (req_id, thread_id, id);
1361 							} else if (kind == EventKind.USER_BREAK) {
1362 								long id = 0;
1363 								long loc = 0;
1364 								events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id, Location = loc };
1365 								//EventHandler.Exception (req_id, thread_id, id, loc);
1366 							} else if (kind == EventKind.USER_LOG) {
1367 								int level = r.ReadInt ();
1368 								string category = r.ReadString ();
1369 								string message = r.ReadString ();
1370 								events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Level = level, Category = category, Message = message };
1371 								//EventHandler.Exception (req_id, thread_id, id, loc);
1372 							} else if (kind == EventKind.KEEPALIVE) {
1373 								events [i] = new EventInfo (etype, req_id) { };
1374 							} else {
1375 								throw new NotImplementedException ("Unknown event kind: " + kind);
1376 							}
1377 						}
1378 
1379 						EventHandler.Events (suspend_policy, events);
1380 					}
1381 				}
1382 
1383 				return true;
1384 		}
1385 
1386 		internal IEventHandler EventHandler {
1387 			get; set;
1388 		}
1389 
CommandString(CommandSet command_set, int command)1390 		static String CommandString (CommandSet command_set, int command)
1391 		{
1392 			string cmd;
1393 			switch (command_set) {
1394 			case CommandSet.VM:
1395 				cmd = ((CmdVM)command).ToString ();
1396 				break;
1397 			case CommandSet.OBJECT_REF:
1398 				cmd = ((CmdObjectRef)command).ToString ();
1399 				break;
1400 			case CommandSet.STRING_REF:
1401 				cmd = ((CmdStringRef)command).ToString ();
1402 				break;
1403 			case CommandSet.THREAD:
1404 				cmd = ((CmdThread)command).ToString ();
1405 				break;
1406 			case CommandSet.ARRAY_REF:
1407 				cmd = ((CmdArrayRef)command).ToString ();
1408 				break;
1409 			case CommandSet.EVENT_REQUEST:
1410 				cmd = ((CmdEventRequest)command).ToString ();
1411 				break;
1412 			case CommandSet.STACK_FRAME:
1413 				cmd = ((CmdStackFrame)command).ToString ();
1414 				break;
1415 			case CommandSet.APPDOMAIN:
1416 				cmd = ((CmdAppDomain)command).ToString ();
1417 				break;
1418 			case CommandSet.ASSEMBLY:
1419 				cmd = ((CmdAssembly)command).ToString ();
1420 				break;
1421 			case CommandSet.METHOD:
1422 				cmd = ((CmdMethod)command).ToString ();
1423 				break;
1424 			case CommandSet.TYPE:
1425 				cmd = ((CmdType)command).ToString ();
1426 				break;
1427 			case CommandSet.MODULE:
1428 				cmd = ((CmdModule)command).ToString ();
1429 				break;
1430 			case CommandSet.FIELD:
1431 				cmd = ((CmdField)command).ToString ();
1432 				break;
1433 			case CommandSet.EVENT:
1434 				cmd = ((CmdEvent)command).ToString ();
1435 				break;
1436 			default:
1437 				cmd = command.ToString ();
1438 				break;
1439 			}
1440 			return string.Format ("[{0} {1}]", command_set, cmd);
1441 		}
1442 
1443 		long total_protocol_ticks;
1444 
LogPacket(int packet_id, byte[] encoded_packet, byte[] reply_packet, CommandSet command_set, int command, Stopwatch watch)1445 		void LogPacket (int packet_id, byte[] encoded_packet, byte[] reply_packet, CommandSet command_set, int command, Stopwatch watch) {
1446 			watch.Stop ();
1447 			total_protocol_ticks += watch.ElapsedTicks;
1448 			var ts = TimeSpan.FromTicks (total_protocol_ticks);
1449 			string msg = string.Format ("Packet: {0} sent: {1} received: {2} ms: {3} total ms: {4} {5}",
1450 			   packet_id, encoded_packet.Length, reply_packet.Length, watch.ElapsedMilliseconds,
1451 			   (ts.Seconds * 1000) + ts.Milliseconds,
1452 			   CommandString (command_set, command));
1453 
1454 			LoggingStream.WriteLine (msg);
1455 			LoggingStream.Flush ();
1456 		}
1457 
1458 		bool buffer_packets;
1459 		List<byte[]> buffered_packets = new List<byte[]> ();
1460 
1461 		//
1462 		// Start buffering request/response packets on both the client and the debuggee side.
1463 		// Packets sent between StartBuffering ()/StopBuffering () must be async, i.e. sent
1464 		// using Send () and not SendReceive ().
1465 		//
StartBuffering()1466 		public void StartBuffering () {
1467 			buffer_packets = true;
1468 			if (Version.AtLeast (2, 34))
1469 				VM_StartBuffering ();
1470 		}
1471 
StopBuffering()1472 		public void StopBuffering () {
1473 			if (Version.AtLeast (2, 34))
1474 				VM_StopBuffering ();
1475 			buffer_packets = false;
1476 
1477 			WritePackets (buffered_packets);
1478 			if (EnableConnectionLogging) {
1479 				LoggingStream.WriteLine (String.Format ("Sent {0} packets.", buffered_packets.Count));
1480 				LoggingStream.Flush ();
1481 			}
1482 			buffered_packets.Clear ();
1483 		}
1484 
1485 		/* Send a request and call cb when a result is received */
Send(CommandSet command_set, int command, PacketWriter packet, Action<PacketReader> cb, int count)1486 		int Send (CommandSet command_set, int command, PacketWriter packet, Action<PacketReader> cb, int count) {
1487 			int id = IdGenerator;
1488 
1489 			Stopwatch watch = null;
1490 			if (EnableConnectionLogging)
1491 				watch = Stopwatch.StartNew ();
1492 
1493 			byte[] encoded_packet;
1494 			if (packet == null)
1495 				encoded_packet = EncodePacket (id, (int)command_set, command, null, 0);
1496 			else
1497 				encoded_packet = EncodePacket (id, (int)command_set, command, packet.Data, packet.Offset);
1498 
1499 			if (cb != null) {
1500 				lock (reply_packets_monitor) {
1501 					reply_cbs [id] = delegate (int packet_id, byte[] p) {
1502 						if (EnableConnectionLogging)
1503 							LogPacket (packet_id, encoded_packet, p, command_set, command, watch);
1504 						/* Run the callback on a tp thread to avoid blocking the receive thread */
1505 						PacketReader r = new PacketReader (p);
1506 						cb.BeginInvoke (r, null, null);
1507 					};
1508 					reply_cb_counts [id] = count;
1509 				}
1510 			}
1511 
1512 			if (buffer_packets)
1513 				buffered_packets.Add (encoded_packet);
1514 			else
1515 				WritePacket (encoded_packet);
1516 
1517 			return id;
1518 		}
1519 
1520 		// Send a request without waiting for an answer
Send(CommandSet command_set, int command)1521 		void Send (CommandSet command_set, int command) {
1522 			Send (command_set, command, null, null, 0);
1523 		}
1524 
SendReceive(CommandSet command_set, int command, PacketWriter packet)1525 		PacketReader SendReceive (CommandSet command_set, int command, PacketWriter packet) {
1526 			int id = IdGenerator;
1527 			Stopwatch watch = null;
1528 
1529 			if (disconnected)
1530 				throw new VMDisconnectedException ();
1531 
1532 			if (EnableConnectionLogging)
1533 				watch = Stopwatch.StartNew ();
1534 
1535 			byte[] encoded_packet;
1536 
1537 			if (packet == null)
1538 				encoded_packet = EncodePacket (id, (int)command_set, command, null, 0);
1539 			else
1540 				encoded_packet = EncodePacket (id, (int)command_set, command, packet.Data, packet.Offset);
1541 
1542 			WritePacket (encoded_packet);
1543 
1544 			int packetId = id;
1545 
1546 			/* Wait for the reply packet */
1547 			while (true) {
1548 				lock (reply_packets_monitor) {
1549 					if (reply_packets.ContainsKey (packetId)) {
1550 						byte[] reply = reply_packets [packetId];
1551 						reply_packets.Remove (packetId);
1552 						PacketReader r = new PacketReader (reply);
1553 
1554 						if (EnableConnectionLogging)
1555 							LogPacket (packetId, encoded_packet, reply, command_set, command, watch);
1556 						if (r.ErrorCode != 0) {
1557 							if (ErrorHandler != null)
1558 								ErrorHandler (this, new ErrorHandlerEventArgs () { ErrorCode = (ErrorCode)r.ErrorCode });
1559 							throw new NotImplementedException ("No error handler set.");
1560 						} else {
1561 							return r;
1562 						}
1563 					} else {
1564 						if (disconnected)
1565 							throw new VMDisconnectedException ();
1566 						Monitor.Wait (reply_packets_monitor);
1567 					}
1568 				}
1569 			}
1570 		}
1571 
SendReceive(CommandSet command_set, int command)1572 		PacketReader SendReceive (CommandSet command_set, int command) {
1573 			return SendReceive (command_set, command, null);
1574 		}
1575 
1576 		int packet_id_generator;
1577 
1578 		int IdGenerator {
1579 			get {
1580 				return Interlocked.Increment (ref packet_id_generator);
1581 			}
1582 		}
1583 
ReadCattrs(PacketReader r)1584 		CattrInfo[] ReadCattrs (PacketReader r) {
1585 			CattrInfo[] res = new CattrInfo [r.ReadInt ()];
1586 			for (int i = 0; i < res.Length; ++i) {
1587 				CattrInfo info = new CattrInfo ();
1588 				info.ctor_id = r.ReadId ();
1589 				info.ctor_args = new ValueImpl [r.ReadInt ()];
1590 				for (int j = 0; j < info.ctor_args.Length; ++j) {
1591 					info.ctor_args [j] = r.ReadValue ();
1592 				}
1593 				info.named_args = new CattrNamedArgInfo [r.ReadInt ()];
1594 				for (int j = 0; j < info.named_args.Length; ++j) {
1595 					CattrNamedArgInfo arg = new CattrNamedArgInfo ();
1596 					int arg_type = r.ReadByte ();
1597 					arg.is_property = arg_type == 0x54;
1598 					arg.id = r.ReadId ();
1599 					arg.value = r.ReadValue ();
1600 					info.named_args [j] = arg;
1601 				}
1602 				res [i] = info;
1603 			}
1604 			return res;
1605 		}
1606 
TypeCodeToElementType(TypeCode c)1607 		static ElementType TypeCodeToElementType (TypeCode c) {
1608 			switch (c) {
1609 			case TypeCode.Boolean:
1610 				return ElementType.Boolean;
1611 			case TypeCode.Char:
1612 				return ElementType.Char;
1613 			case TypeCode.SByte:
1614 				return ElementType.I1;
1615 			case TypeCode.Byte:
1616 				return ElementType.U1;
1617 			case TypeCode.Int16:
1618 				return ElementType.I2;
1619 			case TypeCode.UInt16:
1620 				return ElementType.U2;
1621 			case TypeCode.Int32:
1622 				return ElementType.I4;
1623 			case TypeCode.UInt32:
1624 				return ElementType.U4;
1625 			case TypeCode.Int64:
1626 				return ElementType.I8;
1627 			case TypeCode.UInt64:
1628 				return ElementType.U8;
1629 			case TypeCode.Single:
1630 				return ElementType.R4;
1631 			case TypeCode.Double:
1632 				return ElementType.R8;
1633 			default:
1634 				throw new NotImplementedException ();
1635 			}
1636 		}
1637 
1638 		/*
1639 		 * Implementation of debugger commands
1640 		 */
1641 
VM_GetVersion()1642 		internal VersionInfo VM_GetVersion () {
1643 			var res = SendReceive (CommandSet.VM, (int)CmdVM.VERSION, null);
1644 			VersionInfo info = new VersionInfo ();
1645 			info.VMVersion = res.ReadString ();
1646 			info.MajorVersion = res.ReadInt ();
1647 			info.MinorVersion = res.ReadInt ();
1648 			return info;
1649 		}
1650 
VM_SetProtocolVersion(int major, int minor)1651 		internal void VM_SetProtocolVersion (int major, int minor) {
1652 			SendReceive (CommandSet.VM, (int)CmdVM.SET_PROTOCOL_VERSION, new PacketWriter ().WriteInt (major).WriteInt (minor));
1653 		}
1654 
VM_GetThreads(Action<long[]> resultCallaback)1655 		internal void VM_GetThreads (Action<long[]> resultCallaback) {
1656 			Send (CommandSet.VM, (int)CmdVM.ALL_THREADS, null, (res) => {
1657 				int len = res.ReadInt ();
1658 				long[] arr = new long [len];
1659 				for (int i = 0; i < len; ++i)
1660 					arr [i] = res.ReadId ();
1661 				resultCallaback(arr);
1662 			}, 1);
1663 		}
1664 
VM_Suspend()1665 		internal void VM_Suspend () {
1666 			SendReceive (CommandSet.VM, (int)CmdVM.SUSPEND);
1667 		}
1668 
VM_Resume()1669 		internal void VM_Resume () {
1670 			SendReceive (CommandSet.VM, (int)CmdVM.RESUME);
1671 		}
1672 
VM_Exit(int exitCode)1673 		internal void VM_Exit (int exitCode) {
1674 			SendReceive (CommandSet.VM, (int)CmdVM.EXIT, new PacketWriter ().WriteInt (exitCode));
1675 		}
1676 
VM_Dispose()1677 		internal void VM_Dispose () {
1678 			SendReceive (CommandSet.VM, (int)CmdVM.DISPOSE);
1679 		}
1680 
VM_InvokeMethod(long thread, long method, ValueImpl this_arg, ValueImpl[] arguments, InvokeFlags flags, out ValueImpl exc)1681 		internal ValueImpl VM_InvokeMethod (long thread, long method, ValueImpl this_arg, ValueImpl[] arguments, InvokeFlags flags, out ValueImpl exc) {
1682 			exc = null;
1683 			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));
1684 			if (r.ReadByte () == 0) {
1685 				exc = r.ReadValue ();
1686 				return null;
1687 			} else {
1688 				return r.ReadValue ();
1689 			}
1690 		}
1691 
InvokeMethodCallback(ValueImpl v, ValueImpl exc, ValueImpl out_this, ValueImpl[] out_args, ErrorCode error, object state)1692 		internal delegate void InvokeMethodCallback (ValueImpl v, ValueImpl exc, ValueImpl out_this, ValueImpl[] out_args, ErrorCode error, object state);
1693 
read_invoke_res(PacketReader r, out ValueImpl v, out ValueImpl exc, out ValueImpl out_this, out ValueImpl[] out_args)1694 		void read_invoke_res (PacketReader r, out ValueImpl v, out ValueImpl exc, out ValueImpl out_this, out ValueImpl[] out_args) {
1695 			int resflags = r.ReadByte ();
1696 			v = null;
1697 			exc = null;
1698 			out_this = null;
1699 			out_args = null;
1700 			if (resflags == 0) {
1701 				exc = r.ReadValue ();
1702 			} else {
1703 				v = r.ReadValue ();
1704 				if ((resflags & 2) != 0)
1705 					out_this = r.ReadValue ();
1706 				if ((resflags & 4) != 0) {
1707 					int nargs = r.ReadInt ();
1708 					out_args = new ValueImpl [nargs];
1709 					for (int i = 0; i < nargs; ++i)
1710 						out_args [i] = r.ReadValue ();
1711 				}
1712 			}
1713 		}
1714 
VM_BeginInvokeMethod(long thread, long method, ValueImpl this_arg, ValueImpl[] arguments, InvokeFlags flags, InvokeMethodCallback callback, object state)1715 		internal int VM_BeginInvokeMethod (long thread, long method, ValueImpl this_arg, ValueImpl[] arguments, InvokeFlags flags, InvokeMethodCallback callback, object state) {
1716 			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) {
1717 					ValueImpl v, exc, out_this = null;
1718 					ValueImpl[] out_args = null;
1719 
1720 					if (r.ErrorCode != 0) {
1721 						callback (null, null, null, null, (ErrorCode)r.ErrorCode, state);
1722 					} else {
1723 						read_invoke_res (r, out v, out exc, out out_this, out out_args);
1724 						callback (v, exc, out_this, out_args, 0, state);
1725 					}
1726 				}, 1);
1727 		}
1728 
VM_BeginInvokeMethods(long thread, long[] methods, ValueImpl this_arg, List<ValueImpl[]> arguments, InvokeFlags flags, InvokeMethodCallback callback, object state)1729 		internal int VM_BeginInvokeMethods (long thread, long[] methods, ValueImpl this_arg, List<ValueImpl[]> arguments, InvokeFlags flags, InvokeMethodCallback callback, object state) {
1730 			// FIXME: Merge this with INVOKE_METHOD
1731 			var w = new PacketWriter ();
1732 			w.WriteId (thread);
1733 			w.WriteInt ((int)flags);
1734 			w.WriteInt (methods.Length);
1735 			for (int i = 0; i < methods.Length; ++i) {
1736 				w.WriteId (methods [i]);
1737 				w.WriteValue (this_arg);
1738 				w.WriteInt (arguments [i].Length);
1739 				w.WriteValues (arguments [i]);
1740 			}
1741 			return Send (CommandSet.VM, (int)CmdVM.INVOKE_METHODS, w, delegate (PacketReader r) {
1742 					ValueImpl v, exc, out_this = null;
1743 					ValueImpl[] out_args = null;
1744 
1745 					if (r.ErrorCode != 0) {
1746 						callback (null, null, null, null, (ErrorCode)r.ErrorCode, state);
1747 					} else {
1748 						read_invoke_res (r, out v, out exc, out out_this, out out_args);
1749 						callback (v, exc, out_this, out_args, 0, state);
1750 					}
1751 				}, methods.Length);
1752 		}
1753 
VM_AbortInvoke(long thread, int id)1754 		internal void VM_AbortInvoke (long thread, int id)
1755 		{
1756 			SendReceive (CommandSet.VM, (int)CmdVM.ABORT_INVOKE, new PacketWriter ().WriteId (thread).WriteInt (id));
1757 		}
1758 
SetSocketTimeouts(int send_timeout, int receive_timeout, int keepalive_interval)1759 		internal void SetSocketTimeouts (int send_timeout, int receive_timeout, int keepalive_interval)
1760 		{
1761 			TransportSetTimeouts (send_timeout, receive_timeout);
1762 			SendReceive (CommandSet.VM, (int)CmdVM.SET_KEEPALIVE, new PacketWriter ().WriteId (keepalive_interval));
1763 		}
1764 
VM_GetTypesForSourceFile(string fname, bool ignoreCase)1765 		internal long[] VM_GetTypesForSourceFile (string fname, bool ignoreCase) {
1766 			var res = SendReceive (CommandSet.VM, (int)CmdVM.GET_TYPES_FOR_SOURCE_FILE, new PacketWriter ().WriteString (fname).WriteBool (ignoreCase));
1767 			int count = res.ReadInt ();
1768 			long[] types = new long [count];
1769 			for (int i = 0; i < count; ++i)
1770 				types [i] = res.ReadId ();
1771 			return types;
1772 		}
1773 
VM_GetTypes(string name, bool ignoreCase)1774 		internal long[] VM_GetTypes (string name, bool ignoreCase) {
1775 			var res = SendReceive (CommandSet.VM, (int)CmdVM.GET_TYPES, new PacketWriter ().WriteString (name).WriteBool (ignoreCase));
1776 			int count = res.ReadInt ();
1777 			long[] types = new long [count];
1778 			for (int i = 0; i < count; ++i)
1779 				types [i] = res.ReadId ();
1780 			return types;
1781 		}
1782 
VM_StartBuffering()1783 		internal void VM_StartBuffering () {
1784 			Send (CommandSet.VM, (int)CmdVM.START_BUFFERING);
1785 		}
1786 
VM_StopBuffering()1787 		internal void VM_StopBuffering () {
1788 			Send (CommandSet.VM, (int)CmdVM.STOP_BUFFERING);
1789 		}
1790 
1791 		/*
1792 		 * DOMAIN
1793 		 */
1794 
1795 		internal long RootDomain {
1796 			get {
1797 				return SendReceive (CommandSet.APPDOMAIN, (int)CmdAppDomain.GET_ROOT_DOMAIN, null).ReadId ();
1798 			}
1799 		}
1800 
Domain_GetName(long id)1801 		internal string Domain_GetName (long id) {
1802 			return SendReceive (CommandSet.APPDOMAIN, (int)CmdAppDomain.GET_FRIENDLY_NAME, new PacketWriter ().WriteId (id)).ReadString ();
1803 		}
1804 
Domain_GetAssemblies(long id)1805 		internal long[] Domain_GetAssemblies (long id) {
1806 			var res = SendReceive (CommandSet.APPDOMAIN, (int)CmdAppDomain.GET_ASSEMBLIES, new PacketWriter ().WriteId (id));
1807 			int count = res.ReadInt ();
1808 			long[] assemblies = new long [count];
1809 			for (int i = 0; i < count; ++i)
1810 				assemblies [i] = res.ReadId ();
1811 			return assemblies;
1812 		}
1813 
Domain_GetEntryAssembly(long id)1814 		internal long Domain_GetEntryAssembly (long id) {
1815 			return SendReceive (CommandSet.APPDOMAIN, (int)CmdAppDomain.GET_ENTRY_ASSEMBLY, new PacketWriter ().WriteId (id)).ReadId ();
1816 		}
1817 
Domain_GetCorlib(long id)1818 		internal long Domain_GetCorlib (long id) {
1819 			return SendReceive (CommandSet.APPDOMAIN, (int)CmdAppDomain.GET_CORLIB, new PacketWriter ().WriteId (id)).ReadId ();
1820 		}
1821 
Domain_CreateString(long id, string s)1822 		internal long Domain_CreateString (long id, string s) {
1823 			return SendReceive (CommandSet.APPDOMAIN, (int)CmdAppDomain.CREATE_STRING, new PacketWriter ().WriteId (id).WriteString (s)).ReadId ();
1824 		}
1825 
Domain_CreateBoxedValue(long id, long type_id, ValueImpl v)1826 		internal long Domain_CreateBoxedValue (long id, long type_id, ValueImpl v) {
1827 			return SendReceive (CommandSet.APPDOMAIN, (int)CmdAppDomain.CREATE_BOXED_VALUE, new PacketWriter ().WriteId (id).WriteId (type_id).WriteValue (v)).ReadId ();
1828 		}
1829 
1830 		/*
1831 		 * METHOD
1832 		 */
1833 
Method_GetName(long id)1834 		internal string Method_GetName (long id) {
1835 			return SendReceive (CommandSet.METHOD, (int)CmdMethod.GET_NAME, new PacketWriter ().WriteId (id)).ReadString ();
1836 		}
1837 
Method_GetDeclaringType(long id)1838 		internal long Method_GetDeclaringType (long id) {
1839 			return SendReceive (CommandSet.METHOD, (int)CmdMethod.GET_DECLARING_TYPE, new PacketWriter ().WriteId (id)).ReadId ();
1840 		}
1841 
Method_GetDebugInfo(long id)1842 		internal DebugInfo Method_GetDebugInfo (long id) {
1843 			var res = SendReceive (CommandSet.METHOD, (int)CmdMethod.GET_DEBUG_INFO, new PacketWriter ().WriteId (id));
1844 
1845 			DebugInfo info = new DebugInfo ();
1846 			info.max_il_offset = res.ReadInt ();
1847 
1848 			SourceInfo[] sources = null;
1849 			if (Version.AtLeast (2, 13)) {
1850 				int n = res.ReadInt ();
1851 				sources = new SourceInfo [n];
1852 				for (int i = 0; i < n; ++i) {
1853 					sources [i].source_file = res.ReadString ();
1854 					if (Version.AtLeast (2, 14)) {
1855 						sources [i].hash = new byte [16];
1856 						for (int j = 0; j < 16; ++j)
1857 							sources [i].hash [j] = (byte)res.ReadByte ();
1858 					}
1859 				}
1860 			} else {
1861 				sources = new SourceInfo [1];
1862 				sources [0].source_file = res.ReadString ();
1863 			}
1864 
1865 			int n_il_offsets = res.ReadInt ();
1866 			info.il_offsets = new int [n_il_offsets];
1867 			info.line_numbers = new int [n_il_offsets];
1868 			info.source_files = new SourceInfo [n_il_offsets];
1869 			info.column_numbers = new int [n_il_offsets];
1870 			info.end_line_numbers = new int [n_il_offsets];
1871 			info.end_column_numbers = new int [n_il_offsets];
1872 			for (int i = 0; i < n_il_offsets; ++i) {
1873 				info.il_offsets [i] = res.ReadInt ();
1874 				info.line_numbers [i] = res.ReadInt ();
1875 				if (Version.AtLeast (2, 12)) {
1876 					int idx = res.ReadInt ();
1877 					info.source_files [i] = idx >= 0 ? sources [idx] : default (SourceInfo);
1878 				} else {
1879 					info.source_files [i] = sources [0];
1880 				}
1881 				if (Version.AtLeast (2, 19))
1882 					info.column_numbers [i] = res.ReadInt ();
1883 				else
1884 					info.column_numbers [i] = 0;
1885 				if (Version.AtLeast (2, 32)) {
1886 					info.end_line_numbers [i] = res.ReadInt ();
1887 					info.end_column_numbers [i] = res.ReadInt ();
1888 				} else {
1889 					info.end_column_numbers [i] = -1;
1890 					info.end_column_numbers [i] = -1;
1891 				}
1892 			}
1893 
1894 			return info;
1895 		}
1896 
Method_GetParamInfo(long id)1897 		internal ParamInfo Method_GetParamInfo (long id) {
1898 			var res = SendReceive (CommandSet.METHOD, (int)CmdMethod.GET_PARAM_INFO, new PacketWriter ().WriteId (id));
1899 
1900 			ParamInfo info = new ParamInfo ();
1901 			info.call_conv = res.ReadInt ();
1902 			info.param_count = res.ReadInt ();
1903 			info.generic_param_count = res.ReadInt ();
1904 			info.ret_type = res.ReadId ();
1905 			info.param_types = new long [info.param_count];
1906 			for (int i = 0; i < info.param_count; ++i)
1907 				info.param_types [i] = res.ReadId ();
1908 			info.param_names = new string [info.param_count];
1909 			for (int i = 0; i < info.param_count; ++i)
1910 				info.param_names [i] = res.ReadString ();
1911 
1912 			return info;
1913 		}
1914 
Method_GetLocalsInfo(long id)1915 		internal LocalsInfo Method_GetLocalsInfo (long id) {
1916 			var res = SendReceive (CommandSet.METHOD, (int)CmdMethod.GET_LOCALS_INFO, new PacketWriter ().WriteId (id));
1917 
1918 			LocalsInfo info = new LocalsInfo ();
1919 
1920 			if (Version.AtLeast (2, 43)) {
1921 				int nscopes = res.ReadInt ();
1922 				info.scopes_start = new int [nscopes];
1923 				info.scopes_end = new int [nscopes];
1924 				int last_start = 0;
1925 				for (int i = 0; i < nscopes; ++i) {
1926 					info.scopes_start [i] = last_start + res.ReadInt ();
1927 					info.scopes_end [i] = info.scopes_start [i] + res.ReadInt ();
1928 					last_start = info.scopes_start [i];
1929 				}
1930 			}
1931 
1932 			int nlocals = res.ReadInt ();
1933 			info.types = new long [nlocals];
1934 			for (int i = 0; i < nlocals; ++i)
1935 				info.types [i] = res.ReadId ();
1936 			info.names = new string [nlocals];
1937 			for (int i = 0; i < nlocals; ++i)
1938 				info.names [i] = res.ReadString ();
1939 			info.live_range_start = new int [nlocals];
1940 			info.live_range_end = new int [nlocals];
1941 			for (int i = 0; i < nlocals; ++i) {
1942 				info.live_range_start [i] = res.ReadInt ();
1943 				info.live_range_end [i] = res.ReadInt ();
1944 			}
1945 
1946 			return info;
1947 		}
1948 
Method_GetInfo(long id)1949 		internal MethodInfo Method_GetInfo (long id) {
1950 			var res = SendReceive (CommandSet.METHOD, (int)CmdMethod.GET_INFO, new PacketWriter ().WriteId (id));
1951 
1952 			MethodInfo info = new MethodInfo ();
1953 			info.attributes = res.ReadInt ();
1954 			info.iattributes = res.ReadInt ();
1955 			info.token = res.ReadInt ();
1956 			if (Version.AtLeast (2, 12)) {
1957 				int attrs = res.ReadByte ();
1958 				if ((attrs & (1 << 0)) != 0)
1959 					info.is_gmd = true;
1960 				if ((attrs & (1 << 1)) != 0)
1961 					info.is_generic_method = true;
1962 				info.gmd = res.ReadId ();
1963 				if (Version.AtLeast (2, 15)) {
1964 					if (info.is_generic_method) {
1965 						int n = res.ReadInt ();
1966 						info.type_args = res.ReadIds (n);
1967 					}
1968 				}
1969 			}
1970 			return info;
1971 		}
1972 
Method_GetBody(long id)1973 		internal MethodBodyInfo Method_GetBody (long id) {
1974 			var res = SendReceive (CommandSet.METHOD, (int)CmdMethod.GET_BODY, new PacketWriter ().WriteId (id));
1975 
1976 			MethodBodyInfo info = new MethodBodyInfo ();
1977 			info.il = new byte [res.ReadInt ()];
1978 			for (int i = 0; i < info.il.Length; ++i)
1979 				info.il [i] = (byte)res.ReadByte ();
1980 
1981 			if (Version.AtLeast (2, 18)) {
1982 				info.clauses = new ExceptionClauseInfo [res.ReadInt ()];
1983 
1984 				for (int i = 0; i < info.clauses.Length; ++i) {
1985 					var clause = new ExceptionClauseInfo {
1986 						flags = (ExceptionClauseFlags) res.ReadInt (),
1987 						try_offset = res.ReadInt (),
1988 						try_length = res.ReadInt (),
1989 						handler_offset = res.ReadInt (),
1990 						handler_length = res.ReadInt (),
1991 					};
1992 
1993 					if (clause.flags == ExceptionClauseFlags.None)
1994 						clause.catch_type_id = res.ReadId ();
1995 					else if (clause.flags == ExceptionClauseFlags.Filter)
1996 						clause.filter_offset = res.ReadInt ();
1997 
1998 					info.clauses [i] = clause;
1999 				}
2000 			} else
2001 				info.clauses = new ExceptionClauseInfo [0];
2002 
2003 			return info;
2004 		}
2005 
Method_ResolveToken(long id, int token)2006 		internal ResolvedToken Method_ResolveToken (long id, int token) {
2007 			var res = SendReceive (CommandSet.METHOD, (int)CmdMethod.RESOLVE_TOKEN, new PacketWriter ().WriteId (id).WriteInt (token));
2008 
2009 			TokenType type = (TokenType)res.ReadByte ();
2010 			switch (type) {
2011 			case TokenType.STRING:
2012 				return new ResolvedToken () { Type = type, Str = res.ReadString () };
2013 			case TokenType.TYPE:
2014 			case TokenType.METHOD:
2015 			case TokenType.FIELD:
2016 				return new ResolvedToken () { Type = type, Id = res.ReadId () };
2017 			case TokenType.UNKNOWN:
2018 				return new ResolvedToken () { Type = type };
2019 			default:
2020 				throw new NotImplementedException ();
2021 			}
2022 		}
2023 
Method_GetCustomAttributes(long id, long attr_type_id, bool inherit)2024 		internal CattrInfo[] Method_GetCustomAttributes (long id, long attr_type_id, bool inherit) {
2025 			PacketReader r = SendReceive (CommandSet.METHOD, (int)CmdMethod.GET_CATTRS, new PacketWriter ().WriteId (id).WriteId (attr_type_id));
2026 			return ReadCattrs (r);
2027 		}
2028 
Method_MakeGenericMethod(long id, long[] args)2029 		internal long Method_MakeGenericMethod (long id, long[] args) {
2030 			PacketReader r = SendReceive (CommandSet.METHOD, (int)CmdMethod.MAKE_GENERIC_METHOD, new PacketWriter ().WriteId (id).WriteInt (args.Length).WriteIds (args));
2031 			return r.ReadId ();
2032 		}
2033 
2034 		/*
2035 		 * THREAD
2036 		 */
2037 
Thread_GetName(long id)2038 		internal string Thread_GetName (long id) {
2039 			return SendReceive (CommandSet.THREAD, (int)CmdThread.GET_NAME, new PacketWriter ().WriteId (id)).ReadString ();
2040 		}
2041 
Thread_GetFrameInfo(long id, int start_frame, int length, Action<FrameInfo[]> resultCallaback)2042 		internal void Thread_GetFrameInfo (long id, int start_frame, int length, Action<FrameInfo[]> resultCallaback) {
2043 			Send (CommandSet.THREAD, (int)CmdThread.GET_FRAME_INFO, new PacketWriter ().WriteId (id).WriteInt (start_frame).WriteInt (length), (res) => {
2044 				int count = res.ReadInt ();
2045 				var frames = new FrameInfo[count];
2046 				for (int i = 0; i < count; ++i) {
2047 					var f = new FrameInfo ();
2048 					f.id = res.ReadInt ();
2049 					f.method = res.ReadId ();
2050 					f.il_offset = res.ReadInt ();
2051 					f.flags = (StackFrameFlags)res.ReadByte ();
2052 					frames [i] = f;
2053 				}
2054 				resultCallaback (frames);
2055 			}, 1);
2056 		}
2057 
Thread_GetState(long id)2058 		internal int Thread_GetState (long id) {
2059 			return SendReceive (CommandSet.THREAD, (int)CmdThread.GET_STATE, new PacketWriter ().WriteId (id)).ReadInt ();
2060 		}
2061 
Thread_GetInfo(long id)2062 		internal ThreadInfo Thread_GetInfo (long id) {
2063 			PacketReader r = SendReceive (CommandSet.THREAD, (int)CmdThread.GET_INFO, new PacketWriter ().WriteId (id));
2064 
2065 			ThreadInfo res = new ThreadInfo () { is_thread_pool = r.ReadByte () > 0 ? true : false };
2066 
2067 			return res;
2068 		}
2069 
Thread_GetId(long id)2070 		internal long Thread_GetId (long id) {
2071 			return SendReceive (CommandSet.THREAD, (int)CmdThread.GET_ID, new PacketWriter ().WriteId (id)).ReadLong ();
2072 		}
2073 
Thread_GetTID(long id)2074 		internal long Thread_GetTID (long id) {
2075 			return SendReceive (CommandSet.THREAD, (int)CmdThread.GET_TID, new PacketWriter ().WriteId (id)).ReadLong ();
2076 		}
2077 
Thread_SetIP(long id, long method_id, long il_offset)2078 		internal void Thread_SetIP (long id, long method_id, long il_offset) {
2079 			SendReceive (CommandSet.THREAD, (int)CmdThread.SET_IP, new PacketWriter ().WriteId (id).WriteId (method_id).WriteLong (il_offset));
2080 		}
2081 
2082 		/*
2083 		 * MODULE
2084 		 */
2085 
Module_GetInfo(long id)2086 		internal ModuleInfo Module_GetInfo (long id) {
2087 			PacketReader r = SendReceive (CommandSet.MODULE, (int)CmdModule.GET_INFO, new PacketWriter ().WriteId (id));
2088 			ModuleInfo info = new ModuleInfo { Name = r.ReadString (), ScopeName = r.ReadString (), FQName = r.ReadString (), Guid = r.ReadString (), Assembly = r.ReadId () };
2089 			return info;
2090 		}
2091 
2092 		/*
2093 		 * ASSEMBLY
2094 		 */
2095 
Assembly_GetLocation(long id)2096 		internal string Assembly_GetLocation (long id) {
2097 			return SendReceive (CommandSet.ASSEMBLY, (int)CmdAssembly.GET_LOCATION, new PacketWriter ().WriteId (id)).ReadString ();
2098 		}
2099 
Assembly_GetEntryPoint(long id)2100 		internal long Assembly_GetEntryPoint (long id) {
2101 			return SendReceive (CommandSet.ASSEMBLY, (int)CmdAssembly.GET_ENTRY_POINT, new PacketWriter ().WriteId (id)).ReadId ();
2102 		}
2103 
Assembly_GetManifestModule(long id)2104 		internal long Assembly_GetManifestModule (long id) {
2105 			return SendReceive (CommandSet.ASSEMBLY, (int)CmdAssembly.GET_MANIFEST_MODULE, new PacketWriter ().WriteId (id)).ReadId ();
2106 		}
2107 
Assembly_GetObject(long id)2108 		internal long Assembly_GetObject (long id) {
2109 			return SendReceive (CommandSet.ASSEMBLY, (int)CmdAssembly.GET_OBJECT, new PacketWriter ().WriteId (id)).ReadId ();
2110 		}
2111 
Assembly_GetType(long id, string name, bool ignoreCase)2112 		internal long Assembly_GetType (long id, string name, bool ignoreCase) {
2113 			return SendReceive (CommandSet.ASSEMBLY, (int)CmdAssembly.GET_TYPE, new PacketWriter ().WriteId (id).WriteString (name).WriteBool (ignoreCase)).ReadId ();
2114 		}
2115 
Assembly_GetName(long id)2116 		internal string Assembly_GetName (long id) {
2117 			return SendReceive (CommandSet.ASSEMBLY, (int)CmdAssembly.GET_NAME, new PacketWriter ().WriteId (id)).ReadString ();
2118 		}
2119 
Assembly_GetIdDomain(long id)2120 		internal long Assembly_GetIdDomain (long id) {
2121 			return SendReceive (CommandSet.ASSEMBLY, (int)CmdAssembly.GET_DOMAIN, new PacketWriter ().WriteId (id)).ReadId ();
2122 		}
2123 
2124 		/*
2125 		 * TYPE
2126 		 */
2127 
Type_GetInfo(long id)2128 		internal TypeInfo Type_GetInfo (long id) {
2129 			PacketReader r = SendReceive (CommandSet.TYPE, (int)CmdType.GET_INFO, new PacketWriter ().WriteId (id));
2130 			TypeInfo res = new TypeInfo ();
2131 
2132 			res.ns = r.ReadString ();
2133 			res.name = r.ReadString ();
2134 			res.full_name = r.ReadString ();
2135 			res.assembly = r.ReadId ();
2136 			res.module = r.ReadId ();
2137 			res.base_type = r.ReadId ();
2138 			res.element_type = r.ReadId ();
2139 			res.token = r.ReadInt ();
2140 			res.rank = r.ReadByte ();
2141 			res.attributes = r.ReadInt ();
2142 			int b = r.ReadByte ();
2143 			res.is_byref = (b & 1) != 0;
2144 			res.is_pointer = (b & 2) != 0;
2145 			res.is_primitive = (b & 4) != 0;
2146 			res.is_valuetype = (b & 8) != 0;
2147 			res.is_enum = (b & 16) != 0;
2148 			res.is_gtd = (b & 32) != 0;
2149 			res.is_generic_type = (b & 64) != 0;
2150 
2151 			int nested_len = r.ReadInt ();
2152 			res.nested = new long [nested_len];
2153 			for (int i = 0; i < nested_len; ++i)
2154 				res.nested [i] = r.ReadId ();
2155 
2156 			if (Version.AtLeast (2, 12))
2157 				res.gtd = r.ReadId ();
2158 			if (Version.AtLeast (2, 15) && res.is_generic_type) {
2159 				int n = r.ReadInt ();
2160 				res.type_args = r.ReadIds (n);
2161 			}
2162 
2163 			return res;
2164 		}
2165 
Type_GetMethods(long id)2166 		internal long[] Type_GetMethods (long id) {
2167 			PacketReader r = SendReceive (CommandSet.TYPE, (int)CmdType.GET_METHODS, new PacketWriter ().WriteId (id));
2168 
2169 			int n = r.ReadInt ();
2170 			long[] res = new long [n];
2171 			for (int i = 0; i < n; ++i)
2172 				res [i] = r.ReadId ();
2173 			return res;
2174 		}
2175 
Type_GetFields(long id, out string[] names, out long[] types, out int[] attrs)2176 		internal long[] Type_GetFields (long id, out string[] names, out long[] types, out int[] attrs) {
2177 			PacketReader r = SendReceive (CommandSet.TYPE, (int)CmdType.GET_FIELDS, new PacketWriter ().WriteId (id));
2178 
2179 			int n = r.ReadInt ();
2180 			long[] res = new long [n];
2181 			names = new string [n];
2182 			types = new long [n];
2183 			attrs = new int [n];
2184 			for (int i = 0; i < n; ++i) {
2185 				res [i] = r.ReadId ();
2186 				names [i] = r.ReadString ();
2187 				types [i] = r.ReadId ();
2188 				attrs [i] = r.ReadInt ();
2189 			}
2190 			return res;
2191 		}
2192 
Type_GetProperties(long id)2193 		internal PropInfo[] Type_GetProperties (long id) {
2194 			PacketReader r = SendReceive (CommandSet.TYPE, (int)CmdType.GET_PROPERTIES, new PacketWriter ().WriteId (id));
2195 
2196 			int n = r.ReadInt ();
2197 			PropInfo[] res = new PropInfo [n];
2198 			for (int i = 0; i < n; ++i) {
2199 				res [i] = new PropInfo ();
2200 				res [i].id = r.ReadId ();
2201 				res [i].name = r.ReadString ();
2202 				res [i].get_method = r.ReadId ();
2203 				res [i].set_method = r.ReadId ();
2204 				res [i].attrs = r.ReadInt ();
2205 			}
2206 
2207 			return res;
2208 		}
2209 
Type_GetObject(long id)2210 		internal long Type_GetObject (long id) {
2211 			return SendReceive (CommandSet.TYPE, (int)CmdType.GET_OBJECT, new PacketWriter ().WriteId (id)).ReadId ();
2212 		}
2213 
Type_GetValues(long id, long[] fields, long thread_id)2214 		internal ValueImpl[] Type_GetValues (long id, long[] fields, long thread_id) {
2215 			int len = fields.Length;
2216 			PacketReader r;
2217 			if (thread_id != 0 && Version.AtLeast(2, 3))
2218 				r = SendReceive (CommandSet.TYPE, (int)CmdType.GET_VALUES_2, new PacketWriter ().WriteId (id).WriteId (thread_id).WriteInt (len).WriteIds (fields));
2219 			else
2220 				r = SendReceive (CommandSet.TYPE, (int)CmdType.GET_VALUES, new PacketWriter ().WriteId (id).WriteInt (len).WriteIds (fields));
2221 
2222 			ValueImpl[] res = new ValueImpl [len];
2223 			for (int i = 0; i < len; ++i)
2224 				res [i] = r.ReadValue ();
2225 			return res;
2226 		}
2227 
Type_SetValues(long id, long[] fields, ValueImpl[] values)2228 		internal void Type_SetValues (long id, long[] fields, ValueImpl[] values) {
2229 			SendReceive (CommandSet.TYPE, (int)CmdType.SET_VALUES, new PacketWriter ().WriteId (id).WriteInt (fields.Length).WriteIds (fields).WriteValues (values));
2230 		}
2231 
Type_GetSourceFiles(long id, bool return_full_paths)2232 		internal string[] Type_GetSourceFiles (long id, bool return_full_paths) {
2233 			var r = SendReceive (CommandSet.TYPE, return_full_paths ? (int)CmdType.GET_SOURCE_FILES_2 : (int)CmdType.GET_SOURCE_FILES, new PacketWriter ().WriteId (id));
2234 			int len = r.ReadInt ();
2235 			string[] res = new string [len];
2236 			for (int i = 0; i < len; ++i)
2237 				res [i] = r.ReadString ();
2238 			return res;
2239 		}
2240 
Type_IsAssignableFrom(long id, long c_id)2241 		internal bool Type_IsAssignableFrom (long id, long c_id) {
2242 			return SendReceive (CommandSet.TYPE, (int)CmdType.IS_ASSIGNABLE_FROM, new PacketWriter ().WriteId (id).WriteId (c_id)).ReadByte () > 0;
2243 		}
2244 
Type_GetCustomAttributes(long id, long attr_type_id, bool inherit)2245 		internal CattrInfo[] Type_GetCustomAttributes (long id, long attr_type_id, bool inherit) {
2246 			PacketReader r = SendReceive (CommandSet.TYPE, (int)CmdType.GET_CATTRS, new PacketWriter ().WriteId (id).WriteId (attr_type_id));
2247 			return ReadCattrs (r);
2248 		}
2249 
Type_GetFieldCustomAttributes(long id, long field_id, long attr_type_id, bool inherit)2250 		internal CattrInfo[] Type_GetFieldCustomAttributes (long id, long field_id, long attr_type_id, bool inherit) {
2251 			PacketReader r = SendReceive (CommandSet.TYPE, (int)CmdType.GET_FIELD_CATTRS, new PacketWriter ().WriteId (id).WriteId (field_id).WriteId (attr_type_id));
2252 			return ReadCattrs (r);
2253 		}
2254 
Type_GetPropertyCustomAttributes(long id, long field_id, long attr_type_id, bool inherit)2255 		internal CattrInfo[] Type_GetPropertyCustomAttributes (long id, long field_id, long attr_type_id, bool inherit) {
2256 			PacketReader r = SendReceive (CommandSet.TYPE, (int)CmdType.GET_PROPERTY_CATTRS, new PacketWriter ().WriteId (id).WriteId (field_id).WriteId (attr_type_id));
2257 			return ReadCattrs (r);
2258 		}
2259 
Type_GetMethodsByNameFlags(long id, string name, int flags, bool ignoreCase)2260 		public long[] Type_GetMethodsByNameFlags (long id, string name, int flags, bool ignoreCase) {
2261 			flags |= ignoreCase ? (int)BindingFlagsExtensions.BINDING_FLAGS_IGNORE_CASE : 0;
2262 			PacketReader r = SendReceive (CommandSet.TYPE, (int)CmdType.CMD_TYPE_GET_METHODS_BY_NAME_FLAGS, new PacketWriter ().WriteId (id).WriteString (name).WriteInt (flags));
2263 			int len = r.ReadInt ();
2264 			long[] res = new long [len];
2265 			for (int i = 0; i < len; ++i)
2266 				res [i] = r.ReadId ();
2267 			return res;
2268 		}
2269 
Type_GetInterfaces(long id)2270 		internal long[] Type_GetInterfaces (long id) {
2271 			PacketReader r = SendReceive (CommandSet.TYPE, (int)CmdType.GET_INTERFACES, new PacketWriter ().WriteId (id));
2272 			int len = r.ReadInt ();
2273 			return r.ReadIds (len);
2274 		}
2275 
Type_GetInterfaceMap(long id, long[] ids)2276 		internal IfaceMapInfo[] Type_GetInterfaceMap (long id, long[] ids) {
2277 			PacketReader r = SendReceive (CommandSet.TYPE, (int)CmdType.GET_INTERFACE_MAP, new PacketWriter ().WriteId (id).WriteInt (ids.Length).WriteIds (ids));
2278 			var res = new IfaceMapInfo [ids.Length];
2279 			for (int i = 0; i < ids.Length; ++i) {
2280 				int n = r.ReadInt ();
2281 
2282 				res [i].iface_id = ids [i];
2283 				res [i].iface_methods = r.ReadIds (n);
2284 				res [i].target_methods = r.ReadIds (n);
2285 			}
2286 
2287 			return res;
2288 		}
2289 
Type_IsInitialized(long id)2290 		internal bool Type_IsInitialized (long id) {
2291 			PacketReader r = SendReceive (CommandSet.TYPE, (int)CmdType.IS_INITIALIZED, new PacketWriter ().WriteId (id));
2292 			return r.ReadInt () == 1;
2293 		}
2294 
Type_CreateInstance(long id)2295 		internal long Type_CreateInstance (long id) {
2296 			PacketReader r = SendReceive (CommandSet.TYPE, (int)CmdType.CREATE_INSTANCE, new PacketWriter ().WriteId (id));
2297 			return r.ReadId ();
2298 		}
2299 
2300 		/*
2301 		 * FIELD
2302 		 */
2303 
Field_GetInfo(long id)2304 		internal FieldMirrorInfo Field_GetInfo (long id) {
2305 			PacketReader r = SendReceive (CommandSet.FIELD, (int)CmdField.GET_INFO, new PacketWriter ().WriteId (id));
2306 			FieldMirrorInfo info = new FieldMirrorInfo { Name = r.ReadString (), Parent = r.ReadId (), TypeId = r.ReadId (), Attrs = r.ReadInt () };
2307 			return info;
2308 		}
2309 
2310 		/*
2311 		 * EVENTS
2312 		 */
2313 
EnableEvent(EventType etype, SuspendPolicy suspend_policy, List<Modifier> mods)2314 		internal int EnableEvent (EventType etype, SuspendPolicy suspend_policy, List<Modifier> mods) {
2315 			var w = new PacketWriter ().WriteByte ((byte)etype).WriteByte ((byte)suspend_policy);
2316 			if (mods != null) {
2317 				if (mods.Count > 255)
2318 					throw new NotImplementedException ();
2319 				w.WriteByte ((byte)mods.Count);
2320 				foreach (Modifier mod in mods) {
2321 					if (mod is CountModifier) {
2322 						w.WriteByte ((byte)ModifierKind.COUNT);
2323 						w.WriteInt ((mod as CountModifier).Count);
2324 					} else if (mod is LocationModifier) {
2325 						w.WriteByte ((byte)ModifierKind.LOCATION_ONLY);
2326 						w.WriteId ((mod as LocationModifier).Method);
2327 						w.WriteLong ((mod as LocationModifier).Location);
2328 					} else if (mod is StepModifier) {
2329 						w.WriteByte ((byte)ModifierKind.STEP);
2330 						w.WriteId ((mod as StepModifier).Thread);
2331 						w.WriteInt ((mod as StepModifier).Size);
2332 						w.WriteInt ((mod as StepModifier).Depth);
2333 						if (Version.AtLeast (2, 16))
2334 							w.WriteInt ((mod as StepModifier).Filter);
2335 					} else if (mod is ThreadModifier) {
2336 						w.WriteByte ((byte)ModifierKind.THREAD_ONLY);
2337 						w.WriteId ((mod as ThreadModifier).Thread);
2338 					} else if (mod is ExceptionModifier) {
2339 						var em = mod as ExceptionModifier;
2340 						w.WriteByte ((byte)ModifierKind.EXCEPTION_ONLY);
2341 						w.WriteId (em.Type);
2342 						if (Version.MajorVersion > 2 || Version.MinorVersion > 0) {
2343 							/* This is only supported in protocol version 2.1 */
2344 							w.WriteBool (em.Caught);
2345 							w.WriteBool (em.Uncaught);
2346 						} else if (!em.Caught || !em.Uncaught) {
2347 							throw new NotSupportedException ("This request is not supported by the protocol version implemented by the debuggee.");
2348 						}
2349 						if (Version.MajorVersion > 2 || Version.MinorVersion > 24) {
2350 							w.WriteBool (em.Subclasses);
2351 						} else if (!em.Subclasses) {
2352 							throw new NotSupportedException ("This request is not supported by the protocol version implemented by the debuggee.");
2353 						}
2354 					} else if (mod is AssemblyModifier) {
2355 						w.WriteByte ((byte)ModifierKind.ASSEMBLY_ONLY);
2356 						var amod = (mod as AssemblyModifier);
2357 						w.WriteInt (amod.Assemblies.Length);
2358 						foreach (var id in amod.Assemblies)
2359 							w.WriteId (id);
2360 					} else if (mod is SourceFileModifier) {
2361 						w.WriteByte ((byte)ModifierKind.SOURCE_FILE_ONLY);
2362 						var smod = (mod as SourceFileModifier);
2363 						w.WriteInt (smod.SourceFiles.Length);
2364 						foreach (var s in smod.SourceFiles)
2365 							w.WriteString (s);
2366 					} else if (mod is TypeNameModifier) {
2367 						w.WriteByte ((byte)ModifierKind.TYPE_NAME_ONLY);
2368 						var tmod = (mod as TypeNameModifier);
2369 						w.WriteInt (tmod.TypeNames.Length);
2370 						foreach (var s in tmod.TypeNames)
2371 							w.WriteString (s);
2372 					} else {
2373 						throw new NotImplementedException ();
2374 					}
2375 				}
2376 			} else {
2377 				w.WriteByte (0);
2378 			}
2379 			return SendReceive (CommandSet.EVENT_REQUEST, (int)CmdEventRequest.SET, w).ReadInt ();
2380 		}
2381 
ClearEventRequest(EventType etype, int req_id)2382 		internal void ClearEventRequest (EventType etype, int req_id) {
2383 			SendReceive (CommandSet.EVENT_REQUEST, (int)CmdEventRequest.CLEAR, new PacketWriter ().WriteByte ((byte)etype).WriteInt (req_id));
2384 		}
2385 
ClearAllBreakpoints()2386 		internal void ClearAllBreakpoints () {
2387 			SendReceive (CommandSet.EVENT_REQUEST, (int)CmdEventRequest.CLEAR_ALL_BREAKPOINTS, new PacketWriter ());
2388 		}
2389 
2390 		/*
2391 		 * STACK FRAME
2392 		 */
StackFrame_GetThis(long thread_id, long id)2393 		internal ValueImpl StackFrame_GetThis (long thread_id, long id) {
2394 			PacketReader r = SendReceive (CommandSet.STACK_FRAME, (int)CmdStackFrame.GET_THIS, new PacketWriter ().WriteId (thread_id).WriteId (id));
2395 			return r.ReadValue ();
2396 		}
2397 
StackFrame_GetValues(long thread_id, long id, int[] pos)2398 		internal ValueImpl[] StackFrame_GetValues (long thread_id, long id, int[] pos) {
2399 			/* pos < 0 -> argument at pos (-pos) - 1 */
2400 			/* pos >= 0 -> local at pos */
2401 			int len = pos.Length;
2402 			PacketReader r = SendReceive (CommandSet.STACK_FRAME, (int)CmdStackFrame.GET_VALUES, new PacketWriter ().WriteId (thread_id).WriteId (id).WriteInt (len).WriteInts (pos));
2403 
2404 			ValueImpl[] res = new ValueImpl [len];
2405 			for (int i = 0; i < len; ++i)
2406 				res [i] = r.ReadValue ();
2407 			return res;
2408 		}
2409 
StackFrame_SetValues(long thread_id, long id, int[] pos, ValueImpl[] values)2410 		internal void StackFrame_SetValues (long thread_id, long id, int[] pos, ValueImpl[] values) {
2411 			/* pos < 0 -> argument at pos (-pos) - 1 */
2412 			/* pos >= 0 -> local at pos */
2413 			int len = pos.Length;
2414 			SendReceive (CommandSet.STACK_FRAME, (int)CmdStackFrame.SET_VALUES, new PacketWriter ().WriteId (thread_id).WriteId (id).WriteInt (len).WriteInts (pos).WriteValues (values));
2415 		}
2416 
StackFrame_GetDomain(long thread_id, long id)2417 		internal long StackFrame_GetDomain (long thread_id, long id) {
2418 			return SendReceive (CommandSet.STACK_FRAME, (int)CmdStackFrame.GET_DOMAIN, new PacketWriter ().WriteId (thread_id).WriteId (id)).ReadId ();
2419 		}
2420 
StackFrame_SetThis(long thread_id, long id, ValueImpl value)2421 		internal void StackFrame_SetThis (long thread_id, long id, ValueImpl value) {
2422 			SendReceive (CommandSet.STACK_FRAME, (int)CmdStackFrame.SET_THIS, new PacketWriter ().WriteId (thread_id).WriteId (id).WriteValue (value));
2423 		}
2424 
2425 		/*
2426 		 * ARRAYS
2427 		 */
Array_GetLength(long id, out int rank, out int[] lower_bounds)2428 		internal int[] Array_GetLength (long id, out int rank, out int[] lower_bounds) {
2429 			var r = SendReceive (CommandSet.ARRAY_REF, (int)CmdArrayRef.GET_LENGTH, new PacketWriter ().WriteId (id));
2430 			rank = r.ReadInt ();
2431 			int[] res = new int [rank];
2432 			lower_bounds = new int [rank];
2433 			for (int i = 0; i < rank; ++i) {
2434 				res [i] = r.ReadInt ();
2435 				lower_bounds [i] = r.ReadInt ();
2436 			}
2437 			return res;
2438 		}
2439 
Array_GetValues(long id, int index, int len)2440 		internal ValueImpl[] Array_GetValues (long id, int index, int len) {
2441 			var r = SendReceive (CommandSet.ARRAY_REF, (int)CmdArrayRef.GET_VALUES, new PacketWriter ().WriteId (id).WriteInt (index).WriteInt (len));
2442 			ValueImpl[] res = new ValueImpl [len];
2443 			for (int i = 0; i < len; ++i)
2444 				res [i] = r.ReadValue ();
2445 			return res;
2446 		}
2447 
Array_SetValues(long id, int index, ValueImpl[] values)2448 		internal void Array_SetValues (long id, int index, ValueImpl[] values) {
2449 			SendReceive (CommandSet.ARRAY_REF, (int)CmdArrayRef.SET_VALUES, new PacketWriter ().WriteId (id).WriteInt (index).WriteInt (values.Length).WriteValues (values));
2450 		}
2451 
2452 		/*
2453 		 * STRINGS
2454 		 */
String_GetValue(long id)2455 		internal string String_GetValue (long id) {
2456 			var r = SendReceive (CommandSet.STRING_REF, (int)CmdStringRef.GET_VALUE, new PacketWriter ().WriteId (id));
2457 
2458 			bool is_utf16 = false;
2459 			if (Version.AtLeast (2, 41))
2460 				is_utf16 = r.ReadByte () == 1;
2461 
2462 			if (is_utf16)
2463 				return r.ReadUTF16String ();
2464 			else
2465 				return r.ReadString ();
2466 		}
2467 
String_GetLength(long id)2468 		internal int String_GetLength (long id) {
2469 			return (int)SendReceive (CommandSet.STRING_REF, (int)CmdStringRef.GET_LENGTH, new PacketWriter ().WriteId (id)).ReadLong ();
2470 		}
2471 
String_GetChars(long id, int index, int length)2472 		internal char[] String_GetChars (long id, int index, int length) {
2473 			var r = SendReceive (CommandSet.STRING_REF, (int)CmdStringRef.GET_CHARS, new PacketWriter ().WriteId (id).WriteLong (index).WriteLong (length));
2474 			var res = new char [length];
2475 			for (int i = 0; i < length; ++i)
2476 				res [i] = (char)r.ReadShort ();
2477 			return res;
2478 		}
2479 
2480 		/*
2481 		 * OBJECTS
2482 		 */
Object_GetType(long id)2483 		internal long Object_GetType (long id) {
2484 			return SendReceive (CommandSet.OBJECT_REF, (int)CmdObjectRef.GET_TYPE, new PacketWriter ().WriteId (id)).ReadId ();
2485 		}
2486 
Object_GetDomain(long id)2487 		internal long Object_GetDomain (long id) {
2488 			return SendReceive (CommandSet.OBJECT_REF, (int)CmdObjectRef.GET_DOMAIN, new PacketWriter ().WriteId (id)).ReadId ();
2489 		}
2490 
Object_GetValues(long id, long[] fields)2491 		internal ValueImpl[] Object_GetValues (long id, long[] fields) {
2492 			int len = fields.Length;
2493 			PacketReader r = SendReceive (CommandSet.OBJECT_REF, (int)CmdObjectRef.GET_VALUES, new PacketWriter ().WriteId (id).WriteInt (len).WriteIds (fields));
2494 
2495 			ValueImpl[] res = new ValueImpl [len];
2496 			for (int i = 0; i < len; ++i)
2497 				res [i] = r.ReadValue ();
2498 			return res;
2499 		}
2500 
Object_SetValues(long id, long[] fields, ValueImpl[] values)2501 		internal void Object_SetValues (long id, long[] fields, ValueImpl[] values) {
2502 			SendReceive (CommandSet.OBJECT_REF, (int)CmdObjectRef.SET_VALUES, new PacketWriter ().WriteId (id).WriteInt (fields.Length).WriteIds (fields).WriteValues (values));
2503 		}
2504 
Object_IsCollected(long id)2505 		internal bool Object_IsCollected (long id) {
2506 			return SendReceive (CommandSet.OBJECT_REF, (int)CmdObjectRef.IS_COLLECTED, new PacketWriter ().WriteId (id)).ReadInt () == 1;
2507 		}
2508 
Object_GetAddress(long id)2509 		internal long Object_GetAddress (long id) {
2510 			return SendReceive (CommandSet.OBJECT_REF, (int)CmdObjectRef.GET_ADDRESS, new PacketWriter ().WriteId (id)).ReadLong ();
2511 		}
2512 
Object_GetInfo(long id)2513 		internal ObjectRefInfo Object_GetInfo (long id) {
2514 			ObjectRefInfo res = new ObjectRefInfo ();
2515 			PacketReader r = SendReceive (CommandSet.OBJECT_REF, (int)CmdObjectRef.GET_INFO, new PacketWriter ().WriteId (id));
2516 
2517 			res.type_id = r.ReadId ();
2518 			res.domain_id = r.ReadId ();
2519 			return res;
2520 		}
2521 
ForceDisconnect()2522 		public void ForceDisconnect ()
2523 		{
2524 			closed = true;
2525 			disconnected = true;
2526 			DisconnectedEvent.Set ();
2527 			TransportClose ();
2528 		}
2529 	}
2530 
2531 	class TcpConnection : Connection
2532 	{
2533 		Socket socket;
2534 
TcpConnection(Socket socket)2535 		internal TcpConnection (Socket socket)
2536 		{
2537 			this.socket = socket;
2538 			//socket.SetSocketOption (SocketOptionLevel.IP, SocketOptionName.NoDelay, 1);
2539 		}
2540 
2541 		internal EndPoint EndPoint {
2542 			get {
2543 				return socket.RemoteEndPoint;
2544 			}
2545 		}
2546 
TransportSend(byte[] buf, int buf_offset, int len)2547 		protected override int TransportSend (byte[] buf, int buf_offset, int len)
2548 		{
2549 			return socket.Send (buf, buf_offset, len, SocketFlags.None);
2550 		}
2551 
TransportReceive(byte[] buf, int buf_offset, int len)2552 		protected override int TransportReceive (byte[] buf, int buf_offset, int len)
2553 		{
2554 			return socket.Receive (buf, buf_offset, len, SocketFlags.None);
2555 		}
2556 
TransportSetTimeouts(int send_timeout, int receive_timeout)2557 		protected override void TransportSetTimeouts (int send_timeout, int receive_timeout)
2558 		{
2559 			socket.SendTimeout = send_timeout;
2560 			socket.ReceiveTimeout = receive_timeout;
2561 		}
2562 
TransportClose()2563 		protected override void TransportClose ()
2564 		{
2565 			socket.Close ();
2566 		}
2567 	}
2568 
2569 	/* This is the interface exposed by the debugger towards the debugger agent */
2570 	interface IEventHandler
2571 	{
Events(SuspendPolicy suspend_policy, EventInfo[] events)2572 		void Events (SuspendPolicy suspend_policy, EventInfo[] events);
2573 
VMDisconnect(int req_id, long thread_id, string vm_uri)2574 		void VMDisconnect (int req_id, long thread_id, string vm_uri);
2575 	}
2576 }
2577