Last active
July 15, 2019 18:47
-
-
Save lambdageek/cb4408be0ddbb6376404bee33e349b0c to your computer and use it in GitHub Desktop.
debugger-libs Mono.Debugger.Soft vs mono Mono.Debugger.Soft
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| diff -u /Users/alklig/work/debugger-libs/Mono.Debugger.Soft/Mono.Debugger.Soft/ArrayMirror.cs /Users/alklig/work/mono/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/ArrayMirror.cs | |
| --- /Users/alklig/work/debugger-libs/Mono.Debugger.Soft/Mono.Debugger.Soft/ArrayMirror.cs 2019-07-15 14:32:06.000000000 -0400 | |
| +++ /Users/alklig/work/mono/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/ArrayMirror.cs 2015-09-30 17:51:36.000000000 -0400 | |
| @@ -1,4 +1,3 @@ | |
| - | |
| using System; | |
| using System.Collections; | |
| using System.Collections.Generic; | |
| @@ -93,14 +92,6 @@ | |
| vm.conn.Array_SetValues (id, index, vm.EncodeValues (values)); | |
| } | |
| - public void SetByteValues (byte[] bytes) | |
| - { | |
| - if (bytes != null && bytes.Length != Length) { | |
| - throw new IndexOutOfRangeException (); | |
| - } | |
| - vm.conn.ByteArray_SetValues (id, bytes); | |
| - } | |
| - | |
| IEnumerator IEnumerable.GetEnumerator () | |
| { | |
| return new SimpleEnumerator (this); | |
| diff -u /Users/alklig/work/debugger-libs/Mono.Debugger.Soft/Mono.Debugger.Soft/AssemblyMirror.cs /Users/alklig/work/mono/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/AssemblyMirror.cs | |
| --- /Users/alklig/work/debugger-libs/Mono.Debugger.Soft/Mono.Debugger.Soft/AssemblyMirror.cs 2019-07-15 14:32:06.000000000 -0400 | |
| +++ /Users/alklig/work/mono/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/AssemblyMirror.cs 2019-06-04 14:44:12.000000000 -0400 | |
| @@ -1,8 +1,12 @@ | |
| using System; | |
| using System.Reflection; | |
| using Mono.Debugger; | |
| -using Mono.Cecil; | |
| using System.Collections.Generic; | |
| +using System.IO; | |
| + | |
| +#if ENABLE_CECIL | |
| +using Mono.Cecil; | |
| +#endif | |
| namespace Mono.Debugger.Soft | |
| { | |
| @@ -13,10 +17,19 @@ | |
| bool entry_point_set; | |
| ModuleMirror main_module; | |
| AssemblyName aname; | |
| - AssemblyDefinition meta; | |
| AppDomainMirror domain; | |
| + byte[] metadata_blob; | |
| + bool? isDynamic; | |
| + byte[] pdb_blob; | |
| + bool? has_debug_info; | |
| Dictionary<string, long> typeCacheIgnoreCase = new Dictionary<string, long> (StringComparer.InvariantCultureIgnoreCase); | |
| Dictionary<string, long> typeCache = new Dictionary<string, long> (); | |
| + Dictionary<uint, long> tokenTypeCache = new Dictionary<uint, long> (); | |
| + Dictionary<uint, long> tokenMethodCache = new Dictionary<uint, long> (); | |
| + | |
| +#if ENABLE_CECIL | |
| + AssemblyDefinition meta; | |
| +#endif | |
| internal AssemblyMirror (VirtualMachine vm, long id) : base (vm, id) { | |
| } | |
| @@ -112,13 +125,16 @@ | |
| return GetType (name, false, false); | |
| } | |
| +#if ENABLE_CECIL | |
| /* | |
| * An optional Cecil assembly which could be used to access metadata instead | |
| * of reading it from the debuggee. | |
| */ | |
| public AssemblyDefinition Metadata { | |
| get { | |
| - return meta; | |
| + if (meta != null) | |
| + return meta; | |
| + return null; | |
| } | |
| set { | |
| if (value.MainModule.Name != ManifestModule.Name) | |
| @@ -128,5 +144,96 @@ | |
| meta = value; | |
| } | |
| } | |
| - } | |
| + | |
| + // Read assembly metadata from the debuggee | |
| + // Since protocol version 2.47 | |
| + public AssemblyDefinition GetMetadata () { | |
| + if (IsDynamic) | |
| + throw new NotSupportedException (); | |
| + | |
| + using (var ms = new MemoryStream (GetMetadataBlob ())) | |
| + return meta = AssemblyDefinition.ReadAssembly (ms); | |
| + } | |
| +#endif | |
| + | |
| + public byte[] GetMetadataBlob () { | |
| + if (metadata_blob != null) | |
| + return metadata_blob; | |
| + | |
| + vm.CheckProtocolVersion (2, 47); | |
| + | |
| + return metadata_blob = vm.conn.Assembly_GetMetadataBlob (id); | |
| + } | |
| + | |
| + public bool IsDynamic { | |
| + get { | |
| + if (isDynamic.HasValue) | |
| + return isDynamic.Value; | |
| + | |
| + vm.CheckProtocolVersion (2, 47); | |
| + | |
| + isDynamic = vm.conn.Assembly_IsDynamic (id); | |
| + return isDynamic.Value; | |
| + } | |
| + } | |
| + | |
| + public bool HasPdb { | |
| + get { | |
| + return pdb_blob != null; | |
| + } | |
| + } | |
| + | |
| + public bool HasFetchedPdb { get; private set; } | |
| + | |
| + public byte[] GetPdbBlob () { | |
| + if (HasFetchedPdb) | |
| + return pdb_blob; | |
| + | |
| + vm.CheckProtocolVersion (2, 47); | |
| + var blob = vm.conn.Assembly_GetPdbBlob (id); | |
| + if (blob != null && blob.Length > 0) { | |
| + pdb_blob = blob; | |
| + } | |
| + HasFetchedPdb = true; | |
| + return pdb_blob; | |
| + } | |
| + | |
| + public TypeMirror GetType (uint token) { | |
| + vm.CheckProtocolVersion (2, 47); | |
| + if (IsDynamic) | |
| + throw new NotSupportedException (); | |
| + | |
| + long typeId; | |
| + if (!tokenTypeCache.TryGetValue (token, out typeId)) { | |
| + typeId = vm.conn.Assembly_GetType (id, token); | |
| + tokenTypeCache.Add (token, typeId); | |
| + } | |
| + return vm.GetType (typeId); | |
| + } | |
| + | |
| + public MethodMirror GetMethod (uint token) { | |
| + vm.CheckProtocolVersion (2, 47); | |
| + if (IsDynamic) | |
| + throw new NotSupportedException (); | |
| + | |
| + long methodId; | |
| + if (!tokenMethodCache.TryGetValue (token, out methodId)) { | |
| + methodId = vm.conn.Assembly_GetMethod (id, token); | |
| + tokenMethodCache.Add (token, methodId); | |
| + } | |
| + return vm.GetMethod (methodId); | |
| + } | |
| + | |
| + public bool HasDebugInfo { | |
| + get { | |
| + if (has_debug_info.HasValue) | |
| + return has_debug_info.Value; | |
| + | |
| + vm.CheckProtocolVersion (2, 51); | |
| + | |
| + has_debug_info = vm.conn.Assembly_HasDebugInfo (id); | |
| + return has_debug_info.Value; | |
| + } | |
| + } | |
| + } | |
| } | |
| diff -u /Users/alklig/work/debugger-libs/Mono.Debugger.Soft/Mono.Debugger.Soft/Connection.cs /Users/alklig/work/mono/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/Connection.cs | |
| --- /Users/alklig/work/debugger-libs/Mono.Debugger.Soft/Mono.Debugger.Soft/Connection.cs 2019-07-15 14:46:30.000000000 -0400 | |
| +++ /Users/alklig/work/mono/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/Connection.cs 2019-07-12 13:31:46.000000000 -0400 | |
| @@ -6,7 +6,6 @@ | |
| using System.Collections.Generic; | |
| using System.Text; | |
| using System.Diagnostics; | |
| -using Mono.Cecil.Metadata; | |
| namespace Mono.Debugger.Soft | |
| { | |
| @@ -219,7 +218,7 @@ | |
| } | |
| class ModuleInfo { | |
| - public string Name, ScopeName, FQName, Guid; | |
| + public string Name, ScopeName, FQName, Guid, SourceLink; | |
| public long Assembly; | |
| } | |
| @@ -367,6 +366,14 @@ | |
| get; set; | |
| } | |
| + public string Dump { | |
| + get; set; | |
| + } | |
| + | |
| + public ulong Hash { | |
| + get; set; | |
| + } | |
| + | |
| public EventInfo (EventType type, int req_id) { | |
| EventType = type; | |
| ReqId = req_id; | |
| @@ -420,7 +427,7 @@ | |
| * with newer runtimes, and vice versa. | |
| */ | |
| internal const int MAJOR_VERSION = 2; | |
| - internal const int MINOR_VERSION = 45; | |
| + internal const int MINOR_VERSION = 52; | |
| enum WPSuspendPolicy { | |
| NONE = 0, | |
| @@ -442,7 +449,8 @@ | |
| TYPE = 23, | |
| MODULE = 24, | |
| FIELD = 25, | |
| - EVENT = 64 | |
| + EVENT = 64, | |
| + POINTER = 65 | |
| } | |
| enum EventKind { | |
| @@ -462,7 +470,8 @@ | |
| EXCEPTION = 13, | |
| KEEPALIVE = 14, | |
| USER_BREAK = 15, | |
| - USER_LOG = 16 | |
| + USER_LOG = 16, | |
| + CRASH = 17 | |
| } | |
| enum ModifierKind { | |
| @@ -525,7 +534,7 @@ | |
| CREATE_STRING = 5, | |
| GET_CORLIB = 6, | |
| CREATE_BOXED_VALUE = 7, | |
| - CREATE_BYTE_ARRAY = 8 | |
| + CREATE_BYTE_ARRAY = 8, | |
| } | |
| enum CmdAssembly { | |
| @@ -535,7 +544,13 @@ | |
| GET_OBJECT = 4, | |
| GET_TYPE = 5, | |
| GET_NAME = 6, | |
| - GET_DOMAIN = 7 | |
| + GET_DOMAIN = 7, | |
| + GET_METADATA_BLOB = 8, | |
| + GET_IS_DYNAMIC = 9, | |
| + GET_PDB_BLOB = 10, | |
| + GET_TYPE_FROM_TOKEN = 11, | |
| + GET_METHOD_FROM_TOKEN = 12, | |
| + HAS_DEBUG_INFO = 13, | |
| } | |
| enum CmdModule { | |
| @@ -576,7 +591,8 @@ | |
| GET_INTERFACES = 16, | |
| GET_INTERFACE_MAP = 17, | |
| IS_INITIALIZED = 18, | |
| - CREATE_INSTANCE = 19 | |
| + CREATE_INSTANCE = 19, | |
| + GET_VALUE_SIZE = 20 | |
| } | |
| enum CmdField { | |
| @@ -588,6 +604,11 @@ | |
| BINDING_FLAGS_IGNORE_CASE = 0x70000000, | |
| } | |
| + enum MemberListTypeExtensions { | |
| + CaseSensitive = 1, | |
| + CaseInsensitive = 2 | |
| + } | |
| + | |
| enum CmdStackFrame { | |
| GET_VALUES = 1, | |
| GET_THIS = 2, | |
| @@ -608,6 +629,10 @@ | |
| GET_CHARS = 3 | |
| } | |
| + enum CmdPointer { | |
| + GET_VALUE = 1 | |
| + } | |
| + | |
| enum CmdObjectRef { | |
| GET_TYPE = 1, | |
| GET_VALUES = 2, | |
| @@ -644,6 +669,17 @@ | |
| return packet [offset++]; | |
| } | |
| + static byte[] decode_bytes (byte[] packet, ref int offset, int length) | |
| + { | |
| + if (length + offset > packet.Length) | |
| + throw new ArgumentOutOfRangeException (); | |
| + | |
| + var bytes = new byte[length]; | |
| + Array.Copy (packet, offset, bytes, 0, length); | |
| + offset += length; | |
| + return bytes; | |
| + } | |
| + | |
| static int decode_short (byte[] packet, ref int offset) { | |
| int res = ((int)packet [offset] << 8) | (int)packet [offset + 1]; | |
| offset += 2; | |
| @@ -732,10 +768,12 @@ | |
| } | |
| class PacketReader { | |
| + Connection connection; | |
| byte[] packet; | |
| int offset; | |
| - public PacketReader (byte[] packet) { | |
| + public PacketReader (Connection connection, byte[] packet) { | |
| + this.connection = connection; | |
| this.packet = packet; | |
| // For event packets | |
| @@ -847,9 +885,16 @@ | |
| return new ValueImpl { Type = etype, Value = ReadDouble () }; | |
| case ElementType.I: | |
| case ElementType.U: | |
| - case ElementType.Ptr: | |
| // FIXME: The client and the debuggee might have different word sizes | |
| return new ValueImpl { Type = etype, Value = ReadLong () }; | |
| + case ElementType.Ptr: | |
| + long value = ReadLong (); | |
| + if (connection.Version.AtLeast (2, 46)) { | |
| + long pointerClass = ReadId (); | |
| + return new ValueImpl { Type = etype, Klass = pointerClass, Value = value }; | |
| + } else { | |
| + return new ValueImpl { Type = etype, Value = value }; | |
| + } | |
| case ElementType.String: | |
| case ElementType.SzArray: | |
| case ElementType.Class: | |
| @@ -882,6 +927,15 @@ | |
| res [i] = ReadId (); | |
| return res; | |
| } | |
| + | |
| + public byte[] ReadByteArray () { | |
| + var length = ReadInt (); | |
| + return decode_bytes (packet, ref offset, length); | |
| + } | |
| + | |
| + public bool ReadBool () { | |
| + return ReadByte () != 0; | |
| + } | |
| } | |
| class PacketWriter { | |
| @@ -972,7 +1026,6 @@ | |
| offset += b.Length; | |
| return this; | |
| } | |
| - | |
| public PacketWriter WriteBytes (byte[] b) { | |
| if (b == null) | |
| return WriteInt (-1); | |
| @@ -1090,9 +1143,6 @@ | |
| internal event EventHandler<ErrorHandlerEventArgs> ErrorHandler; | |
| - [Obsolete("This constructor will be removed in next version")] | |
| - protected Connection (TextWriter logWriter) : this () { } | |
| - | |
| protected Connection () { | |
| closed = false; | |
| reply_packets = new Dictionary<int, byte[]> (); | |
| @@ -1243,6 +1293,7 @@ | |
| } | |
| bool disconnected; | |
| + VMCrashException crashed; | |
| internal ManualResetEvent DisconnectedEvent = new ManualResetEvent (false); | |
| @@ -1250,10 +1301,14 @@ | |
| while (!closed) { | |
| try { | |
| bool res = ReceivePacket (); | |
| - if (!res) | |
| + if (!res) { | |
| break; | |
| + } | |
| } catch (ThreadAbortException) { | |
| break; | |
| + } catch (VMCrashException ex) { | |
| + crashed = ex; | |
| + break; | |
| } catch (Exception ex) { | |
| if (!closed) { | |
| Console.WriteLine (ex); | |
| @@ -1271,6 +1326,15 @@ | |
| EventHandler.VMDisconnect (0, 0, null); | |
| } | |
| + void disconnected_check () { | |
| + if (!disconnected) | |
| + return; | |
| + else if (crashed != null) | |
| + throw crashed; | |
| + else | |
| + throw new VMDisconnectedException (); | |
| + } | |
| + | |
| bool ReceivePacket () { | |
| byte[] packet = ReadPacket (); | |
| @@ -1299,7 +1363,7 @@ | |
| if (cb != null) | |
| cb.Invoke (id, packet); | |
| } else { | |
| - PacketReader r = new PacketReader (packet); | |
| + PacketReader r = new PacketReader (this, packet); | |
| if (r.CommandSet == CommandSet.EVENT && r.Command == (int)CmdEvent.COMPOSITE) { | |
| int spolicy = r.ReadByte (); | |
| @@ -1325,6 +1389,11 @@ | |
| exit_code = r.ReadInt (); | |
| //EventHandler.VMDeath (req_id, 0, null); | |
| events [i] = new EventInfo (etype, req_id) { ExitCode = exit_code }; | |
| + } else if (kind == EventKind.CRASH) { | |
| + ulong hash = (ulong) r.ReadLong (); | |
| + string dump = r.ReadString (); | |
| + | |
| + events [i] = new EventInfo (etype, req_id) { Dump = dump, Hash = hash}; | |
| } else if (kind == EventKind.THREAD_START) { | |
| events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = thread_id }; | |
| //EventHandler.ThreadStart (req_id, thread_id, thread_id); | |
| @@ -1518,7 +1587,7 @@ | |
| if (EnableConnectionLogging) | |
| LogPacket (packet_id, encoded_packet, p, command_set, command, watch); | |
| /* Run the callback on a tp thread to avoid blocking the receive thread */ | |
| - PacketReader r = new PacketReader (p); | |
| + PacketReader r = new PacketReader (this, p); | |
| cb.BeginInvoke (r, null, null); | |
| }; | |
| reply_cb_counts [id] = count; | |
| @@ -1542,8 +1611,7 @@ | |
| int id = IdGenerator; | |
| Stopwatch watch = null; | |
| - if (disconnected) | |
| - throw new VMDisconnectedException (); | |
| + disconnected_check (); | |
| if (EnableConnectionLogging) | |
| watch = Stopwatch.StartNew (); | |
| @@ -1562,10 +1630,10 @@ | |
| /* Wait for the reply packet */ | |
| while (true) { | |
| lock (reply_packets_monitor) { | |
| - if (reply_packets.ContainsKey (packetId)) { | |
| - byte[] reply = reply_packets [packetId]; | |
| + byte[] reply; | |
| + if (reply_packets.TryGetValue (packetId, out reply)) { | |
| reply_packets.Remove (packetId); | |
| - PacketReader r = new PacketReader (reply); | |
| + PacketReader r = new PacketReader (this, reply); | |
| if (EnableConnectionLogging) | |
| LogPacket (packetId, encoded_packet, reply, command_set, command, watch); | |
| @@ -1577,8 +1645,7 @@ | |
| return r; | |
| } | |
| } else { | |
| - if (disconnected) | |
| - throw new VMDisconnectedException (); | |
| + disconnected_check (); | |
| Monitor.Wait (reply_packets_monitor); | |
| } | |
| } | |
| @@ -1611,7 +1678,15 @@ | |
| CattrNamedArgInfo arg = new CattrNamedArgInfo (); | |
| int arg_type = r.ReadByte (); | |
| arg.is_property = arg_type == 0x54; | |
| - arg.id = r.ReadId (); | |
| + | |
| + // 2.12 is the only version we can guarantee the server will send a field id | |
| + // It was added in https://github.com/mono/mono/commit/db0b932cd6c3c93976479ae3f6b5b2a885f681de | |
| + // In between 2.11 and 2.12 | |
| + if (arg.is_property) | |
| + arg.id = r.ReadId (); | |
| + else if (Version.AtLeast (2, 12)) | |
| + arg.id = r.ReadId (); | |
| + | |
| arg.value = r.ReadValue (); | |
| info.named_args [j] = arg; | |
| } | |
| @@ -2060,9 +2135,11 @@ | |
| internal string Thread_GetName (long id) { | |
| return SendReceive (CommandSet.THREAD, (int)CmdThread.GET_NAME, new PacketWriter ().WriteId (id)).ReadString (); | |
| } | |
| + | |
| internal long Thread_GetElapsedTime (long id) { | |
| return SendReceive (CommandSet.THREAD, (int)CmdThread.GET_ELAPSED_TIME, new PacketWriter ().WriteId (id)).ReadLong (); | |
| } | |
| + | |
| internal void Thread_GetFrameInfo (long id, int start_frame, int length, Action<FrameInfo[]> resultCallaback) { | |
| Send (CommandSet.THREAD, (int)CmdThread.GET_FRAME_INFO, new PacketWriter ().WriteId (id).WriteInt (start_frame).WriteInt (length), (res) => { | |
| int count = res.ReadInt (); | |
| @@ -2110,6 +2187,8 @@ | |
| internal ModuleInfo Module_GetInfo (long id) { | |
| PacketReader r = SendReceive (CommandSet.MODULE, (int)CmdModule.GET_INFO, new PacketWriter ().WriteId (id)); | |
| ModuleInfo info = new ModuleInfo { Name = r.ReadString (), ScopeName = r.ReadString (), FQName = r.ReadString (), Guid = r.ReadString (), Assembly = r.ReadId () }; | |
| + if (Version.AtLeast (2, 48)) | |
| + info.SourceLink = r.ReadString (); | |
| return info; | |
| } | |
| @@ -2144,6 +2223,30 @@ | |
| internal long Assembly_GetIdDomain (long id) { | |
| return SendReceive (CommandSet.ASSEMBLY, (int)CmdAssembly.GET_DOMAIN, new PacketWriter ().WriteId (id)).ReadId (); | |
| } | |
| + | |
| + internal byte[] Assembly_GetMetadataBlob (long id) { | |
| + return SendReceive (CommandSet.ASSEMBLY, (int)CmdAssembly.GET_METADATA_BLOB, new PacketWriter ().WriteId (id)).ReadByteArray (); | |
| + } | |
| + | |
| + internal bool Assembly_IsDynamic (long id) { | |
| + return SendReceive (CommandSet.ASSEMBLY, (int) CmdAssembly.GET_IS_DYNAMIC, new PacketWriter ().WriteId (id)).ReadBool (); | |
| + } | |
| + | |
| + internal byte[] Assembly_GetPdbBlob (long id) { | |
| + return SendReceive (CommandSet.ASSEMBLY, (int)CmdAssembly.GET_PDB_BLOB, new PacketWriter ().WriteId (id)).ReadByteArray (); | |
| + } | |
| + | |
| + internal long Assembly_GetType (long id, uint token) { | |
| + return SendReceive (CommandSet.ASSEMBLY, (int)CmdAssembly.GET_TYPE_FROM_TOKEN, new PacketWriter ().WriteId (id).WriteInt ((int)token)).ReadId (); | |
| + } | |
| + | |
| + internal long Assembly_GetMethod (long id, uint token) { | |
| + return SendReceive (CommandSet.ASSEMBLY, (int)CmdAssembly.GET_METHOD_FROM_TOKEN, new PacketWriter ().WriteId (id).WriteInt ((int)token)).ReadId (); | |
| + } | |
| + | |
| + internal bool Assembly_HasDebugInfo (long id) { | |
| + return SendReceive (CommandSet.ASSEMBLY, (int)CmdAssembly.HAS_DEBUG_INFO, new PacketWriter ().WriteId (id)).ReadBool (); | |
| + } | |
| /* | |
| * TYPE | |
| @@ -2283,7 +2386,11 @@ | |
| public long[] Type_GetMethodsByNameFlags (long id, string name, int flags, bool ignoreCase) { | |
| flags |= ignoreCase ? (int)BindingFlagsExtensions.BINDING_FLAGS_IGNORE_CASE : 0; | |
| - PacketReader r = SendReceive (CommandSet.TYPE, (int)CmdType.CMD_TYPE_GET_METHODS_BY_NAME_FLAGS, new PacketWriter ().WriteId (id).WriteString (name).WriteInt (flags)); | |
| + int listType = ignoreCase ? (int)MemberListTypeExtensions.CaseInsensitive : (int)MemberListTypeExtensions.CaseSensitive; | |
| + var w = new PacketWriter ().WriteId (id).WriteString (name).WriteInt (flags); | |
| + if (Version.AtLeast (2, 48)) | |
| + w.WriteInt (listType); | |
| + PacketReader r = SendReceive (CommandSet.TYPE, (int)CmdType.CMD_TYPE_GET_METHODS_BY_NAME_FLAGS, w); | |
| int len = r.ReadInt (); | |
| long[] res = new long [len]; | |
| for (int i = 0; i < len; ++i) | |
| @@ -2321,6 +2428,11 @@ | |
| return r.ReadId (); | |
| } | |
| + internal int Type_GetValueSize (long id) { | |
| + PacketReader r = SendReceive (CommandSet.TYPE, (int)CmdType.GET_VALUE_SIZE, new PacketWriter ().WriteId (id)); | |
| + return r.ReadInt (); | |
| + } | |
| + | |
| /* | |
| * FIELD | |
| */ | |
| @@ -2473,21 +2585,6 @@ | |
| SendReceive (CommandSet.ARRAY_REF, (int)CmdArrayRef.SET_VALUES, new PacketWriter ().WriteId (id).WriteInt (index).WriteInt (values.Length).WriteValues (values)); | |
| } | |
| - // This is a special case when setting values of an array that | |
| - // consists of a large number of bytes. This saves much time and | |
| - // cost than we create ValueImpl object for each byte. | |
| - internal void ByteArray_SetValues (long id, byte[] bytes) | |
| - { | |
| - int index = 0; | |
| - var typ = (byte)ElementType.U1; | |
| - var w = new PacketWriter ().WriteId (id).WriteInt (index).WriteInt (bytes.Length); | |
| - for (int i = 0; i < bytes.Length; i++) { | |
| - w.WriteByte (typ); | |
| - w.WriteInt (bytes[i]); | |
| - } | |
| - SendReceive (CommandSet.ARRAY_REF, (int)CmdArrayRef.SET_VALUES, w); | |
| - } | |
| - | |
| /* | |
| * STRINGS | |
| */ | |
| @@ -2514,7 +2611,16 @@ | |
| for (int i = 0; i < length; ++i) | |
| res [i] = (char)r.ReadShort (); | |
| return res; | |
| - } | |
| + } | |
| + | |
| + /* | |
| + * POINTERS | |
| + */ | |
| + | |
| + internal ValueImpl Pointer_GetValue (long address, TypeMirror type) | |
| + { | |
| + return SendReceive (CommandSet.POINTER, (int)CmdPointer.GET_VALUE, new PacketWriter ().WriteLong (address).WriteId (type.Id)).ReadValue (); | |
| + } | |
| /* | |
| * OBJECTS | |
| Only in /Users/alklig/work/mono/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft: CrashEvent.cs | |
| diff -u /Users/alklig/work/debugger-libs/Mono.Debugger.Soft/Mono.Debugger.Soft/CustomAttributeDataMirror.cs /Users/alklig/work/mono/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/CustomAttributeDataMirror.cs | |
| --- /Users/alklig/work/debugger-libs/Mono.Debugger.Soft/Mono.Debugger.Soft/CustomAttributeDataMirror.cs 2019-07-15 14:32:06.000000000 -0400 | |
| +++ /Users/alklig/work/mono/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/CustomAttributeDataMirror.cs 2019-06-04 14:44:12.000000000 -0400 | |
| @@ -4,7 +4,6 @@ | |
| using System.Runtime.InteropServices; | |
| using System.Reflection; | |
| using System.Text; | |
| -using Mono.Cecil.Metadata; | |
| namespace Mono.Debugger.Soft { | |
| @@ -112,32 +111,34 @@ | |
| var ctor_args = new object [attr.ctor_args.Length]; | |
| for (int j = 0; j < ctor_args.Length; ++j) | |
| ctor_args [j] = CreateArg (vm, attr.ctor_args [j]); | |
| - var named_args = new object [attr.named_args.Length]; | |
| - for (int j = 0; j < named_args.Length; ++j) { | |
| + var named_args = new List<object> (attr.named_args.Length); | |
| + for (int j = 0; j < attr.named_args.Length; ++j) { | |
| CattrNamedArgInfo arg = attr.named_args [j]; | |
| CustomAttributeTypedArgumentMirror val; | |
| + CustomAttributeNamedArgumentMirror? named_arg = null; | |
| val = CreateArg (vm, arg.value); | |
| TypeMirror t = ctor.DeclaringType; | |
| - while (named_args [j] == null && t != null) { | |
| + while (named_arg == null && t != null) { | |
| if (arg.is_property) { | |
| foreach (var prop in t.GetProperties ()) { | |
| if (prop.Id == arg.id) | |
| - named_args [j] = new CustomAttributeNamedArgumentMirror (prop, null, val); | |
| + named_arg = new CustomAttributeNamedArgumentMirror (prop, null, val); | |
| } | |
| - } else { | |
| + } else if (vm.Version.AtLeast (2, 12)) { // we don't have the field ID before 2.12 | |
| foreach (var field in t.GetFields ()) { | |
| if (field.Id == arg.id) | |
| - named_args [j] = new CustomAttributeNamedArgumentMirror (null, field, val); | |
| + named_arg = new CustomAttributeNamedArgumentMirror (null, field, val); | |
| } | |
| } | |
| t = t.BaseType; | |
| } | |
| - if (named_args [j] == null) | |
| - throw new NotImplementedException (); | |
| + | |
| + if (named_arg.HasValue) | |
| + named_args.Add (named_arg.Value); | |
| } | |
| - res [i] = new CustomAttributeDataMirror (ctor, ctor_args, named_args); | |
| + res [i] = new CustomAttributeDataMirror (ctor, ctor_args, named_args.ToArray ()); | |
| } | |
| return res; | |
| Only in /Users/alklig/work/debugger-libs/Mono.Debugger.Soft/Mono.Debugger.Soft: DelayedLambdaType.cs | |
| Only in /Users/alklig/work/debugger-libs/Mono.Debugger.Soft/Mono.Debugger.Soft: DelayedLambdaValue.cs | |
| diff -u /Users/alklig/work/debugger-libs/Mono.Debugger.Soft/Mono.Debugger.Soft/EnumMirror.cs /Users/alklig/work/mono/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/EnumMirror.cs | |
| --- /Users/alklig/work/debugger-libs/Mono.Debugger.Soft/Mono.Debugger.Soft/EnumMirror.cs 2019-07-15 14:32:06.000000000 -0400 | |
| +++ /Users/alklig/work/mono/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/EnumMirror.cs 2019-06-04 14:44:12.000000000 -0400 | |
| @@ -19,7 +19,8 @@ | |
| if (!type.IsEnum) | |
| throw new ArgumentException ("type must be an enum type", "type"); | |
| TypeMirror t = type.EnumUnderlyingType; | |
| - if (value.Value == null || !value.Value.GetType ().IsPrimitive || t != vm.RootDomain.GetCorrespondingType (value.Value.GetType ())) | |
| + // Can't access t's domain, so compare type names | |
| + if (value.Value == null || !value.Value.GetType ().IsPrimitive || t.Name != vm.RootDomain.GetCorrespondingType (value.Value.GetType ()).Name) | |
| throw new ArgumentException ("Value '" + value.Value + "' does not match the type of the enum."); | |
| } | |
| diff -u /Users/alklig/work/debugger-libs/Mono.Debugger.Soft/Mono.Debugger.Soft/EventType.cs /Users/alklig/work/mono/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/EventType.cs | |
| --- /Users/alklig/work/debugger-libs/Mono.Debugger.Soft/Mono.Debugger.Soft/EventType.cs 2019-07-15 14:32:06.000000000 -0400 | |
| +++ /Users/alklig/work/mono/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/EventType.cs 2019-06-04 14:44:12.000000000 -0400 | |
| @@ -26,6 +26,8 @@ | |
| // System.Diagnostics.Debugger.Log () | |
| // | |
| UserLog = 16, | |
| + // Fatal error handling | |
| + Crash = 17, | |
| // Not part of the wire protocol | |
| VMDisconnect = 99 | |
| } | |
| diff -u /Users/alklig/work/debugger-libs/Mono.Debugger.Soft/Mono.Debugger.Soft/FieldInfoMirror.cs /Users/alklig/work/mono/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/FieldInfoMirror.cs | |
| --- /Users/alklig/work/debugger-libs/Mono.Debugger.Soft/Mono.Debugger.Soft/FieldInfoMirror.cs 2019-07-15 14:32:06.000000000 -0400 | |
| +++ /Users/alklig/work/mono/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/FieldInfoMirror.cs 2019-06-04 14:44:12.000000000 -0400 | |
| @@ -2,8 +2,10 @@ | |
| using System.Collections.Generic; | |
| using System.Text; | |
| using System.Reflection; | |
| + | |
| +#if ENABLE_CECIL | |
| using C = Mono.Cecil; | |
| -using Mono.Cecil.Metadata; | |
| +#endif | |
| namespace Mono.Debugger.Soft | |
| { | |
| @@ -14,9 +16,12 @@ | |
| TypeMirror type; | |
| FieldAttributes attrs; | |
| CustomAttributeDataMirror[] cattrs; | |
| - C.FieldDefinition meta; | |
| bool inited; | |
| +#if ENABLE_CECIL | |
| + C.FieldDefinition meta; | |
| +#endif | |
| + | |
| public FieldInfoMirror (TypeMirror parent, long id, string name, TypeMirror type, FieldAttributes attrs) : base (parent.VirtualMachine, id) { | |
| this.parent = parent; | |
| this.name = name; | |
| @@ -167,6 +172,7 @@ | |
| return GetCAttrs (attributeType, inherit); | |
| } | |
| +#if ENABLE_CECIL | |
| public C.FieldDefinition Metadata { | |
| get { | |
| if (parent.Metadata == null) | |
| @@ -184,10 +190,14 @@ | |
| return meta; | |
| } | |
| } | |
| +#endif | |
| CustomAttributeDataMirror[] GetCAttrs (TypeMirror type, bool inherit) { | |
| + | |
| +#if ENABLE_CECIL | |
| if (cattrs == null && Metadata != null && !Metadata.HasCustomAttributes) | |
| cattrs = new CustomAttributeDataMirror [0]; | |
| +#endif | |
| // FIXME: Handle inherit | |
| if (cattrs == null) { | |
| diff -u /Users/alklig/work/debugger-libs/Mono.Debugger.Soft/Mono.Debugger.Soft/ILInstruction.cs /Users/alklig/work/mono/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/ILInstruction.cs | |
| --- /Users/alklig/work/debugger-libs/Mono.Debugger.Soft/Mono.Debugger.Soft/ILInstruction.cs 2019-07-15 14:32:06.000000000 -0400 | |
| +++ /Users/alklig/work/mono/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/ILInstruction.cs 2019-06-04 14:44:12.000000000 -0400 | |
| @@ -1,11 +1,15 @@ | |
| using System; | |
| using System.Collections.Generic; | |
| using System.Text; | |
| -using Mono.Cecil.Cil; | |
| -using Mono.Cecil.Metadata; | |
| using System.IO; | |
| using System.Reflection; | |
| +#if ENABLE_CECIL | |
| +using Mono.Cecil.Cil; | |
| +#else | |
| +using System.Reflection.Emit; | |
| +#endif | |
| + | |
| namespace Mono.Debugger.Soft | |
| { | |
| /* | |
| diff -u /Users/alklig/work/debugger-libs/Mono.Debugger.Soft/Mono.Debugger.Soft/ILInterpreter.cs /Users/alklig/work/mono/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/ILInterpreter.cs | |
| --- /Users/alklig/work/debugger-libs/Mono.Debugger.Soft/Mono.Debugger.Soft/ILInterpreter.cs 2019-07-15 14:32:06.000000000 -0400 | |
| +++ /Users/alklig/work/mono/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/ILInterpreter.cs 2019-06-04 14:44:12.000000000 -0400 | |
| @@ -1,6 +1,10 @@ | |
| using System; | |
| + | |
| +#if ENABLE_CECIL | |
| using Mono.Cecil.Cil; | |
| -using Mono.Cecil.Metadata; | |
| +#else | |
| +using System.Reflection.Emit; | |
| +#endif | |
| namespace Mono.Debugger.Soft | |
| { | |
| diff -u /Users/alklig/work/debugger-libs/Mono.Debugger.Soft/Mono.Debugger.Soft/InterfaceMappingMirror.cs /Users/alklig/work/mono/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/InterfaceMappingMirror.cs | |
| --- /Users/alklig/work/debugger-libs/Mono.Debugger.Soft/Mono.Debugger.Soft/InterfaceMappingMirror.cs 2019-07-15 14:32:06.000000000 -0400 | |
| +++ /Users/alklig/work/mono/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/InterfaceMappingMirror.cs 2019-06-04 14:44:12.000000000 -0400 | |
| @@ -1,8 +1,6 @@ | |
| using System; | |
| using System.Collections.Generic; | |
| using System.Reflection; | |
| -using C = Mono.Cecil; | |
| -using Mono.Cecil.Metadata; | |
| namespace Mono.Debugger.Soft | |
| { | |
| diff -u /Users/alklig/work/debugger-libs/Mono.Debugger.Soft/Mono.Debugger.Soft/MethodBodyMirror.cs /Users/alklig/work/mono/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/MethodBodyMirror.cs | |
| --- /Users/alklig/work/debugger-libs/Mono.Debugger.Soft/Mono.Debugger.Soft/MethodBodyMirror.cs 2019-07-15 14:32:06.000000000 -0400 | |
| +++ /Users/alklig/work/mono/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/MethodBodyMirror.cs 2019-06-04 14:44:12.000000000 -0400 | |
| @@ -2,12 +2,16 @@ | |
| using System.Globalization; | |
| using System.Collections.Generic; | |
| using System.Text; | |
| -using Mono.Cecil.Cil; | |
| -using Mono.Cecil.Metadata; | |
| using System.IO; | |
| using System.Linq; | |
| using System.Reflection; | |
| +#if ENABLE_CECIL | |
| +using Mono.Cecil.Cil; | |
| +#else | |
| +using System.Reflection.Emit; | |
| +#endif | |
| + | |
| namespace Mono.Debugger.Soft | |
| { | |
| public class MethodBodyMirror : Mirror | |
| @@ -84,11 +88,21 @@ | |
| if (!opcodes_inited) { | |
| foreach (FieldInfo fi in typeof (OpCodes).GetFields (BindingFlags.Static|BindingFlags.Public)) { | |
| var val = (OpCode)fi.GetValue (null); | |
| + bool isOneByteOpCode; | |
| + uint index; | |
| - if (val.Op1 == 0xff) | |
| - OneByteOpCode [val.Op2] = val; | |
| +#if ENABLE_CECIL | |
| + isOneByteOpCode = val.Op1 == 0xff; | |
| + index = val.Op2; | |
| +#else | |
| + uint value = (uint)val.Value; | |
| + isOneByteOpCode = value <= 0xff; | |
| + index = isOneByteOpCode ? value : value & 0xff; | |
| +#endif | |
| + if (isOneByteOpCode) | |
| + OneByteOpCode [index] = val; | |
| else | |
| - TwoBytesOpCode [val.Op2] = val; | |
| + TwoBytesOpCode [index] = val; | |
| } | |
| opcodes_inited = true; | |
| } | |
| @@ -139,9 +153,11 @@ | |
| case OperandType.ShortInlineVar : | |
| instr.Operand = br.ReadByte (); | |
| break; | |
| +#if ENABLE_CECIL | |
| case OperandType.ShortInlineArg : | |
| instr.Operand = br.ReadByte (); | |
| break; | |
| +#endif | |
| case OperandType.InlineSig : | |
| br.ReadInt32 (); | |
| //instr.Operand = GetCallSiteAt (br.ReadInt32 (), context); | |
| @@ -152,9 +168,11 @@ | |
| case OperandType.InlineVar : | |
| instr.Operand = br.ReadInt16 (); | |
| break; | |
| +#if ENABLE_CECIL | |
| case OperandType.InlineArg : | |
| instr.Operand = br.ReadInt16 (); | |
| break; | |
| +#endif | |
| case OperandType.InlineI8 : | |
| instr.Operand = br.ReadInt64 (); | |
| break; | |
| diff -u /Users/alklig/work/debugger-libs/Mono.Debugger.Soft/Mono.Debugger.Soft/MethodMirror.cs /Users/alklig/work/mono/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/MethodMirror.cs | |
| --- /Users/alklig/work/debugger-libs/Mono.Debugger.Soft/Mono.Debugger.Soft/MethodMirror.cs 2019-07-15 14:32:06.000000000 -0400 | |
| +++ /Users/alklig/work/mono/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/MethodMirror.cs 2019-06-04 14:44:12.000000000 -0400 | |
| @@ -3,8 +3,10 @@ | |
| using System.Linq; | |
| using System.Text; | |
| using System.Reflection; | |
| + | |
| +#if ENABLE_CECIL | |
| using C = Mono.Cecil; | |
| -using Mono.Cecil.Metadata; | |
| +#endif | |
| namespace Mono.Debugger.Soft | |
| { | |
| @@ -14,7 +16,6 @@ | |
| MethodInfo info; | |
| TypeMirror declaring_type; | |
| DebugInfo debug_info; | |
| - C.MethodDefinition meta; | |
| CustomAttributeDataMirror[] cattrs; | |
| ParameterInfoMirror[] param_info; | |
| ParameterInfoMirror ret_param; | |
| @@ -25,6 +26,10 @@ | |
| MethodMirror gmd; | |
| TypeMirror[] type_args; | |
| +#if ENABLE_CECIL | |
| + C.MethodDefinition meta; | |
| +#endif | |
| + | |
| internal MethodMirror (VirtualMachine vm, long id) : base (vm, id) { | |
| } | |
| @@ -93,8 +98,10 @@ | |
| } | |
| CustomAttributeDataMirror[] GetCAttrs (TypeMirror type, bool inherit) { | |
| +#if ENABLE_CECIL | |
| if (cattrs == null && meta != null && !Metadata.HasCustomAttributes) | |
| cattrs = new CustomAttributeDataMirror [0]; | |
| +#endif | |
| // FIXME: Handle inherit | |
| if (cattrs == null) { | |
| @@ -417,6 +424,7 @@ | |
| return null; | |
| } | |
| +#if ENABLE_CECIL | |
| public C.MethodDefinition Metadata { | |
| get { | |
| if (meta == null) | |
| @@ -424,6 +432,7 @@ | |
| return meta; | |
| } | |
| } | |
| +#endif | |
| // | |
| // Evaluate the method on the client using an IL interpreter. | |
| diff -u /Users/alklig/work/debugger-libs/Mono.Debugger.Soft/Mono.Debugger.Soft/ModuleMirror.cs /Users/alklig/work/mono/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/ModuleMirror.cs | |
| --- /Users/alklig/work/debugger-libs/Mono.Debugger.Soft/Mono.Debugger.Soft/ModuleMirror.cs 2019-07-15 14:32:06.000000000 -0400 | |
| +++ /Users/alklig/work/mono/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/ModuleMirror.cs 2019-06-04 14:44:12.000000000 -0400 | |
| @@ -1,6 +1,5 @@ | |
| using System; | |
| using Mono.Debugger; | |
| -using Mono.Cecil; | |
| namespace Mono.Debugger.Soft | |
| { | |
| @@ -62,5 +61,14 @@ | |
| } | |
| // FIXME: Add function to query the guid, check in Metadata | |
| + | |
| + // Since protocol version 2.48 | |
| + public string SourceLink { | |
| + get { | |
| + vm.CheckProtocolVersion (2, 48); | |
| + ReadInfo (); | |
| + return info.SourceLink; | |
| + } | |
| + } | |
| } | |
| } | |
| diff -u /Users/alklig/work/debugger-libs/Mono.Debugger.Soft/Mono.Debugger.Soft/ObjectMirror.cs /Users/alklig/work/mono/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/ObjectMirror.cs | |
| --- /Users/alklig/work/debugger-libs/Mono.Debugger.Soft/Mono.Debugger.Soft/ObjectMirror.cs 2019-07-15 14:32:06.000000000 -0400 | |
| +++ /Users/alklig/work/mono/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/ObjectMirror.cs 2019-06-04 14:44:12.000000000 -0400 | |
| @@ -22,7 +22,17 @@ | |
| public Value[] OutArgs { get; set; } | |
| } | |
| - public class ObjectMirror : Value { | |
| + public interface IInvokable { | |
| + Value InvokeMethod (ThreadMirror thread, MethodMirror method, IList<Value> arguments); | |
| + Value InvokeMethod (ThreadMirror thread, MethodMirror method, IList<Value> arguments, InvokeOptions options); | |
| + IAsyncResult BeginInvokeMethod (ThreadMirror thread, MethodMirror method, IList<Value> arguments, InvokeOptions options, AsyncCallback callback, object state); | |
| + Value EndInvokeMethod (IAsyncResult asyncResult); | |
| + InvokeResult EndInvokeMethodWithResult (IAsyncResult asyncResult); | |
| + Task<Value> InvokeMethodAsync (ThreadMirror thread, MethodMirror method, IList<Value> arguments, InvokeOptions options = InvokeOptions.None); | |
| + Task<InvokeResult> InvokeMethodAsyncWithResult (ThreadMirror thread, MethodMirror method, IList<Value> arguments, InvokeOptions options = InvokeOptions.None); | |
| + } | |
| + | |
| + public class ObjectMirror : Value, IInvokable { | |
| TypeMirror type; | |
| AppDomainMirror domain; | |
| @@ -164,36 +174,37 @@ | |
| } | |
| public InvokeResult EndInvokeMethodWithResult (IAsyncResult asyncResult) { | |
| - return ObjectMirror.EndInvokeMethodInternalWithResult (asyncResult); | |
| + return ObjectMirror.EndInvokeMethodInternalWithResult (asyncResult); | |
| } | |
| public Task<Value> InvokeMethodAsync (ThreadMirror thread, MethodMirror method, IList<Value> arguments, InvokeOptions options = InvokeOptions.None) { | |
| - var tcs = new TaskCompletionSource<Value> (); | |
| - BeginInvokeMethod (thread, method, arguments, options, iar => | |
| - { | |
| - try { | |
| - tcs.SetResult (EndInvokeMethod (iar)); | |
| - } catch (OperationCanceledException) { | |
| - tcs.TrySetCanceled (); | |
| - } catch (Exception ex) { | |
| - tcs.TrySetException (ex); | |
| - } | |
| - }, null); | |
| - return tcs.Task; | |
| + return InvokeMethodAsync (vm, thread, method, this, arguments, options); | |
| + } | |
| + | |
| + internal static Task<Value> InvokeMethodAsync (VirtualMachine vm, ThreadMirror thread, MethodMirror method, Value this_obj, IList<Value> arguments, InvokeOptions options) { | |
| + return InvokeMethodAsync (vm, thread, method, this_obj, arguments, options, EndInvokeMethodInternal); | |
| } | |
| public Task<InvokeResult> InvokeMethodAsyncWithResult (ThreadMirror thread, MethodMirror method, IList<Value> arguments, InvokeOptions options = InvokeOptions.None) { | |
| - var tcs = new TaskCompletionSource<InvokeResult> (); | |
| - BeginInvokeMethod (thread, method, arguments, options, iar => | |
| - { | |
| - try { | |
| - tcs.SetResult (EndInvokeMethodInternalWithResult (iar)); | |
| - } catch (OperationCanceledException) { | |
| - tcs.TrySetCanceled (); | |
| - } catch (Exception ex) { | |
| - tcs.TrySetException (ex); | |
| - } | |
| - }, null); | |
| + return InvokeMethodAsyncWithResult (vm, thread, method, this, arguments, options); | |
| + } | |
| + | |
| + internal static Task<InvokeResult> InvokeMethodAsyncWithResult (VirtualMachine vm, ThreadMirror thread, MethodMirror method, Value this_obj, IList<Value> arguments, InvokeOptions options) { | |
| + return InvokeMethodAsync (vm, thread, method, this_obj, arguments, options, EndInvokeMethodInternalWithResult); | |
| + } | |
| + | |
| + internal static Task<TResult> InvokeMethodAsync<TResult> (VirtualMachine vm, ThreadMirror thread, MethodMirror method, Value this_obj, IList<Value> arguments, InvokeOptions options, Func<IAsyncResult, TResult> callback) { | |
| + var tcs = new TaskCompletionSource<TResult> (); | |
| + BeginInvokeMethod (vm, thread, method, this_obj, arguments, options, iar => | |
| + { | |
| + try { | |
| + tcs.SetResult (callback (iar)); | |
| + } catch (OperationCanceledException) { | |
| + tcs.TrySetCanceled (); | |
| + } catch (Exception ex) { | |
| + tcs.TrySetException (ex); | |
| + } | |
| + }, null); | |
| return tcs.Task; | |
| } | |
| diff -u /Users/alklig/work/debugger-libs/Mono.Debugger.Soft/Mono.Debugger.Soft/PointerValue.cs /Users/alklig/work/mono/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/PointerValue.cs | |
| --- /Users/alklig/work/debugger-libs/Mono.Debugger.Soft/Mono.Debugger.Soft/PointerValue.cs 2019-07-15 14:32:06.000000000 -0400 | |
| +++ /Users/alklig/work/mono/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/PointerValue.cs 2019-06-04 14:44:12.000000000 -0400 | |
| @@ -48,6 +48,16 @@ | |
| get { return type; } | |
| } | |
| + // Since protocol version 2.46 | |
| + public Value Value { | |
| + get { | |
| + if (Address == 0) | |
| + return null; | |
| + | |
| + return vm.DecodeValue (vm.conn.Pointer_GetValue (Address, Type)); | |
| + } | |
| + } | |
| + | |
| public override bool Equals (object obj) { | |
| if (obj != null && obj is PointerValue) | |
| return addr == (obj as PointerValue).addr; | |
| diff -u /Users/alklig/work/debugger-libs/Mono.Debugger.Soft/Mono.Debugger.Soft/PrimitiveValue.cs /Users/alklig/work/mono/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/PrimitiveValue.cs | |
| --- /Users/alklig/work/debugger-libs/Mono.Debugger.Soft/Mono.Debugger.Soft/PrimitiveValue.cs 2019-07-15 14:32:06.000000000 -0400 | |
| +++ /Users/alklig/work/mono/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/PrimitiveValue.cs 2019-06-04 14:44:12.000000000 -0400 | |
| @@ -1,5 +1,6 @@ | |
| using System; | |
| using System.Collections.Generic; | |
| +using System.Threading.Tasks; | |
| namespace Mono.Debugger.Soft | |
| { | |
| @@ -57,7 +58,15 @@ | |
| } | |
| public InvokeResult EndInvokeMethodWithResult (IAsyncResult asyncResult) { | |
| - return ObjectMirror.EndInvokeMethodInternalWithResult (asyncResult); | |
| + return ObjectMirror.EndInvokeMethodInternalWithResult (asyncResult); | |
| + } | |
| + | |
| + public Task<Value> InvokeMethodAsync (ThreadMirror thread, MethodMirror method, IList<Value> arguments, InvokeOptions options = InvokeOptions.None) { | |
| + return ObjectMirror.InvokeMethodAsync (vm, thread, method, this, arguments, options); | |
| + } | |
| + | |
| + public Task<InvokeResult> InvokeMethodAsyncWithResult (ThreadMirror thread, MethodMirror method, IList<Value> arguments, InvokeOptions options = InvokeOptions.None) { | |
| + return ObjectMirror.InvokeMethodAsyncWithResult (vm, thread, method, this, arguments, options); | |
| } | |
| } | |
| } | |
| \ No newline at end of file | |
| diff -u /Users/alklig/work/debugger-libs/Mono.Debugger.Soft/Mono.Debugger.Soft/PropertyInfoMirror.cs /Users/alklig/work/mono/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/PropertyInfoMirror.cs | |
| --- /Users/alklig/work/debugger-libs/Mono.Debugger.Soft/Mono.Debugger.Soft/PropertyInfoMirror.cs 2019-07-15 14:32:06.000000000 -0400 | |
| +++ /Users/alklig/work/mono/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/PropertyInfoMirror.cs 2019-06-04 14:44:12.000000000 -0400 | |
| @@ -2,8 +2,10 @@ | |
| using System.Collections.Generic; | |
| using System.Text; | |
| using System.Reflection; | |
| + | |
| +#if ENABLE_CECIL | |
| using C = Mono.Cecil; | |
| -using Mono.Cecil.Metadata; | |
| +#endif | |
| namespace Mono.Debugger.Soft | |
| { | |
| @@ -14,7 +16,10 @@ | |
| PropertyAttributes attrs; | |
| MethodMirror get_method, set_method; | |
| CustomAttributeDataMirror[] cattrs; | |
| + | |
| +#if ENABLE_CECIL | |
| C.PropertyDefinition meta; | |
| +#endif | |
| public PropertyInfoMirror (TypeMirror parent, long id, string name, MethodMirror get_method, MethodMirror set_method, PropertyAttributes attrs) : base (parent.VirtualMachine, id) { | |
| this.parent = parent; | |
| @@ -91,6 +96,7 @@ | |
| return new ParameterInfoMirror [0]; | |
| } | |
| +#if ENABLE_CECIL | |
| public C.PropertyDefinition Metadata { | |
| get { | |
| if (parent.Metadata == null) | |
| @@ -108,6 +114,7 @@ | |
| return meta; | |
| } | |
| } | |
| +#endif | |
| public CustomAttributeDataMirror[] GetCustomAttributes (bool inherit) { | |
| return GetCAttrs (null, inherit); | |
| @@ -120,8 +127,11 @@ | |
| } | |
| CustomAttributeDataMirror[] GetCAttrs (TypeMirror type, bool inherit) { | |
| + | |
| +#if ENABLE_CECIL | |
| if (cattrs == null && Metadata != null && !Metadata.HasCustomAttributes) | |
| cattrs = new CustomAttributeDataMirror [0]; | |
| +#endif | |
| // FIXME: Handle inherit | |
| if (cattrs == null) { | |
| diff -u /Users/alklig/work/debugger-libs/Mono.Debugger.Soft/Mono.Debugger.Soft/StructMirror.cs /Users/alklig/work/mono/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/StructMirror.cs | |
| --- /Users/alklig/work/debugger-libs/Mono.Debugger.Soft/Mono.Debugger.Soft/StructMirror.cs 2019-07-15 14:32:06.000000000 -0400 | |
| +++ /Users/alklig/work/mono/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/StructMirror.cs 2019-06-04 14:44:12.000000000 -0400 | |
| @@ -7,7 +7,7 @@ | |
| /* | |
| * Represents a valuetype value in the debuggee | |
| */ | |
| - public class StructMirror : Value { | |
| + public class StructMirror : Value, IInvokable { | |
| TypeMirror type; | |
| Value[] fields; | |
| @@ -84,11 +84,7 @@ | |
| } | |
| public Value EndInvokeMethod (IAsyncResult asyncResult) { | |
| - var result = ObjectMirror.EndInvokeMethodInternalWithResult (asyncResult); | |
| - var outThis = result.OutThis as StructMirror; | |
| - if (outThis != null) { | |
| - SetFields (outThis.Fields); | |
| - } | |
| + var result = EndInvokeMethodWithResult (asyncResult); | |
| return result.Result; | |
| } | |
| @@ -102,33 +98,11 @@ | |
| } | |
| public Task<Value> InvokeMethodAsync (ThreadMirror thread, MethodMirror method, IList<Value> arguments, InvokeOptions options = InvokeOptions.None) { | |
| - var tcs = new TaskCompletionSource<Value> (); | |
| - BeginInvokeMethod (thread, method, arguments, options, iar => | |
| - { | |
| - try { | |
| - tcs.SetResult (EndInvokeMethod (iar)); | |
| - } catch (OperationCanceledException) { | |
| - tcs.TrySetCanceled (); | |
| - } catch (Exception ex) { | |
| - tcs.TrySetException (ex); | |
| - } | |
| - }, null); | |
| - return tcs.Task; | |
| + return ObjectMirror.InvokeMethodAsync (vm, thread, method, this, arguments, options, EndInvokeMethod); | |
| } | |
| public Task<InvokeResult> InvokeMethodAsyncWithResult (ThreadMirror thread, MethodMirror method, IList<Value> arguments, InvokeOptions options = InvokeOptions.None) { | |
| - var tcs = new TaskCompletionSource<InvokeResult> (); | |
| - BeginInvokeMethod (thread, method, arguments, options, iar => | |
| - { | |
| - try { | |
| - tcs.SetResult (ObjectMirror.EndInvokeMethodInternalWithResult (iar)); | |
| - } catch (OperationCanceledException) { | |
| - tcs.TrySetCanceled (); | |
| - } catch (Exception ex) { | |
| - tcs.TrySetException (ex); | |
| - } | |
| - }, null); | |
| - return tcs.Task; | |
| + return ObjectMirror.InvokeMethodAsync (vm, thread, method, this, arguments, options, EndInvokeMethodWithResult); | |
| } | |
| } | |
| } | |
| diff -u /Users/alklig/work/debugger-libs/Mono.Debugger.Soft/Mono.Debugger.Soft/ThreadMirror.cs /Users/alklig/work/mono/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/ThreadMirror.cs | |
| --- /Users/alklig/work/debugger-libs/Mono.Debugger.Soft/Mono.Debugger.Soft/ThreadMirror.cs 2019-07-15 14:32:06.000000000 -0400 | |
| +++ /Users/alklig/work/mono/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/ThreadMirror.cs 2019-07-12 13:31:46.000000000 -0400 | |
| @@ -31,6 +31,7 @@ | |
| } | |
| public long ElapsedTime () { | |
| + vm.CheckProtocolVersion (2, 50); | |
| long elapsedTime = GetElapsedTime (); | |
| return elapsedTime; | |
| } | |
| @@ -39,9 +40,11 @@ | |
| cacheInvalid = true; | |
| threadStateInvalid = true; | |
| } | |
| + | |
| internal long GetElapsedTime () { | |
| return vm.conn.Thread_GetElapsedTime (id); | |
| } | |
| + | |
| internal void FetchFrames (bool mustFetch = false) { | |
| lock (fetchingLocker) { | |
| if (fetching || !cacheInvalid) | |
| @@ -165,6 +168,10 @@ | |
| throw new ArgumentNullException ("loc"); | |
| try { | |
| vm.conn.Thread_SetIP (id, loc.Method.Id, loc.ILOffset); | |
| + if (vm.conn.Version.AtLeast(2, 52)) { | |
| + InvalidateFrames(); | |
| + FetchFrames(true); | |
| + } | |
| } catch (CommandException ex) { | |
| if (ex.ErrorCode == ErrorCode.INVALID_ARGUMENT) | |
| throw new ArgumentException ("loc doesn't refer to a location in the current method of this thread.", "loc"); | |
| diff -u /Users/alklig/work/debugger-libs/Mono.Debugger.Soft/Mono.Debugger.Soft/TypeMirror.cs /Users/alklig/work/mono/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/TypeMirror.cs | |
| --- /Users/alklig/work/debugger-libs/Mono.Debugger.Soft/Mono.Debugger.Soft/TypeMirror.cs 2019-07-15 14:32:06.000000000 -0400 | |
| +++ /Users/alklig/work/mono/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/TypeMirror.cs 2019-06-04 14:44:12.000000000 -0400 | |
| @@ -1,10 +1,12 @@ | |
| using System; | |
| using System.Collections.Generic; | |
| using System.Reflection; | |
| -using C = Mono.Cecil; | |
| -using Mono.Cecil.Metadata; | |
| using System.Threading.Tasks; | |
| +#if ENABLE_CECIL | |
| +using C = Mono.Cecil; | |
| +#endif | |
| + | |
| namespace Mono.Debugger.Soft | |
| { | |
| /* | |
| @@ -12,12 +14,11 @@ | |
| * It might be better to make this a subclass of Type, but that could be | |
| * difficult as some of our methods like GetMethods () return Mirror objects. | |
| */ | |
| - public class TypeMirror : Mirror | |
| + public class TypeMirror : Mirror, IInvokable | |
| { | |
| MethodMirror[] methods; | |
| AssemblyMirror ass; | |
| ModuleMirror module; | |
| - C.TypeDefinition meta; | |
| FieldInfoMirror[] fields; | |
| PropertyInfoMirror[] properties; | |
| TypeInfo info; | |
| @@ -30,6 +31,10 @@ | |
| bool cached_base_type; | |
| bool inited; | |
| +#if ENABLE_CECIL | |
| + C.TypeDefinition meta; | |
| +#endif | |
| + | |
| internal const BindingFlags DefaultBindingFlags = | |
| BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance; | |
| @@ -613,6 +618,7 @@ | |
| return res; | |
| } | |
| +#if ENABLE_CECIL | |
| public C.TypeDefinition Metadata { | |
| get { | |
| if (meta == null) { | |
| @@ -623,6 +629,7 @@ | |
| return meta; | |
| } | |
| } | |
| +#endif | |
| TypeInfo GetInfo () { | |
| if (info == null) | |
| @@ -705,8 +712,10 @@ | |
| void AppendCustomAttrs (IList<CustomAttributeDataMirror> attrs, TypeMirror type, bool inherit) | |
| { | |
| +#if ENABLE_CECIL | |
| if (cattrs == null && Metadata != null && !Metadata.HasCustomAttributes) | |
| cattrs = new CustomAttributeDataMirror [0]; | |
| +#endif | |
| if (cattrs == null) { | |
| CattrInfo[] info = vm.conn.Type_GetCustomAttributes (id, 0, false); | |
| @@ -805,22 +814,15 @@ | |
| } | |
| public InvokeResult EndInvokeMethodWithResult (IAsyncResult asyncResult) { | |
| - return ObjectMirror.EndInvokeMethodInternalWithResult (asyncResult); | |
| + return ObjectMirror.EndInvokeMethodInternalWithResult (asyncResult); | |
| } | |
| public Task<Value> InvokeMethodAsync (ThreadMirror thread, MethodMirror method, IList<Value> arguments, InvokeOptions options = InvokeOptions.None) { | |
| - var tcs = new TaskCompletionSource<Value> (); | |
| - BeginInvokeMethod (thread, method, arguments, options, iar => | |
| - { | |
| - try { | |
| - tcs.SetResult (EndInvokeMethod (iar)); | |
| - } catch (OperationCanceledException) { | |
| - tcs.TrySetCanceled (); | |
| - } catch (Exception ex) { | |
| - tcs.TrySetException (ex); | |
| - } | |
| - }, null); | |
| - return tcs.Task; | |
| + return ObjectMirror.InvokeMethodAsync (vm, thread, method, null, arguments, options); | |
| + } | |
| + | |
| + public Task<InvokeResult> InvokeMethodAsyncWithResult (ThreadMirror thread, MethodMirror method, IList<Value> arguments, InvokeOptions options = InvokeOptions.None) { | |
| + return ObjectMirror.InvokeMethodAsyncWithResult (vm, thread, method, null, arguments, options); | |
| } | |
| public Value NewInstance (ThreadMirror thread, MethodMirror method, IList<Value> arguments) { | |
| @@ -842,6 +844,11 @@ | |
| return vm.GetObject (vm.conn.Type_CreateInstance (id)); | |
| } | |
| + // Since protocol version 2.46 | |
| + public int GetValueSize () { | |
| + return vm.conn.Type_GetValueSize (id); | |
| + } | |
| + | |
| // Since protocol version 2.11 | |
| public TypeMirror[] GetInterfaces () { | |
| if (ifaces == null) | |
| diff -u /Users/alklig/work/debugger-libs/Mono.Debugger.Soft/Mono.Debugger.Soft/VMDisconnectedException.cs /Users/alklig/work/mono/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/VMDisconnectedException.cs | |
| --- /Users/alklig/work/debugger-libs/Mono.Debugger.Soft/Mono.Debugger.Soft/VMDisconnectedException.cs 2019-07-15 14:32:06.000000000 -0400 | |
| +++ /Users/alklig/work/mono/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/VMDisconnectedException.cs 2019-06-04 14:44:12.000000000 -0400 | |
| @@ -7,4 +7,14 @@ | |
| public VMDisconnectedException () : base () { | |
| } | |
| } | |
| + | |
| + public class VMCrashException : VMDisconnectedException { | |
| + public readonly string Dump; | |
| + public readonly ulong Hash; | |
| + | |
| + public VMCrashException (string dump, ulong hash) : base () { | |
| + this.Dump = dump; | |
| + this.Hash = hash; | |
| + } | |
| + } | |
| } | |
| diff -u /Users/alklig/work/debugger-libs/Mono.Debugger.Soft/Mono.Debugger.Soft/VirtualMachine.cs /Users/alklig/work/mono/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/VirtualMachine.cs | |
| --- /Users/alklig/work/debugger-libs/Mono.Debugger.Soft/Mono.Debugger.Soft/VirtualMachine.cs 2019-07-15 14:32:06.000000000 -0400 | |
| +++ /Users/alklig/work/mono/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/VirtualMachine.cs 2019-06-27 17:29:30.000000000 -0400 | |
| @@ -5,7 +5,6 @@ | |
| using System.Diagnostics; | |
| using System.Collections; | |
| using System.Collections.Generic; | |
| -using Mono.Cecil.Metadata; | |
| namespace Mono.Debugger.Soft | |
| { | |
| @@ -110,6 +109,21 @@ | |
| } | |
| } | |
| + public EventSet GetNextEventSet (int timeoutInMilliseconds) { | |
| + lock (queue_monitor) { | |
| + if (queue.Count == 0) { | |
| + if (!Monitor.Wait (queue_monitor, timeoutInMilliseconds)) { | |
| + return null; | |
| + } | |
| + } | |
| + | |
| + current_es = null; | |
| + current_es_index = 0; | |
| + | |
| + return (EventSet)queue.Dequeue (); | |
| + } | |
| + } | |
| + | |
| [Obsolete ("Use GetNextEventSet () instead")] | |
| public T GetNextEvent<T> () where T : Event { | |
| return GetNextEvent () as T; | |
| @@ -136,8 +150,8 @@ | |
| } | |
| public void Detach () { | |
| - conn.VM_Dispose (); | |
| conn.Close (); | |
| + conn.VM_Dispose (); | |
| notify_vm_event (EventType.VMDisconnect, SuspendPolicy.None, 0, 0, null, 0); | |
| } | |
| @@ -522,43 +536,65 @@ | |
| Dictionary <long, ObjectMirror> objects; | |
| object objects_lock = new object (); | |
| - internal T GetObject<T> (long id, long domain_id, long type_id) where T : ObjectMirror { | |
| + // Return a mirror if it exists | |
| + // Does not call into the debuggee | |
| + internal T TryGetObject<T> (long id) where T : ObjectMirror { | |
| lock (objects_lock) { | |
| if (objects == null) | |
| objects = new Dictionary <long, ObjectMirror> (); | |
| ObjectMirror obj; | |
| - if (!objects.TryGetValue (id, out obj)) { | |
| - /* | |
| - * Obtain the domain/type of the object to determine the type of | |
| - * object we need to create. | |
| - */ | |
| - if (domain_id == 0 || type_id == 0) { | |
| - if (conn.Version.AtLeast (2, 5)) { | |
| - var info = conn.Object_GetInfo (id); | |
| - domain_id = info.domain_id; | |
| - type_id = info.type_id; | |
| - } else { | |
| - if (domain_id == 0) | |
| - domain_id = conn.Object_GetDomain (id); | |
| - if (type_id == 0) | |
| - type_id = conn.Object_GetType (id); | |
| - } | |
| + objects.TryGetValue (id, out obj); | |
| + return (T)obj; | |
| + } | |
| + } | |
| + | |
| + internal T GetObject<T> (long id, long domain_id, long type_id) where T : ObjectMirror { | |
| + ObjectMirror obj = null; | |
| + lock (objects_lock) { | |
| + if (objects == null) | |
| + objects = new Dictionary <long, ObjectMirror> (); | |
| + objects.TryGetValue (id, out obj); | |
| + } | |
| + | |
| + if (obj == null) { | |
| + /* | |
| + * Obtain the domain/type of the object to determine the type of | |
| + * object we need to create. Do this outside the lock. | |
| + */ | |
| + if (domain_id == 0 || type_id == 0) { | |
| + if (conn.Version.AtLeast (2, 5)) { | |
| + var info = conn.Object_GetInfo (id); | |
| + domain_id = info.domain_id; | |
| + type_id = info.type_id; | |
| + } else { | |
| + if (domain_id == 0) | |
| + domain_id = conn.Object_GetDomain (id); | |
| + if (type_id == 0) | |
| + type_id = conn.Object_GetType (id); | |
| } | |
| - AppDomainMirror d = GetDomain (domain_id); | |
| - TypeMirror t = GetType (type_id); | |
| + } | |
| + AppDomainMirror d = GetDomain (domain_id); | |
| + TypeMirror t = GetType (type_id); | |
| + | |
| + if (t.Assembly == d.Corlib && t.Namespace == "System.Threading" && t.Name == "Thread") | |
| + obj = new ThreadMirror (this, id, t, d); | |
| + else if (t.Assembly == d.Corlib && t.Namespace == "System" && t.Name == "String") | |
| + obj = new StringMirror (this, id, t, d); | |
| + else if (typeof (T) == typeof (ArrayMirror)) | |
| + obj = new ArrayMirror (this, id, t, d); | |
| + else | |
| + obj = new ObjectMirror (this, id, t, d); | |
| - if (t.Assembly == d.Corlib && t.Namespace == "System.Threading" && t.Name == "Thread") | |
| - obj = new ThreadMirror (this, id, t, d); | |
| - else if (t.Assembly == d.Corlib && t.Namespace == "System" && t.Name == "String") | |
| - obj = new StringMirror (this, id, t, d); | |
| - else if (typeof (T) == typeof (ArrayMirror)) | |
| - obj = new ArrayMirror (this, id, t, d); | |
| + // Publish | |
| + lock (objects_lock) { | |
| + ObjectMirror prev_obj; | |
| + if (objects.TryGetValue (id, out prev_obj)) | |
| + obj = prev_obj; | |
| else | |
| - obj = new ObjectMirror (this, id, t, d); | |
| - objects [id] = obj; | |
| + objects [id] = obj; | |
| } | |
| - return (T)obj; | |
| } | |
| + return (T)obj; | |
| } | |
| internal T GetObject<T> (long id) where T : ObjectMirror { | |
| @@ -573,6 +609,10 @@ | |
| return GetObject <ThreadMirror> (id); | |
| } | |
| + internal ThreadMirror TryGetThread (long id) { | |
| + return TryGetObject <ThreadMirror> (id); | |
| + } | |
| + | |
| Dictionary <long, FieldInfoMirror> fields; | |
| object fields_lock = new object (); | |
| @@ -616,8 +656,11 @@ | |
| } | |
| internal Value DecodeValue (ValueImpl v, Dictionary<int, Value> parent_vtypes) { | |
| - if (v.Value != null) | |
| + if (v.Value != null) { | |
| + if (Version.AtLeast (2, 46) && v.Type == ElementType.Ptr) | |
| + return new PointerValue(this, GetType(v.Klass), (long)v.Value); | |
| return new PrimitiveValue (this, v.Value); | |
| + } | |
| switch (v.Type) { | |
| case ElementType.Void: | |
| @@ -682,8 +725,11 @@ | |
| duplicates.Add (v); | |
| return new ValueImpl { Type = ElementType.ValueType, Klass = (v as StructMirror).Type.Id, Fields = EncodeValues ((v as StructMirror).Fields, duplicates) }; | |
| + } else if (v is PointerValue) { | |
| + PointerValue val = (PointerValue)v; | |
| + return new ValueImpl { Type = ElementType.Ptr, Klass = val.Type.Id, Value = val.Address }; | |
| } else { | |
| - throw new NotSupportedException (); | |
| + throw new NotSupportedException ("Value of type " + v.GetType()); | |
| } | |
| } | |
| @@ -730,6 +776,11 @@ | |
| l.Add (new ThreadStartEvent (vm, req_id, id)); | |
| break; | |
| case EventType.ThreadDeath: | |
| + // Avoid calling GetThread () since it might call into the debuggee | |
| + // and we can't do that in the event handler | |
| + var thread = vm.TryGetThread (id); | |
| + if (thread != null) | |
| + thread.InvalidateFrames (); | |
| vm.InvalidateThreadCache (); | |
| l.Add (new ThreadDeathEvent (vm, req_id, id)); | |
| break; | |
| @@ -771,6 +822,9 @@ | |
| case EventType.UserLog: | |
| l.Add (new UserLogEvent (vm, req_id, thread_id, ei.Level, ei.Category, ei.Message)); | |
| break; | |
| + case EventType.Crash: | |
| + l.Add (new CrashEvent (vm, req_id, thread_id, ei.Dump, ei.Hash)); | |
| + break; | |
| } | |
| } | |
| diff -u /Users/alklig/work/debugger-libs/Mono.Debugger.Soft/Mono.Debugger.Soft/VirtualMachineManager.cs /Users/alklig/work/mono/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/VirtualMachineManager.cs | |
| --- /Users/alklig/work/debugger-libs/Mono.Debugger.Soft/Mono.Debugger.Soft/VirtualMachineManager.cs 2019-07-15 14:32:06.000000000 -0400 | |
| +++ /Users/alklig/work/mono/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/VirtualMachineManager.cs 2017-10-18 14:16:57.000000000 -0400 | |
| @@ -96,8 +96,11 @@ | |
| info.FileName = "valgrind"; | |
| info.UseShellExecute = false; | |
| - info.StandardErrorEncoding = Encoding.UTF8; | |
| - info.StandardOutputEncoding = Encoding.UTF8; | |
| + if (info.RedirectStandardError) | |
| + info.StandardErrorEncoding = Encoding.UTF8; | |
| + | |
| + if (info.RedirectStandardOutput) | |
| + info.StandardOutputEncoding = Encoding.UTF8; | |
| ITargetProcess p; | |
| if (options != null && options.CustomProcessLauncher != null) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment