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:
-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
-rw-r--r--mono/mini/debugger-agent.c66
7 files changed, 178 insertions, 15 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
diff --git a/mono/mini/debugger-agent.c b/mono/mini/debugger-agent.c
index 0113fbcde38..c3c32c98558 100644
--- a/mono/mini/debugger-agent.c
+++ b/mono/mini/debugger-agent.c
@@ -275,7 +275,7 @@ typedef struct {
#define HEADER_LENGTH 11
#define MAJOR_VERSION 2
-#define MINOR_VERSION 45
+#define MINOR_VERSION 46
typedef enum {
CMD_SET_VM = 1,
@@ -291,7 +291,8 @@ typedef enum {
CMD_SET_TYPE = 23,
CMD_SET_MODULE = 24,
CMD_SET_FIELD = 25,
- CMD_SET_EVENT = 64
+ CMD_SET_EVENT = 64,
+ CMD_SET_POINTER = 65
} CommandSet;
typedef enum {
@@ -496,7 +497,8 @@ typedef enum {
CMD_TYPE_GET_INTERFACES = 16,
CMD_TYPE_GET_INTERFACE_MAP = 17,
CMD_TYPE_IS_INITIALIZED = 18,
- CMD_TYPE_CREATE_INSTANCE = 19
+ CMD_TYPE_CREATE_INSTANCE = 19,
+ CMD_TYPE_GET_VALUE_SIZE = 20
} CmdType;
typedef enum {
@@ -520,6 +522,10 @@ typedef enum {
} CmdString;
typedef enum {
+ CMD_POINTER_GET_VALUE = 1
+} CmdPointer;
+
+typedef enum {
CMD_OBJECT_REF_GET_TYPE = 1,
CMD_OBJECT_REF_GET_VALUES = 2,
CMD_OBJECT_REF_IS_COLLECTED = 3,
@@ -6333,6 +6339,8 @@ buffer_add_value_full (Buffer *buf, MonoType *t, void *addr, MonoDomain *domain,
buffer_add_byte (buf, t->type);
buffer_add_long (buf, val);
+ if (CHECK_PROTOCOL_VERSION(2, 46))
+ buffer_add_typeid (buf, domain, mono_class_from_mono_type (t));
break;
}
handle_ref:
@@ -9003,6 +9011,13 @@ type_commands_internal (int command, MonoClass *klass, MonoDomain *domain, guint
buffer_add_objid (buf, obj);
break;
}
+ case CMD_TYPE_GET_VALUE_SIZE: {
+ int32_t value_size;
+
+ value_size = mono_class_value_size (klass, NULL);
+ buffer_add_int (buf, value_size);
+ break;
+ }
default:
return ERR_NOT_IMPLEMENTED;
}
@@ -9999,6 +10014,34 @@ string_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
}
static ErrorCode
+pointer_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
+{
+ ErrorCode err;
+ gint64 addr;
+ MonoClass* klass;
+ MonoDomain* domain = NULL;
+
+ switch (command) {
+ case CMD_POINTER_GET_VALUE:
+ addr = decode_long (p, &p, end);
+ klass = decode_typeid (p, &p, end, &domain, &err);
+ if (err != ERR_NONE)
+ return err;
+
+ if (klass->byval_arg.type != MONO_TYPE_PTR)
+ return ERR_INVALID_ARGUMENT;
+
+ buffer_add_value (buf, &klass->element_class->byval_arg, (gpointer)addr, domain);
+
+ break;
+ default:
+ return ERR_NOT_IMPLEMENTED;
+ }
+
+ return ERR_NONE;
+}
+
+static ErrorCode
object_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
{
ERROR_DECL (error);
@@ -10199,6 +10242,8 @@ command_set_to_string (CommandSet command_set)
return "FIELD";
case CMD_SET_EVENT:
return "EVENT";
+ case CMD_SET_POINTER:
+ return "POINTER";
default:
return "";
}
@@ -10295,7 +10340,9 @@ static const char* type_cmds_str[] = {
"GET_METHODS_BY_NAME_FLAGS",
"GET_INTERFACES",
"GET_INTERFACE_MAP",
- "IS_INITIALIZED"
+ "IS_INITIALIZED",
+ "CREATE_INSTANCE",
+ "GET_VALUE_SIZE"
};
static const char* stack_frame_cmds_str[] = {
@@ -10318,6 +10365,10 @@ static const char* string_cmds_str[] = {
"GET_CHARS"
};
+static const char* pointer_cmds_str[] = {
+ "GET_VALUE"
+};
+
static const char* object_cmds_str[] = {
"GET_TYPE",
"GET_VALUES",
@@ -10391,6 +10442,10 @@ cmd_to_string (CommandSet set, int command)
cmds = event_cmds_str;
cmds_len = G_N_ELEMENTS (event_cmds_str);
break;
+ case CMD_SET_POINTER:
+ cmds = pointer_cmds_str;
+ cmds_len = G_N_ELEMENTS (pointer_cmds_str);
+ break;
default:
return NULL;
}
@@ -10568,6 +10623,9 @@ debugger_thread (void *arg)
case CMD_SET_STRING_REF:
err = string_commands (command, p, end, &buf);
break;
+ case CMD_SET_POINTER:
+ err = pointer_commands (command, p, end, &buf);
+ break;
case CMD_SET_OBJECT_REF:
err = object_commands (command, p, end, &buf);
break;