/// <summary>
            // Sets the value of one or more local variables. Each variable must be visible at the current frame code index.
            // For primitive values, the value's type must match the variable's type exactly. For object values, there must
            // be a widening reference conversion from the value's type to the variable's type and the variable's type must
            // be loaded.
            // Even if local variable information is not available, values can be set, if the front-end is able to determine
            // the correct local variable index. (Typically, this index can be determined for method arguments from the
            // method signature without access to the local variable table information.)
            /// </summary>
            public Task SetValuesAsync(ThreadId threadId, FrameId frameId, params SlotValue[] slotValues)
            {
                var conn = ConnectionOrError;

                DLog.Debug(DContext.DebuggerLibCommands, () => string.Format("StackFrame.SetValues {0}", string.Join(", ", slotValues.Select(x => x.ToString()))));
                var t = conn.SendAsync(JdwpPacket.CreateCommand(conn, Nr, 2, 4000 /* we don't know how long the packet is going to be... */,
                                                                x =>
                {
                    var data = x.Data;
                    threadId.WriteTo(data);
                    frameId.WriteTo(data);
                    data.SetInt(slotValues.Length);
                    foreach (var value in slotValues)
                    {
                        value.Write(data);
                    }
                    x.Length = data.Offset;
                }));

                return(t.ContinueWith(x =>
                {
                    x.ForwardException();
                    var result = x.Result;
                    result.ThrowOnError();
                }));
            }
Exemple #2
0
 /// <summary>
 /// Read an untagged value.
 /// </summary>
 private static object ReadUntaggedValue(JdwpPacket.DataReaderWriter readerWriter, Jdwp.Tag tag)
 {
     switch (tag)
     {
         case Jdwp.Tag.Array:
         case Jdwp.Tag.Object:
         case Jdwp.Tag.String:
         case Jdwp.Tag.Thread:
         case Jdwp.Tag.ThreadGroup:
         case Jdwp.Tag.ClassLoader:
         case Jdwp.Tag.ClassObject:
             return new ObjectId(readerWriter);
         case Jdwp.Tag.Byte:
             return readerWriter.GetByte();
         case Jdwp.Tag.Char:
             return (char)readerWriter.GetInt16();
         case Jdwp.Tag.Float:
             return readerWriter.GetFloat();
         case Jdwp.Tag.Double:
             return readerWriter.GetDouble();
         case Jdwp.Tag.Int:
             return readerWriter.GetInt();
         case Jdwp.Tag.Long:
             return readerWriter.GetLong();
         case Jdwp.Tag.Short:
             return readerWriter.GetInt16();
         case Jdwp.Tag.Void:
             return null;
         case Jdwp.Tag.Boolean:
             return readerWriter.GetBoolean();
         default:
             throw new ArgumentException("Unknown tag " + (int)tag);
     }
 }
            /// <summary>
            /// Gets the current call stack of the thread with given id.
            /// </summary>
            public Task <List <Tuple <FrameId, Location> > > FramesAsync(ThreadId id, int length = -1)
            {
                var conn     = ConnectionOrError;
                var sizeInfo = conn.GetIdSizeInfo();
                var t        = conn.SendAsync(JdwpPacket.CreateCommand(conn, Nr, 6, sizeInfo.ObjectIdSize + 8,
                                                                       x => {
                    id.WriteTo(x.Data);
                    x.Data.SetInt(0);      // start frame
                    x.Data.SetInt(length); // length -1 == all
                }));

                return(t.ContinueWith(x => {
                    x.ForwardException();
                    var result = x.Result;
                    result.ThrowOnError();

                    var count = result.Data.GetInt();
                    var list = new List <Tuple <FrameId, Location> >(count);
                    for (var i = 0; i < count; i++)
                    {
                        var frame = new FrameId(result.Data, sizeInfo);
                        var location = new Location(result.Data);
                        list.Add(Tuple.Create(frame, location));
                    }
                    return list;
                }));
            }
            /// <summary>
            /// Returns variable information for the method, including generic signatures for the variables. The variable table includes arguments and
            /// locals declared within the method. For instance methods, the "this" reference is included in the table. Also, synthetic variables may be
            /// present. Generic signatures are described in the signature attribute section in the Java Virtual Machine Specification, 3rd Edition.
            /// Since JDWP version 1.5.
            /// </summary>
            public Task <List <VariableInfo> > VariableTableWithGenericAsync(ReferenceTypeId typeId, MethodId methodId)
            {
                var conn = ConnectionOrError;
                var t    = conn.SendAsync(JdwpPacket.CreateCommand(conn, Nr, 5, typeId.Size + methodId.Size,
                                                                   x => {
                    var data = x.Data;
                    typeId.WriteTo(data);
                    methodId.WriteTo(data);
                }));

                return(t.ContinueWith(x => {
                    x.ForwardException();
                    var result = x.Result;
                    result.ThrowOnError();
                    var data = result.Data;
                    var argCnt = data.GetInt();
                    var count = data.GetInt();
                    var list = new List <VariableInfo>(count);
                    for (var i = 0; i < count; i++)
                    {
                        var codeIndex = data.GetLong();
                        var name = data.GetString();
                        var signature = data.GetString();
                        var genericSignature = data.GetString();
                        var length = data.GetInt();
                        var slot = data.GetInt();
                        list.Add(new VariableInfo(codeIndex, name, signature, genericSignature, length, slot));
                    }
                    return list;
                }));
            }
        private void HandleCompositeCommand(JdwpPacket packet)
        {
            var data = packet.Data;
            var suspendPolicy = (Jdwp.SuspendPolicy) data.GetByte();
            var count = data.GetInt();

            for (var i = 0; i < count; i++)
            {
                var eventKind = (Jdwp.EventKind) data.GetByte();
                JdwpEvent evt;
                switch (eventKind)
                {
                    case Jdwp.EventKind.VmInit:
                        evt = new VmStart(data);
                        break;
                    case Jdwp.EventKind.SingleStep:
                        evt = new SingleStep(data);
                        break;
                    case Jdwp.EventKind.BreakPoint:
                        evt = new Breakpoint(data);
                        break;
                    case Jdwp.EventKind.MethodEntry:
                        evt = new MethodEntry(data);
                        break;
                    case Jdwp.EventKind.MethodExit:
                        evt = new MethodExit(data);
                        break;
                    case Jdwp.EventKind.Exception:
                        evt = new Exception(data);
                        break;
                    case Jdwp.EventKind.ThreadStart:
                        evt = new ThreadStart(data);
                        break;
                    case Jdwp.EventKind.ThreadEnd:
                        evt = new ThreadDeath(data);
                        break;
                    case Jdwp.EventKind.ClassPrepare:
                        evt = new ClassPrepare(data);
                        break;
                    case Jdwp.EventKind.ClassUnload:
                        evt = new ClassUnload(data);
                        break;
                    case Jdwp.EventKind.FieldAccess:
                        evt = new FieldAccess(data);
                        break;
                    case Jdwp.EventKind.FieldModification:
                        evt = new FieldModification(data);
                        break;
                    case Jdwp.EventKind.VmDeath:
                        evt = new VmDeath(data);
                        break;
                    default:
                        throw new ArgumentException("Unknown event kind in compositive command " + (int)eventKind);
                }
                DLog.Debug(DContext.DebuggerLibDebugger, "JDWP event {0} {1}", eventKind, evt);
                Task.Factory.StartNew(() => {
                    evt.Accept(compositeCommandProcessor, suspendPolicy);
                });
            }
        }
            /// <summary>
            /// Returns the value of one or more instance fields. Each field must be member of the object's type or one of its superclasses,
            /// superinterfaces, or implemented interfaces. Access control is not enforced; for example, the values of private fields can be obtained.
            /// </summary>
            public Task <List <Value> > GetValuesAsync(ObjectId objectId, FieldId[] fields)
            {
                var conn     = ConnectionOrError;
                var sizeInfo = conn.GetIdSizeInfo();
                var t        = conn.SendAsync(JdwpPacket.CreateCommand(conn, Nr, 2, objectId.Size + 4 + (sizeInfo.FieldIdSize * fields.Length),
                                                                       x => {
                    var data = x.Data;
                    objectId.WriteTo(data);
                    data.SetInt(fields.Length);
                    foreach (var fieldId in fields)
                    {
                        fieldId.WriteTo(data);
                    }
                }));

                return(t.ContinueWith(x => {
                    x.ForwardException();
                    var result = x.Result;
                    result.ThrowOnError();
                    var data = result.Data;
                    var count = data.GetInt();
                    var list = new List <Value>(count);
                    for (var i = 0; i < count; i++)
                    {
                        var value = new Value(data);
                        list.Add(value);
                    }
                    return list;
                }));
            }
            /// <summary>
            /// Returns the value of one or more local variables in a given frame. Each variable must be visible at the frame's code index.
            /// Even if local variable information is not available, values can be retrieved if the front-end is able to determine the correct
            /// local variable index. (Typically, this index can be determined for method arguments from the method signature without access to
            /// the local variable table information.)
            /// </summary>
            public Task <List <Value> > GetValuesAsync(ThreadId threadId, FrameId frameId, SlotRequest[] slots)
            {
                var conn = ConnectionOrError;

                DLog.Debug(DContext.DebuggerLibCommands, () => string.Format("StackFrame.GetValues {0}", string.Join(", ", slots.Select(x => x.ToString()))));
                var t = conn.SendAsync(JdwpPacket.CreateCommand(conn, Nr, 1, threadId.Size + frameId.Size + 4 + (slots.Length * 5),
                                                                x => {
                    var data = x.Data;
                    threadId.WriteTo(data);
                    frameId.WriteTo(data);
                    data.SetInt(slots.Length);
                    foreach (var slot in slots)
                    {
                        data.SetInt(slot.Slot);
                        data.SetByte((byte)slot.Tag);
                    }
                }));

                return(t.ContinueWith(x => {
                    x.ForwardException();
                    var result = x.Result;
                    result.ThrowOnError();
                    var data = result.Data;
                    var count = data.GetInt();
                    var list = new List <Value>(count);
                    for (var i = 0; i < count; i++)
                    {
                        var value = new Value(data);
                        list.Add(value);
                    }
                    return list;
                }));
            }
Exemple #8
0
            /// <summary>
            /// Returns reference types for all classes currently loaded by the target VM.
            /// </summary>
            public Task <List <ClassInfo> > AllClassesWithGenericAsync()
            {
                var conn     = ConnectionOrError;
                var sizeInfo = conn.GetIdSizeInfo();
                var t        = conn.SendAsync(JdwpPacket.CreateCommand(conn, Nr, 20, 0));

                return(t.ContinueWith(x => {
                    x.ForwardException();
                    var result = x.Result;
                    result.ThrowOnError();
                    var data = result.Data;
                    var count = data.GetInt();
                    var list = new List <ClassInfo>();
                    while (count > 0)
                    {
                        count--;
                        var typeId = ReferenceTypeId.Read(data);
                        var signature = data.GetString();
                        var genericSignature = data.GetString();
                        var status = data.GetInt();
                        list.Add(new ClassInfo(typeId, signature, genericSignature, (Jdwp.ClassStatus)status));
                    }
                    return list;
                }));
            }
Exemple #9
0
            /// <summary>
            /// Returns information for each method in a reference type. Inherited methods are not included. The list of methods will include constructors
            /// (identified with the name "&lt;init&gt;"), the initialization method (identified with the name "&lt;clinit&gt;") if present, and any synthetic methods
            /// created by the compiler. Methods are returned in the order they occur in the class file.
            /// </summary>
            public Task <List <MethodInfo> > MethodsAsync(ReferenceTypeId id)
            {
                var conn     = ConnectionOrError;
                var sizeInfo = conn.GetIdSizeInfo();
                var t        = conn.SendAsync(JdwpPacket.CreateCommand(conn, Nr, 15, sizeInfo.ReferenceTypeIdSize, x => id.WriteTo(x.Data)));

                return(t.ContinueWith(x => {
                    x.ForwardException();
                    var result = x.Result;
                    result.ThrowOnError();
                    var data = result.Data;
                    var count = data.GetInt();
                    var list = new List <MethodInfo>(count);
                    for (var i = 0; i < count; i++)
                    {
                        var methodId = new MethodId(data);
                        var name = data.GetString();
                        var signature = data.GetString();
                        var genericSignature = data.GetString();
                        var accessFlags = data.GetInt();
                        list.Add(new MethodInfo(methodId, name, signature, genericSignature, accessFlags));
                    }
                    return list;
                }));
            }
Exemple #10
0
            /// <summary>
            /// Returns a range of array components. The specified range must be within the bounds of the array.
            /// </summary>
            public Task <List <Value> > GetValuesAsync(ObjectId objectId, string elementSignature, int firstIndex, int length)
            {
                var conn = ConnectionOrError;
                var t    = conn.SendAsync(JdwpPacket.CreateCommand(conn, Nr, 2, objectId.Size + 8,
                                                                   x => {
                    var data = x.Data;
                    objectId.WriteTo(data);
                    data.SetInt(firstIndex);
                    data.SetInt(length);
                }));

                return(t.ContinueWith(x => {
                    x.ForwardException();
                    var result = x.Result;
                    result.ThrowOnError();
                    var data = result.Data;
                    var arrayElementTag = (Jdwp.Tag)data.GetByte();
                    var arrayElementIsObject = !arrayElementTag.IsPrimitive();
                    var count = data.GetInt();
                    var list = new List <Value>(count);
                    for (var i = 0; i < count; i++)
                    {
                        var value = arrayElementIsObject ? new Value(data) : new Value(data, arrayElementTag);
                        list.Add(value);
                    }
                    return list;
                }));
            }
Exemple #11
0
 /// <summary>
 /// Handle the given non-DDM, non-reply packet.
 /// </summary>
 private void PacketHandler(JdwpPacket packet)
 {
     if ((packet.CommandSet == 64) && (packet.Command == 100))
     {
         // Composite command
         HandleCompositeCommand(packet);
     }
 }
Exemple #12
0
 /// <summary>
 /// Send the entire packet towards the target VM.
 /// </summary>
 protected internal void AddToWriteQueue(JdwpPacket packet)
 {
     packet.Id = GetNextId();
     lock (writeQueueLock)
     {
         writeQueue.Enqueue(packet);
         Monitor.Pulse(writeQueueLock);
     }
 }
            /// <summary>
            /// Removes all set breakpoints, a no-op if there are no breakpoints set.
            /// </summary>
            public Task ClearAllBreakpointsAsync()
            {
                var conn = ConnectionOrError;
                var t    = conn.SendAsync(JdwpPacket.CreateCommand(conn, Nr, 3, 0));

                return(t.ContinueWith(x => {
                    x.ForwardException();
                    var result = x.Result;
                    result.ThrowOnError();
                }));
            }
            /// <summary>
            /// Returns the immediate superclass of a class.
            /// </summary>
            public Task <ClassId> SuperclassAsync(ReferenceTypeId id)
            {
                var conn = ConnectionOrError;
                var t    = conn.SendAsync(JdwpPacket.CreateCommand(conn, Nr, 1, id.Size, x => id.WriteTo(x.Data)));

                return(t.ContinueWith(x => {
                    x.ForwardException();
                    var result = x.Result;
                    result.ThrowOnError();
                    return new ClassId(result.Data);
                }));
            }
            /// <summary>
            /// Resume the thread with given id.
            /// </summary>
            public Task ResumeAsync(ThreadId id)
            {
                var conn     = ConnectionOrError;
                var sizeInfo = conn.GetIdSizeInfo();
                var t        = conn.SendAsync(JdwpPacket.CreateCommand(conn, Nr, 3, sizeInfo.ObjectIdSize, x => id.WriteTo(x.Data)));

                return(t.ContinueWith(x => {
                    x.ForwardException();
                    var result = x.Result;
                    result.ThrowOnError();
                }));
            }
Exemple #16
0
            /// <summary>
            /// Returns the JNI signature of a reference type. JNI signature formats are described in the Java Native Inteface Specification
            /// For primitive classes the returned signature is the signature of the corresponding primitive type; for example, "I" is returned
            /// as the signature of the class represented by java.lang.Integer.TYPE.
            /// </summary>
            public Task <string> SignatureAsync(ReferenceTypeId id)
            {
                var conn     = ConnectionOrError;
                var sizeInfo = conn.GetIdSizeInfo();
                var t        = conn.SendAsync(JdwpPacket.CreateCommand(conn, Nr, 1, sizeInfo.ReferenceTypeIdSize, x => id.WriteTo(x.Data)));

                return(t.ContinueWith(x => {
                    x.ForwardException();
                    var result = x.Result;
                    result.ThrowOnError();
                    return result.Data.GetString();
                }));
            }
Exemple #17
0
            /// <summary>
            /// Request exit.
            /// </summary>
            public void Exit(int exitCode)
            {
                // Send exit command
                var conn = ConnectionOrError;

                conn.SendAsync(JdwpPacket.CreateCommand(conn, Nr, 10, 4, x => x.Data.SetInt(exitCode)));

                // Wait until write queue is empty
                conn.WaitUntilWriteQueueEmpty();

                // Disconnect
                Debugger.Disconnect();
            }
Exemple #18
0
        /// <summary>
        /// Create a command packet.
        /// </summary>
        public static JdwpPacket CreateCommand(IJdwpServerInfo serverInfo, int commandSet, int command, int dataLength, Action <JdwpPacket> initialize = null)
        {
            var data   = new byte[HeaderLength + dataLength];
            var packet = new JdwpPacket(serverInfo, data, 0)
            {
                CommandSet = commandSet, Command = command, Length = data.Length
            };

            if (initialize != null)
            {
                initialize(packet);
            }
            return(packet);
        }
Exemple #19
0
        /// <summary>
        /// Try to find a packet in the given buffer.
        /// </summary>
        /// <returns>Null if not found</returns>
        private static JdwpPacket FindPacket(IJdwpServerInfo serverInfo, byte[] buffer, int length)
        {
            if (length < JdwpPacket.HeaderLength)
            {
                return(null);
            }
            var pkt = new JdwpPacket(serverInfo, buffer, 0);

            if (pkt.Length > length)
            {
                return(null);
            }
            return(new JdwpPacket(serverInfo, buffer, 0, true));
        }
            /// <summary>
            /// Clear an event request. See JDWP.EventKind for a complete list of events that can be cleared. Only the event request matching the
            /// specified event kind and requestID is cleared. If there isn't a matching event request the command is a no-op and does not result
            /// in an error. Automatically generated events do not have a corresponding event request and may not be cleared using this command.
            /// </summary>
            public Task ClearAsync(Jdwp.EventKind eventKind, int requestId)
            {
                var conn = ConnectionOrError;
                var t    = conn.SendAsync(JdwpPacket.CreateCommand(conn, Nr, 2, 5, x => {
                    var data = x.Data;
                    data.SetByte((byte)eventKind);
                    data.SetInt(requestId);
                }));

                return(t.ContinueWith(x => {
                    x.ForwardException();
                    var result = x.Result;
                    result.ThrowOnError();
                }));
            }
            /// <summary>
            /// Gets the status of a thread.
            /// </summary>
            public Task <ThreadStatusInfo> StatusAsync(ThreadId id)
            {
                var conn     = ConnectionOrError;
                var sizeInfo = conn.GetIdSizeInfo();
                var t        = conn.SendAsync(JdwpPacket.CreateCommand(conn, Nr, 4, sizeInfo.ObjectIdSize, x => id.WriteTo(x.Data)));

                return(t.ContinueWith(x => {
                    x.ForwardException();
                    var result = x.Result;
                    result.ThrowOnError();
                    var threadStatus = result.Data.GetInt();
                    var suspendStatus = result.Data.GetInt();
                    return new ThreadStatusInfo((Jdwp.ThreadStatus)threadStatus, (Jdwp.SuspendStatus)suspendStatus);
                }));
            }
        /// <summary>
        /// Request ID size information
        /// </summary>
        public Task <IdSizeInfo> IdSizesAsync()
        {
            var t = SendAsync(JdwpPacket.CreateCommand(this, 1, 7, 0));

            return(t.ContinueWith(x => {
                x.ForwardException();
                var result = x.Result;
                result.ThrowOnError();
                var fieldIdSize = result.Data.GetInt();
                var methodIdSize = result.Data.GetInt();
                var objectIdSize = result.Data.GetInt();
                var referenceTypeIdSize = result.Data.GetInt();
                var frameIdSize = result.Data.GetInt();
                return new IdSizeInfo(fieldIdSize, methodIdSize, objectIdSize, referenceTypeIdSize, frameIdSize);
            }));
        }
            /// <summary>
            /// Returns the runtime type of the object. The runtime type will be a class or an array.
            /// </summary>
            public Task <ReferenceTypeId> ReferenceTypeAsync(ObjectId objectId)
            {
                var conn = ConnectionOrError;
                var t    = conn.SendAsync(JdwpPacket.CreateCommand(conn, Nr, 1, objectId.Size,
                                                                   x => {
                    var data = x.Data;
                    objectId.WriteTo(data);
                }));

                return(t.ContinueWith(x => {
                    x.ForwardException();
                    var result = x.Result;
                    result.ThrowOnError();
                    return ReferenceTypeId.Read(result.Data);
                }));
            }
        /// <summary>
        /// Request version data
        /// </summary>
        public Task <VersionInfo> VersionAsync()
        {
            var t = SendAsync(JdwpPacket.CreateCommand(this, 1, 1, 0));

            return(t.ContinueWith(x => {
                x.ForwardException();
                var result = x.Result;
                result.ThrowOnError();
                var description = result.Data.GetString();
                var major = result.Data.GetInt();
                var minor = result.Data.GetInt();
                var vmVersion = result.Data.GetString();
                var vmName = result.Data.GetString();
                return new VersionInfo(description, major, minor, vmVersion, vmName);
            }));
        }
Exemple #25
0
            /// <summary>
            /// Gets all threads in the VM.
            /// </summary>
            public Task <List <ThreadId> > AllThreadsAsync()
            {
                var conn = ConnectionOrError;
                var t    = conn.SendAsync(JdwpPacket.CreateCommand(conn, Nr, 4, 0));

                return(t.ContinueWith(x => {
                    x.ForwardException();
                    var result = x.Result;
                    result.ThrowOnError();
                    var count = result.Data.GetInt();
                    var list = new List <ThreadId>();
                    while (count > 0)
                    {
                        count--;
                        list.Add(new ThreadId(result.Data));
                    }
                    return list;
                }));
            }
            /// <summary>
            /// Returns the value of one or more local variables in a given frame. Each variable must be visible at the frame's code index.
            /// Even if local variable information is not available, values can be retrieved if the front-end is able to determine the correct
            /// local variable index. (Typically, this index can be determined for method arguments from the method signature without access to
            /// the local variable table information.)
            /// </summary>
            public Task <List <Value> > GetValuesAsync(ThreadId threadId, FrameId frameId, SlotRequest[] slots)
            {
                var conn = ConnectionOrError;

                DLog.Debug(DContext.DebuggerLibCommands, () => string.Format("StackFrame.GetValues {0}", string.Join(", ", slots.Select(x => x.ToString()))));
                var t = conn.SendAsync(JdwpPacket.CreateCommand(conn, Nr, 1, threadId.Size + frameId.Size + 4 + (slots.Length * 5),
                                                                x => {
                    var data = x.Data;
                    threadId.WriteTo(data);
                    frameId.WriteTo(data);
                    data.SetInt(slots.Length);
                    foreach (var slot in slots)
                    {
                        if (slot.Slot == 1000)
                        {
                            // I have seen this crash the VM on a CyanogenMod Android 4.4.4
                            // Samsung GT-I9195. Might be a bug in CyanogenMod.
                            // https://android.googlesource.com/platform/art/+/ffcd9d25199a944625bd3c9a766349c23dcbdb66/runtime/debugger.cc
                            DLog.Debug(DContext.DebuggerLibEvent, "accessing variable with Slot=1000");
                        }

                        data.SetInt(slot.Slot);
                        data.SetByte((byte)slot.Tag);
                    }
                }));

                return(t.ContinueWith(x => {
                    x.ForwardException();
                    var result = x.Result;
                    result.ThrowOnError();
                    var data = result.Data;
                    var count = data.GetInt();
                    var list = new List <Value>(count);
                    for (var i = 0; i < count; i++)
                    {
                        var value = new Value(data);
                        list.Add(value);
                    }
                    return list;
                }));
            }
            /// <summary>
            /// Returns the reference type reflected by this class object.
            /// </summary>
            public Task <ReferenceTypeId> ReflectedTypeAsync(ObjectId classObjectId)
            {
                var conn = ConnectionOrError;
                var t    = conn.SendAsync(JdwpPacket.CreateCommand(conn, Nr, 1, classObjectId.Size, x => classObjectId.WriteTo(x.Data)));

                return(t.ContinueWith(x => {
                    x.ForwardException();
                    var result = x.Result;
                    result.ThrowOnError();

                    var kind = (Jdwp.TypeTag)x.Result.Data.GetByte();
                    if (kind == Jdwp.TypeTag.Array)
                    {
                        return (ReferenceTypeId) new ArrayTypeId(result.Data);
                    }
                    if (kind == Jdwp.TypeTag.Interface)
                    {
                        return new InterfaceId(result.Data);
                    }
                    return new ClassId(result.Data);
                }));
            }
            /// <summary>
            /// Set an event request. When the event described by this request occurs, an event is sent from the target VM.
            /// If an event occurs that has not been requested then it is not sent from the target VM. The two exceptions to this are the
            /// VM Start Event and the VM Death Event which are automatically generated events - see Composite Command for further details.
            /// </summary>
            /// <returns>Task that returns a requestId</returns>
            public Task <int> SetAsync(Jdwp.EventKind eventKind, Jdwp.SuspendPolicy suspendPolicy, params EventModifier[] modifiers)
            {
                var conn     = ConnectionOrError;
                var sizeInfo = conn.GetIdSizeInfo();
                var size     = 6 + modifiers.Sum(x => x.DataSize);
                var t        = conn.SendAsync(JdwpPacket.CreateCommand(conn, Nr, 1, size, x => {
                    var data = x.Data;
                    data.SetByte((byte)eventKind);
                    data.SetByte((byte)suspendPolicy);
                    data.SetInt(modifiers.Length);
                    foreach (var modifier in modifiers)
                    {
                        modifier.WriteTo(data);
                    }
                }));

                return(t.ContinueWith(x => {
                    x.ForwardException();
                    var result = x.Result;
                    result.ThrowOnError();
                    return result.Data.GetInt();
                }));
            }
Exemple #29
0
            /// <summary>
            /// Returns reference types that match the given signature.
            /// </summary>
            public Task <List <ClassInfo> > ClassBySignatureAsync(string signature)
            {
                var conn     = ConnectionOrError;
                var sizeInfo = conn.GetIdSizeInfo();
                var t        = conn.SendAsync(JdwpPacket.CreateCommand(conn, Nr, 2, JdwpPacket.DataReaderWriter.GetStringSize(signature), x => x.Data.SetString(signature)));

                return(t.ContinueWith(x => {
                    x.ForwardException();
                    var result = x.Result;
                    result.ThrowOnError();
                    var data = result.Data;
                    var count = data.GetInt();
                    var list = new List <ClassInfo>();
                    while (count > 0)
                    {
                        count--;
                        var typeId = ReferenceTypeId.Read(data);
                        var status = data.GetInt();
                        list.Add(new ClassInfo(typeId, signature, signature, (Jdwp.ClassStatus)status));
                    }
                    return list;
                }));
            }
Exemple #30
0
 /// <summary>
 /// Read an untagged value.
 /// </summary>
 private static void WriteValue(JdwpPacket.DataReaderWriter data, Jdwp.Tag tag, object obj)
 {
     switch (tag)
     {
         //case Jdwp.Tag.Array:
         //case Jdwp.Tag.Object:
         //case Jdwp.Tag.String:
         //case Jdwp.Tag.Thread:
         //case Jdwp.Tag.ThreadGroup:
         //case Jdwp.Tag.ClassLoader:
         //case Jdwp.Tag.ClassObject:
         //    return new ObjectId(readerWriter);
         case Jdwp.Tag.Byte:
             data.SetByte((byte)obj);
             break;
         case Jdwp.Tag.Short:
         case Jdwp.Tag.Char:
             data.SetInt16((int) obj);
             break;
         //case Jdwp.Tag.Float:
         //    readerWriter.GetFloat(); //?
         //    break;
         //case Jdwp.Tag.Double:
         //    return readerWriter.SetDouble(); //?
         case Jdwp.Tag.Int:
             data.SetInt((int)obj);
             break;
         case Jdwp.Tag.Long:
             data.SetLong((long) obj);
             break;
         case Jdwp.Tag.Boolean:
             data.SetBoolean((bool)obj);
             break;
         default:
             throw new ArgumentException("unsupported tag " + tag);
     }
 }
Exemple #31
0
 /// <summary>
 /// Write the modifier to the writer of a packet.
 /// In this method the kind byte is written override to write additional data.
 /// </summary>
 internal override void WriteTo(JdwpPacket.DataReaderWriter writer)
 {
     base.WriteTo(writer);
     classId.WriteTo(writer);
     fieldId.WriteTo(writer);
 }
Exemple #32
0
 /// <summary>
 /// Read a tagged value.
 /// </summary>
 public Value(JdwpPacket.DataReaderWriter readerWriter)
 {
     Tag = (Jdwp.Tag) readerWriter.GetByte();
     ValueObject = ReadUntaggedValue(readerWriter, Tag);
 }
Exemple #33
0
 /// <summary>
 /// Write the modifier to the writer of a packet.
 /// In this method the kind byte is written override to write additional data.
 /// </summary>
 internal override void WriteTo(JdwpPacket.DataReaderWriter writer)
 {
     base.WriteTo(writer);
     instanceId.WriteTo(writer);
 }
Exemple #34
0
        /// <summary>
        /// Write queued packets
        /// </summary>
        private void WriteLoop()
        {
            var myThread   = Thread.CurrentThread;
            var errorCount = 0;

            while ((writeThread == myThread))
            {
                // Too many errors or disconnected?
                if ((errorCount > MaxWriteErrors) || !tcpClient.Connected)
                {
                    Disconnect.Fire(this);
                    return;
                }

                JdwpPacket packet = null;
                lock (writeQueueLock)
                {
                    if ((writeQueue.Count == 0) || (state == States.AwaitingHandshake))
                    {
                        // Signal all waiters
                        Monitor.PulseAll(writeQueueLock);

                        // Now wait ourselves for new packets
                        Monitor.Wait(writeQueueLock);
                    }
                    else
                    {
                        packet = writeQueue.Dequeue();
                    }
                }

                // Disconnected?
                if (!tcpClient.Connected)
                {
                    Disconnect.Fire(this);
                    return;
                }

                if ((packet != null) && (writeThread == myThread))
                {
                    var attempt   = 0;
                    var succeeded = false;
                    while ((attempt < WriteAttempts) && !succeeded)
                    {
                        try
                        {
                            attempt++;
                            DLog.Debug(DContext.DebuggerLibJdwpConnection, "Write {0}", packet);
                            packet.WriteTo(tcpClient.GetStream());
                            succeeded  = true;
                            errorCount = Math.Max(errorCount - 1, 0);
                        }
                        catch
                        {
                        }
                    }
                    if (!succeeded)
                    {
                        errorCount++;
                    }
                }
            }
        }
Exemple #35
0
 /// <summary>
 /// Default ctor
 /// </summary>
 internal DataReaderWriter(JdwpPacket packet, int offset)
 {
     this.packet = packet;
     this.Offset = offset;
 }
Exemple #36
0
            /// <summary>
            /// Resume the execution of the application running in the target VM.
            /// </summary>
            public Task ResumeAsync()
            {
                var conn = ConnectionOrError;

                return(conn.SendAsync(JdwpPacket.CreateCommand(conn, Nr, 9, 0)));
            }
Exemple #37
0
 /// <summary>
 /// Create a command packet.
 /// </summary>
 public static JdwpPacket CreateCommand(IJdwpServerInfo serverInfo, int commandSet, int command, int dataLength, Action<JdwpPacket> initialize = null)
 {
     var data = new byte[HeaderLength + dataLength];
     var packet = new JdwpPacket(serverInfo, data, 0) { CommandSet = commandSet, Command = command, Length = data.Length };
     if (initialize != null)
     {
         initialize(packet);
     }
     return packet;
 }
Exemple #38
0
 /// <summary>
 /// Write the modifier to the writer of a packet.
 /// In this method the kind byte is written override to write additional data.
 /// </summary>
 internal override void WriteTo(JdwpPacket.DataReaderWriter writer)
 {
     base.WriteTo(writer);
     location.WriteTo(writer);
 }
Exemple #39
0
 /// <summary>
 /// Write the modifier to the writer of a packet.
 /// In this method the kind byte is written override to write additional data.
 /// </summary>
 internal override void WriteTo(JdwpPacket.DataReaderWriter writer)
 {
     base.WriteTo(writer);
     writer.SetInt(count);
 }
Exemple #40
0
 /// <summary>
 /// Write the modifier to the writer of a packet.
 /// In this method the kind byte is written override to write additional data.
 /// </summary>
 internal override void WriteTo(JdwpPacket.DataReaderWriter writer)
 {
     base.WriteTo(writer);
     threadId.WriteTo(writer);
     writer.SetInt((int) stepSize);
     writer.SetInt((int) stepDepth);
 }
Exemple #41
0
 /// <summary>
 /// writes slot and value.
 /// </summary>
 /// <param name="data"></param>
 public void Write(JdwpPacket.DataReaderWriter data)
 {
     data.SetInt(Slot);
     WriteValue(data);
 }
Exemple #42
0
 /// <summary>
 /// writes only the value, without the slot.
 /// </summary>
 /// <param name="data"></param>
 public void WriteValue(JdwpPacket.DataReaderWriter data)
 {
     data.SetByte((byte)Tag);
     WriteValue(data, Tag, Value);
 }
        private void HandleCompositeCommand(JdwpPacket packet)
        {
            var data = packet.Data;
            var suspendPolicy = (Jdwp.SuspendPolicy) data.GetByte();
            var count = data.GetInt();

            for (var i = 0; i < count; i++)
            {
                var eventKind = (Jdwp.EventKind) data.GetByte();
                JdwpEvent evt;
                switch (eventKind)
                {
                    case Jdwp.EventKind.VmInit:
                        evt = new VmStart(data);
                        break;
                    case Jdwp.EventKind.SingleStep:
                        evt = new SingleStep(data);
                        break;
                    case Jdwp.EventKind.BreakPoint:
                        evt = new Breakpoint(data);
                        break;
                    case Jdwp.EventKind.MethodEntry:
                        evt = new MethodEntry(data);
                        break;
                    case Jdwp.EventKind.MethodExit:
                        evt = new MethodExit(data);
                        break;
                    case Jdwp.EventKind.Exception:
                        evt = new Exception(data);
                        break;
                    case Jdwp.EventKind.ThreadStart:
                        evt = new ThreadStart(data);
                        break;
                    case Jdwp.EventKind.ThreadEnd:
                        evt = new ThreadDeath(data);
                        break;
                    case Jdwp.EventKind.ClassPrepare:
                        evt = new ClassPrepare(data);
                        break;
                    case Jdwp.EventKind.ClassUnload:
                        evt = new ClassUnload(data);
                        break;
                    case Jdwp.EventKind.FieldAccess:
                        evt = new FieldAccess(data);
                        break;
                    case Jdwp.EventKind.FieldModification:
                        evt = new FieldModification(data);
                        break;
                    case Jdwp.EventKind.VmDeath:
                        evt = new VmDeath(data);
                        break;
                    default:
                        throw new ArgumentException("Unknown event kind in compositive command " + (int)eventKind);
                }
                DLog.Debug(DContext.DebuggerLibDebugger, "JDWP event {0} {1}", eventKind, evt);
                Task.Factory.StartNew(() => {
                    evt.Accept(compositeCommandProcessor, suspendPolicy);
                }).ContinueWith(task =>
                {
                    DLog.Error(DContext.DebuggerLibJdwpConnection, "HandleCompositeCommand: Internal failure on event processing. SuspendPolicy was {1}; IsCancelled={0}. Exception={1}", suspendPolicy, task.IsCanceled, task.Exception);
                    if (suspendPolicy != Jdwp.SuspendPolicy.None)
                    {
                        // we should better resume the VM, as the command handler may have failed to do so.
                        if(Connected)
                            VirtualMachine.ResumeAsync();
                    }
                }, TaskContinuationOptions.NotOnRanToCompletion);
            }
        }
Exemple #44
0
 /// <summary>
 /// Write the modifier to the writer of a packet.
 /// In this method the kind byte is written override to write additional data.
 /// </summary>
 internal override void WriteTo(JdwpPacket.DataReaderWriter writer)
 {
     base.WriteTo(writer);
     exceptionClassId.WriteTo(writer);
     writer.SetBoolean(caught);
     writer.SetBoolean(uncaught);
 }
Exemple #45
0
 /// <summary>
 /// Default ctor
 /// </summary>
 internal DataReaderWriter(JdwpPacket packet, int offset)
 {
     this.packet = packet;
     this._offset = offset;
 }
Exemple #46
0
 /// <summary>
 /// Write the modifier to the writer of a packet.
 /// In this method the kind byte is written override to write additional data.
 /// </summary>
 internal override void WriteTo(JdwpPacket.DataReaderWriter writer)
 {
     base.WriteTo(writer);
     threadId.WriteTo(writer);
 }
Exemple #47
0
 /// <summary>
 /// Handle the given non-DDM, non-reply packet.
 /// </summary>
 private void PacketHandler(JdwpPacket packet)
 {
     if ((packet.CommandSet == 64) && (packet.Command == 100))
     {
         // Composite command
         HandleCompositeCommand(packet);
     }
 }
Exemple #48
0
 /// <summary>
 /// Read an untagged value.
 /// </summary>
 public Value(JdwpPacket.DataReaderWriter readerWriter, Jdwp.Tag tag)
 {
     Tag = tag;
     ValueObject = ReadUntaggedValue(readerWriter, tag);
 }
Exemple #49
0
 /// <summary>
 /// Write the modifier to the writer of a packet.
 /// In this method the kind byte is written override to write additional data.
 /// </summary>
 internal override void WriteTo(JdwpPacket.DataReaderWriter writer)
 {
     base.WriteTo(writer);
     writer.SetString(classPattern);
 }
Exemple #50
0
 /// <summary>
 /// Default ctor
 /// </summary>
 internal DataReaderWriter(JdwpPacket packet, int offset)
     : base(packet, offset)
 {
 }
Exemple #51
0
 /// <summary>
 /// Write the modifier to the writer of a packet.
 /// In this method the kind byte is written override to write additional data.
 /// </summary>
 internal virtual void WriteTo(JdwpPacket.DataReaderWriter writer)
 {
     writer.SetByte((byte) kind);
 }