Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Chambers <joncham@gmail.com>2018-02-25 09:14:11 +0300
committerZoltan Varga <vargaz@gmail.com>2018-02-25 09:14:11 +0300
commit67c1708677af8c5a3a8955937775a61de9e36e0f (patch)
tree76f2996f3cd0ac42485bcafc254787390b56b8d4 /mcs/class/Mono.Debugger.Soft
parent9bbe5e5e5f807884ea66aa762dae3f8c240652e2 (diff)
Add PointerValue.Value to dereference and access pointer value. (#6840)
Diffstat (limited to 'mcs/class/Mono.Debugger.Soft')
-rw-r--r--mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/Connection.cs47
-rw-r--r--mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/PointerValue.cs10
-rw-r--r--mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/TypeMirror.cs5
-rw-r--r--mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/VirtualMachine.cs10
-rw-r--r--mcs/class/Mono.Debugger.Soft/Test/dtest-app.cs19
-rw-r--r--mcs/class/Mono.Debugger.Soft/Test/dtest.cs36
6 files changed, 116 insertions, 11 deletions
diff --git a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/Connection.cs b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/Connection.cs
index 602c827091d..e480555252e 100644
--- a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/Connection.cs
+++ b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/Connection.cs
@@ -420,7 +420,7 @@ namespace Mono.Debugger.Soft
* with newer runtimes, and vice versa.
*/
internal const int MAJOR_VERSION = 2;
- internal const int MINOR_VERSION = 45;
+ internal const int MINOR_VERSION = 46;
enum WPSuspendPolicy {
NONE = 0,
@@ -442,7 +442,8 @@ namespace Mono.Debugger.Soft
TYPE = 23,
MODULE = 24,
FIELD = 25,
- EVENT = 64
+ EVENT = 64,
+ POINTER = 65
}
enum EventKind {
@@ -574,7 +575,8 @@ namespace Mono.Debugger.Soft
GET_INTERFACES = 16,
GET_INTERFACE_MAP = 17,
IS_INITIALIZED = 18,
- CREATE_INSTANCE = 19
+ CREATE_INSTANCE = 19,
+ GET_VALUE_SIZE = 20
}
enum CmdField {
@@ -606,6 +608,10 @@ namespace Mono.Debugger.Soft
GET_CHARS = 3
}
+ enum CmdPointer {
+ GET_VALUE = 1
+ }
+
enum CmdObjectRef {
GET_TYPE = 1,
GET_VALUES = 2,
@@ -730,10 +736,12 @@ namespace Mono.Debugger.Soft
}
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
@@ -845,9 +853,16 @@ namespace Mono.Debugger.Soft
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:
@@ -1283,7 +1298,7 @@ namespace Mono.Debugger.Soft
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 ();
@@ -1502,7 +1517,7 @@ namespace Mono.Debugger.Soft
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;
@@ -1549,7 +1564,7 @@ namespace Mono.Debugger.Soft
if (reply_packets.ContainsKey (packetId)) {
byte[] reply = reply_packets [packetId];
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);
@@ -2297,6 +2312,11 @@ namespace Mono.Debugger.Soft
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
*/
@@ -2475,7 +2495,16 @@ namespace Mono.Debugger.Soft
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
diff --git a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/PointerValue.cs b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/PointerValue.cs
index 3fa359fcb5d..2cf9dfa418b 100644
--- a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/PointerValue.cs
+++ b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/PointerValue.cs
@@ -48,6 +48,16 @@ namespace Mono.Debugger.Soft
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 --git a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/TypeMirror.cs b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/TypeMirror.cs
index f92dca03932..78c11a8d9af 100644
--- a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/TypeMirror.cs
+++ b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/TypeMirror.cs
@@ -842,6 +842,11 @@ namespace Mono.Debugger.Soft
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 --git a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/VirtualMachine.cs b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/VirtualMachine.cs
index 1eaaac8ec9d..9d60855a31a 100644
--- a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/VirtualMachine.cs
+++ b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/VirtualMachine.cs
@@ -616,8 +616,11 @@ namespace Mono.Debugger.Soft
}
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 +685,11 @@ namespace Mono.Debugger.Soft
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());
}
}
diff --git a/mcs/class/Mono.Debugger.Soft/Test/dtest-app.cs b/mcs/class/Mono.Debugger.Soft/Test/dtest-app.cs
index 97202372c77..33ef36b6d5c 100644
--- a/mcs/class/Mono.Debugger.Soft/Test/dtest-app.cs
+++ b/mcs/class/Mono.Debugger.Soft/Test/dtest-app.cs
@@ -145,6 +145,12 @@ public struct AStruct : ITest2 {
}
}
+
+public struct BlittableStruct {
+ public int i;
+ public double d;
+}
+
public class GClass<T> {
public T field;
public static T static_field;
@@ -349,6 +355,7 @@ public class Tests : TestsBase, ITest2
gc_suspend ();
set_ip ();
step_filters ();
+ pointers ();
if (args.Length > 0 && args [0] == "local-reflect")
local_reflect ();
if (args.Length > 0 && args [0] == "domain-test")
@@ -1761,6 +1768,18 @@ public class Tests : TestsBase, ITest2
static void step_out_void_async_2 ()
{
}
+
+ public static unsafe void pointer_arguments (int* a, BlittableStruct* s) {
+ *a = 0;
+ }
+
+ [MethodImplAttribute (MethodImplOptions.NoInlining)]
+ public static unsafe void pointers () {
+ int[] a = new [] {1,2,3};
+ BlittableStruct s = new BlittableStruct () { i = 2, d = 3.0 };
+ fixed (int* pa = a)
+ pointer_arguments (pa, &s);
+ }
}
public class SentinelClass : MarshalByRefObject {
diff --git a/mcs/class/Mono.Debugger.Soft/Test/dtest.cs b/mcs/class/Mono.Debugger.Soft/Test/dtest.cs
index 75fdd8f6d07..4633ce2ae58 100644
--- a/mcs/class/Mono.Debugger.Soft/Test/dtest.cs
+++ b/mcs/class/Mono.Debugger.Soft/Test/dtest.cs
@@ -325,6 +325,8 @@ public class DebuggerTests
Assert.AreEqual (expected, (val as StringMirror).Value);
} else if (val is StructMirror && (val as StructMirror).Type.Name == "IntPtr") {
AssertValue (expected, (val as StructMirror).Fields [0]);
+ } else if (val is PointerValue) {
+ Assert.AreEqual (expected, (val as PointerValue).Address);
} else {
Assert.IsTrue (val is PrimitiveValue);
Assert.AreEqual (expected, (val as PrimitiveValue).Value);
@@ -4433,5 +4435,39 @@ public class DebuggerTests
// DummyCall
assert_location (e, "Call");
}
+
+ [Test]
+ public void Pointer_GetValue () {
+ var e = run_until ("pointer_arguments");
+ var frame = e.Thread.GetFrames () [0];
+
+ var param = frame.Method.GetParameters()[0];
+ Assert.AreEqual("Int32*", param.ParameterType.Name);
+
+ var pointerValue = frame.GetValue(param) as PointerValue;
+ Assert.AreEqual("Int32*", pointerValue.Type.Name);
+
+ AssertValue(1, pointerValue.Value);
+
+ var pointerValue2 = new PointerValue (pointerValue.VirtualMachine, pointerValue.Type, pointerValue.Address + pointerValue.Type.GetElementType().GetValueSize());
+
+ AssertValue(2, pointerValue2.Value);
+
+
+ param = frame.Method.GetParameters()[1];
+ Assert.AreEqual("BlittableStruct*", param.ParameterType.Name);
+
+ pointerValue = frame.GetValue(param) as PointerValue;
+ Assert.AreEqual("BlittableStruct*", pointerValue.Type.Name);
+
+ var structValue = pointerValue.Value as StructMirror;
+ Assert.AreEqual("BlittableStruct", structValue.Type.Name);
+
+ object f = structValue.Fields[0];
+ AssertValue (2, f);
+ f = structValue.Fields[1];
+ AssertValue (3.0, f);
+
+ }
} // class DebuggerTests
} // namespace