public string[] names;
public int[] live_range_start;
public int[] live_range_end;
+ public int[] scopes_start;
+ public int[] scopes_end;
}
struct PropInfo {
[Flags]
enum InvokeFlags {
- NONE = 0x0,
- DISABLE_BREAKPOINTS = 0x1,
- SINGLE_THREADED = 0x2
+ NONE = 0,
+ DISABLE_BREAKPOINTS = 1,
+ SINGLE_THREADED = 2,
+ OUT_THIS = 4,
+ OUT_ARGS = 8,
+ VIRTUAL = 16,
}
enum ElementType {
ERR_UNLOADED = 103,
ERR_NO_INVOCATION = 104,
ABSENT_INFORMATION = 105,
- NO_SEQ_POINT_AT_IL_OFFSET = 106
+ NO_SEQ_POINT_AT_IL_OFFSET = 106,
+ INVOKE_ABORTED = 107
}
public class ErrorHandlerEventArgs : EventArgs {
static readonly bool EnableConnectionLogging = !String.IsNullOrEmpty (Environment.GetEnvironmentVariable ("MONO_SDB_LOG"));
static int ConnectionId;
- readonly StreamWriter LoggingStream = EnableConnectionLogging ?
- new StreamWriter (string.Format ("/tmp/sdb_conn_log_{0}", ConnectionId++), false) : null;
+ readonly StreamWriter LoggingStream;
/*
* Th version of the wire-protocol implemented by the library. The library
* with newer runtimes, and vice versa.
*/
internal const int MAJOR_VERSION = 2;
- internal const int MINOR_VERSION = 34;
+ internal const int MINOR_VERSION = 44;
enum WPSuspendPolicy {
NONE = 0,
enum CmdStackFrame {
GET_VALUES = 1,
GET_THIS = 2,
- SET_VALUES = 3
+ SET_VALUES = 3,
+ GET_DOMAIN = 4,
+ SET_THIS = 5,
}
enum CmdArrayRef {
return res;
}
+ public string ReadUTF16String () {
+ int len = decode_int (packet, ref offset);
+ string res = new String (Encoding.Unicode.GetChars (packet, offset, len));
+ offset += len;
+ return res;
+ }
+
public ValueImpl ReadValue () {
ElementType etype = (ElementType)ReadByte ();
reply_cbs = new Dictionary<int, ReplyCallback> ();
reply_cb_counts = new Dictionary<int, int> ();
reply_packets_monitor = new Object ();
+ if (EnableConnectionLogging) {
+ var path = Environment.GetEnvironmentVariable ("MONO_SDB_LOG");
+ if (path.Contains ("{0}")) {
+ //C:\SomeDir\sdbLog{0}.txt -> C:\SomeDir\sdbLog1.txt
+ LoggingStream = new StreamWriter (string.Format (path, ConnectionId++), false);
+ } else if (Path.HasExtension (path)) {
+ //C:\SomeDir\sdbLog.txt -> C:\SomeDir\sdbLog1.txt
+ LoggingStream = new StreamWriter (Path.GetDirectoryName (path) + Path.DirectorySeparatorChar + Path.GetFileNameWithoutExtension (path) + ConnectionId++ + "." + Path.GetExtension (path), false);
+ } else {
+ //C:\SomeDir\sdbLog -> C:\SomeDir\sdbLog1
+ LoggingStream = new StreamWriter (path + ConnectionId++, false);
+ }
+ }
}
protected abstract int TransportReceive (byte[] buf, int buf_offset, int len);
bool disconnected;
+ internal ManualResetEvent DisconnectedEvent = new ManualResetEvent (false);
+
void receiver_thread_main () {
while (!closed) {
try {
lock (reply_packets_monitor) {
disconnected = true;
+ DisconnectedEvent.Set ();
Monitor.PulseAll (reply_packets_monitor);
TransportClose ();
}
//
public void StartBuffering () {
buffer_packets = true;
- if (Version.AtLeast (3, 34))
+ if (Version.AtLeast (2, 34))
VM_StartBuffering ();
}
public void StopBuffering () {
- if (Version.AtLeast (3, 34))
+ if (Version.AtLeast (2, 34))
VM_StopBuffering ();
buffer_packets = false;
WritePackets (buffered_packets);
if (EnableConnectionLogging) {
- LoggingStream.WriteLine (String.Format ("Sent {1} packets.", buffered_packets.Count));
+ LoggingStream.WriteLine (String.Format ("Sent {0} packets.", buffered_packets.Count));
LoggingStream.Flush ();
}
buffered_packets.Clear ();
SendReceive (CommandSet.VM, (int)CmdVM.SET_PROTOCOL_VERSION, new PacketWriter ().WriteInt (major).WriteInt (minor));
}
- internal long[] VM_GetThreads () {
- var res = SendReceive (CommandSet.VM, (int)CmdVM.ALL_THREADS, null);
- int len = res.ReadInt ();
- long[] arr = new long [len];
- for (int i = 0; i < len; ++i)
- arr [i] = res.ReadId ();
- return arr;
+ internal void VM_GetThreads (Action<long[]> resultCallaback) {
+ Send (CommandSet.VM, (int)CmdVM.ALL_THREADS, null, (res) => {
+ int len = res.ReadInt ();
+ long[] arr = new long [len];
+ for (int i = 0; i < len; ++i)
+ arr [i] = res.ReadId ();
+ resultCallaback(arr);
+ }, 1);
}
internal void VM_Suspend () {
}
}
- internal delegate void InvokeMethodCallback (ValueImpl v, ValueImpl exc, ErrorCode error, object state);
+ internal delegate void InvokeMethodCallback (ValueImpl v, ValueImpl exc, ValueImpl out_this, ValueImpl[] out_args, ErrorCode error, object state);
+
+ void read_invoke_res (PacketReader r, out ValueImpl v, out ValueImpl exc, out ValueImpl out_this, out ValueImpl[] out_args) {
+ int resflags = r.ReadByte ();
+ v = null;
+ exc = null;
+ out_this = null;
+ out_args = null;
+ if (resflags == 0) {
+ exc = r.ReadValue ();
+ } else {
+ v = r.ReadValue ();
+ if ((resflags & 2) != 0)
+ out_this = r.ReadValue ();
+ if ((resflags & 4) != 0) {
+ int nargs = r.ReadInt ();
+ out_args = new ValueImpl [nargs];
+ for (int i = 0; i < nargs; ++i)
+ out_args [i] = r.ReadValue ();
+ }
+ }
+ }
internal int VM_BeginInvokeMethod (long thread, long method, ValueImpl this_arg, ValueImpl[] arguments, InvokeFlags flags, InvokeMethodCallback callback, object state) {
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) {
- ValueImpl v, exc;
+ ValueImpl v, exc, out_this = null;
+ ValueImpl[] out_args = null;
if (r.ErrorCode != 0) {
- callback (null, null, (ErrorCode)r.ErrorCode, state);
+ callback (null, null, null, null, (ErrorCode)r.ErrorCode, state);
} else {
- if (r.ReadByte () == 0) {
- exc = r.ReadValue ();
- v = null;
- } else {
- v = r.ReadValue ();
- exc = null;
- }
-
- callback (v, exc, 0, state);
+ read_invoke_res (r, out v, out exc, out out_this, out out_args);
+ callback (v, exc, out_this, out_args, 0, state);
}
}, 1);
}
w.WriteValues (arguments [i]);
}
return Send (CommandSet.VM, (int)CmdVM.INVOKE_METHODS, w, delegate (PacketReader r) {
- ValueImpl v, exc;
+ ValueImpl v, exc, out_this = null;
+ ValueImpl[] out_args = null;
if (r.ErrorCode != 0) {
- callback (null, null, (ErrorCode)r.ErrorCode, state);
+ callback (null, null, null, null, (ErrorCode)r.ErrorCode, state);
} else {
- if (r.ReadByte () == 0) {
- exc = r.ReadValue ();
- v = null;
- } else {
- v = r.ReadValue ();
- exc = null;
- }
-
- callback (v, exc, 0, state);
+ read_invoke_res (r, out v, out exc, out out_this, out out_args);
+ callback (v, exc, out_this, out_args, 0, state);
}
}, methods.Length);
}
var res = SendReceive (CommandSet.METHOD, (int)CmdMethod.GET_LOCALS_INFO, new PacketWriter ().WriteId (id));
LocalsInfo info = new LocalsInfo ();
+
+ if (Version.AtLeast (2, 43)) {
+ int nscopes = res.ReadInt ();
+ info.scopes_start = new int [nscopes];
+ info.scopes_end = new int [nscopes];
+ int last_start = 0;
+ for (int i = 0; i < nscopes; ++i) {
+ info.scopes_start [i] = last_start + res.ReadInt ();
+ info.scopes_end [i] = info.scopes_start [i] + res.ReadInt ();
+ last_start = info.scopes_start [i];
+ }
+ }
+
int nlocals = res.ReadInt ();
info.types = new long [nlocals];
for (int i = 0; i < nlocals; ++i)
return SendReceive (CommandSet.THREAD, (int)CmdThread.GET_NAME, new PacketWriter ().WriteId (id)).ReadString ();
}
- internal FrameInfo[] Thread_GetFrameInfo (long id, int start_frame, int length) {
- var res = SendReceive (CommandSet.THREAD, (int)CmdThread.GET_FRAME_INFO, new PacketWriter ().WriteId (id).WriteInt (start_frame).WriteInt (length));
- int count = res.ReadInt ();
-
- var frames = new FrameInfo [count];
- for (int i = 0; i < count; ++i) {
- var f = new FrameInfo ();
- f.id = res.ReadInt ();
- f.method = res.ReadId ();
- f.il_offset = res.ReadInt ();
- f.flags = (StackFrameFlags)res.ReadByte ();
- frames [i] = f;
- }
-
- return frames;
+ 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 ();
+ var frames = new FrameInfo[count];
+ for (int i = 0; i < count; ++i) {
+ var f = new FrameInfo ();
+ f.id = res.ReadInt ();
+ f.method = res.ReadId ();
+ f.il_offset = res.ReadInt ();
+ f.flags = (StackFrameFlags)res.ReadByte ();
+ frames [i] = f;
+ }
+ resultCallaback (frames);
+ }, 1);
}
internal int Thread_GetState (long id) {
SendReceive (CommandSet.STACK_FRAME, (int)CmdStackFrame.SET_VALUES, new PacketWriter ().WriteId (thread_id).WriteId (id).WriteInt (len).WriteInts (pos).WriteValues (values));
}
+ internal long StackFrame_GetDomain (long thread_id, long id) {
+ return SendReceive (CommandSet.STACK_FRAME, (int)CmdStackFrame.GET_DOMAIN, new PacketWriter ().WriteId (thread_id).WriteId (id)).ReadId ();
+ }
+
+ internal void StackFrame_SetThis (long thread_id, long id, ValueImpl value) {
+ SendReceive (CommandSet.STACK_FRAME, (int)CmdStackFrame.SET_THIS, new PacketWriter ().WriteId (thread_id).WriteId (id).WriteValue (value));
+ }
+
/*
* ARRAYS
*/
* STRINGS
*/
internal string String_GetValue (long id) {
- return SendReceive (CommandSet.STRING_REF, (int)CmdStringRef.GET_VALUE, new PacketWriter ().WriteId (id)).ReadString ();
+ var r = SendReceive (CommandSet.STRING_REF, (int)CmdStringRef.GET_VALUE, new PacketWriter ().WriteId (id));
+
+ bool is_utf16 = false;
+ if (Version.AtLeast (2, 41))
+ is_utf16 = r.ReadByte () == 1;
+
+ if (is_utf16)
+ return r.ReadUTF16String ();
+ else
+ return r.ReadString ();
}
internal int String_GetLength (long id) {
{
closed = true;
disconnected = true;
+ DisconnectedEvent.Set ();
TransportClose ();
}
}