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