Example #1
0
		/// <summary>
		/// Handle chunks not recognized by handlers.  The handleChunk() method
		/// in sub-classes should call this if the chunk type isn't recognized.
		/// </summary>
		protected internal virtual void handleUnknownChunk(Client client, int type, ByteBuffer data, bool isReply, int msgId)
		{
			if (type == CHUNK_FAIL)
			{
				int errorCode, msgLen;
				string msg;

                errorCode = data.getInt();
                msgLen = data.getInt();
				msg = getString(data, msgLen);
				Log.w("ddms", "WARNING: failure code=" + errorCode + " msg=" + msg);
			}
			else
			{
				Log.w("ddms", "WARNING: received unknown chunk " + name(type) + ": len=" + data.limit + ", reply=" + isReply + ", msgId=0x" + msgId.toHexString());
			}
			Log.w("ddms", "         client " + client + ", handler " + this);
		}
Example #2
0
		/// <summary>
		/// Handle a reply to our FEAT request.
		/// </summary>
		private static void handleFEAT(Client client, ByteBuffer data)
		{
			int featureCount;
			int i;

            featureCount = data.getInt();
			for (i = 0; i < featureCount; i++)
			{
                int len = data.getInt();
				string feature = getString(data, len);
				client.clientData.addFeature(feature);

				Log.d("ddm-hello", "Feature: " + feature);
			}
		}
Example #3
0
		/*
		 * Handle a reply to our HELO message.
		 */
		private static void handleHELO(Client client, ByteBuffer data)
		{
			int version, pid, vmIdentLen, appNameLen;
			string vmIdent, appName;

            version = data.getInt();
            pid = data.getInt();
            vmIdentLen = data.getInt();
            appNameLen = data.getInt();

			vmIdent = getString(data, vmIdentLen);
			appName = getString(data, appNameLen);

			Log.d("ddm-hello", "HELO: v=" + version + ", pid=" + pid + ", vm='" + vmIdent + "', app='" + appName + "'");

			ClientData cd = client.clientData;

			lock (cd)
			{
				if (cd.pid == pid)
				{
					cd.vmIdentifier = vmIdent;
					cd.clientDescription = appName;
					cd.isDdmAware(true);
				}
				else
				{
					Log.e("ddm-hello", "Received pid (" + pid + ") does not match client pid (" + cd.pid + ")");
				}
			}

			client = checkDebuggerPortForAppName(client, appName);

			if (client != null)
			{
				client.update(Client.CHANGE_NAME);
			}
		}
Example #4
0
		/*
		 * Handle a reply to our APNM message.
		 */
		private static void handleAPNM(Client client, ByteBuffer data)
		{
			int appNameLen;
			string appName;

            appNameLen = data.getInt();
			appName = getString(data, appNameLen);

			Log.d("ddm-appname", "APNM: app='" + appName + "'");

			ClientData cd = client.clientData;
			lock (cd)
			{
				cd.clientDescription = appName;
			}

			client = checkDebuggerPortForAppName(client, appName);

			if (client != null)
			{
				client.update(Client.CHANGE_NAME);
			}
		}
Example #5
0
		/// <summary>
		/// Reads a string table out of "data".
		/// 
		/// This is just a serial collection of strings, each of which is a
		/// four-byte length followed by UTF-16 data.
		/// </summary>
		private void readStringTable(ByteBuffer data, string[] strings)
		{
			int count = strings.Length;
			int i;

			for (i = 0; i < count; i++)
			{
                int nameLen = data.getInt();
				string descriptor = getString(data, nameLen);
				strings[i] = descriptorToDot(descriptor);
			}
		}
Example #6
0
		/*
		 * Handle a REcent ALlocation response.
		 *
		 * Message header (all values big-endian):
		 *   (1b) message header len (to allow future expansion); includes itself
		 *   (1b) entry header len
		 *   (1b) stack frame len
		 *   (2b) number of entries
		 *   (4b) offset to string table from start of message
		 *   (2b) number of class name strings
		 *   (2b) number of method name strings
		 *   (2b) number of source file name strings
		 *   For each entry:
		 *     (4b) total allocation size
		 *     (2b) threadId
		 *     (2b) allocated object's class name index
		 *     (1b) stack depth
		 *     For each stack frame:
		 *       (2b) method's class name
		 *       (2b) method name
		 *       (2b) method source file
		 *       (2b) line number, clipped to 32767; -2 if native; -1 if no source
		 *   (xb) class name strings
		 *   (xb) method name strings
		 *   (xb) source file strings
		 *
		 *   As with other DDM traffic, strings are sent as a 4-byte length
		 *   followed by UTF-16 data.
		 */
		private void handleREAL(Client client, ByteBuffer data)
		{
			Log.e("ddm-heap", "*** Received " + name(CHUNK_REAL));
			int messageHdrLen, entryHdrLen, stackFrameLen;
			int numEntries, offsetToStrings;
			int numClassNames, numMethodNames, numFileNames;

			/*
			 * Read the header.
			 */
			messageHdrLen = (data.get() & 0xff);
			entryHdrLen = (data.get() & 0xff);
			stackFrameLen = (data.get() & 0xff);
			numEntries = (data.getShort() & 0xffff);
            offsetToStrings = data.getInt();
			numClassNames = (data.getShort() & 0xffff);
			numMethodNames = (data.getShort()& 0xffff);
			numFileNames = (data.getShort()& 0xffff);


			/*
			 * Skip forward to the strings and read them.
			 */
			data.position = offsetToStrings;

			string[] classNames = new string[numClassNames];
			string[] methodNames = new string[numMethodNames];
			string[] fileNames = new string[numFileNames];

			readStringTable(data, classNames);
			readStringTable(data, methodNames);
			//System.out.println("METHODS: "
			//    + java.util.Arrays.deepToString(methodNames));
			readStringTable(data, fileNames);

			/*
			 * Skip back to a point just past the header and start reading
			 * entries.
			 */
			data.position = messageHdrLen;

			List<AllocationInfo> list = new List<AllocationInfo>(numEntries);
			int allocNumber = numEntries; // order value for the entry. This is sent in reverse order.
			for (int i = 0; i < numEntries; i++)
			{
				int totalSize;
				int threadId, classNameIndex, stackDepth;

                totalSize = data.getInt();
				threadId = (data.getShort() & 0xffff);
				classNameIndex = (data.getShort() & 0xffff);
				stackDepth = (data.get() & 0xff);
				/* we've consumed 9 bytes; gobble up any extra */
				for (int skip = 9; skip < entryHdrLen; skip++)
				{
					data.get();
				}

				StackTraceElement[] steArray = new StackTraceElement[stackDepth];

				/*
				 * Pull out the stack trace.
				 */
				for (int sti = 0; sti < stackDepth; sti++)
				{
					int methodClassNameIndex, methodNameIndex;
					int methodSourceFileIndex;
					short lineNumber;
					string methodClassName, methodName, methodSourceFile;

					methodClassNameIndex = (data.getShort() & 0xffff);
					methodNameIndex = (data.getShort()& 0xffff);
					methodSourceFileIndex = (data.getShort()& 0xffff);
					lineNumber = data.getShort();

					methodClassName = classNames[methodClassNameIndex];
					methodName = methodNames[methodNameIndex];
					methodSourceFile = fileNames[methodSourceFileIndex];

					steArray[sti] = new StackTraceElement(methodClassName, methodName, methodSourceFile, lineNumber);

					/* we've consumed 8 bytes; gobble up any extra */
					for (int skip = 9; skip < stackFrameLen; skip++)
					{
						data.get();
					}
				}

				list.Add(new AllocationInfo(allocNumber--, classNames[classNameIndex], totalSize, (short) threadId, steArray));
			}

			client.clientData.allocations = list.ToArray();
			client.update(Client.CHANGE_HEAP_ALLOCATIONS);
		}
Example #7
0
		private void handleFAIL(Client client, ByteBuffer data)
		{
			/*int errorCode =*/	 data.getInt();
            int length = data.getInt() * 2;
			string message = null;
			if (length > 0)
			{
				var messageBuffer = new byte[length];
				data.get(messageBuffer, 0, length);
				message = Encoding.Default.GetString(messageBuffer);
			}

			// this can be sent if
			// - MPRS failed (like wrong permission)
			// - MPSE failed for whatever reason

			string filename = client.clientData.pendingMethodProfiling;
			if (filename != null)
			{
				// reset the pending file.
				client.clientData.pendingMethodProfiling = null;

				// and notify of failure
				ClientData.IMethodProfilingHandler handler = ClientData.methodProfilingHandler;
				if (handler != null)
				{
					handler.onStartFailure(client, message);
				}
			}
			else
			{
				// this is MPRE
				// notify of failure
				ClientData.IMethodProfilingHandler handler = ClientData.methodProfilingHandler;
				if (handler != null)
				{
					handler.onEndFailure(client, message);
				}
			}

			// send a query to know the current status
			try
			{
				sendMPRQ(client);
			}
			catch (IOException e)
			{
				Log.e("HandleProfiling", e);
			}
		}
Example #8
0
		/*
		 * Handle a heap info message.
		 */
		private void handleHPIF(Client client, ByteBuffer data)
		{
			Log.d("ddm-heap", "HPIF!");
			try
			{
                int numHeaps = data.getInt();

				for (int i = 0; i < numHeaps; i++)
				{
                    int heapId = data.getInt();
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @SuppressWarnings("unused") long timeStamp = data.getLong();
                    long timeStamp = data.getLong();
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @SuppressWarnings("unused") byte reason = data.get();
					var reason = data.get();
					long maxHeapSize = (long)data.getInt() & 0x00ffffffff;
					long heapSize = (long)data.getInt() & 0x00ffffffff;
					long bytesAllocated = (long)data.getInt() & 0x00ffffffff;
                    long objectsAllocated = (long)data.getInt() & 0x00ffffffff;

					client.clientData.setHeapInfo(heapId, maxHeapSize, heapSize, bytesAllocated, objectsAllocated);
					client.update(Client.CHANGE_HEAP_DATA);
				}
			}
			catch (BufferUnderflowException)
			{
				Log.w("ddm-heap", "malformed HPIF chunk from client");
			}
		}
Example #9
0
        /// <summary>
        /// Reads the header of a RawImage from a <seealso cref="ByteBuffer"/>.
        /// <p/>The way the data is sent over adb is defined in system/core/adb/framebuffer_service.c </summary>
        /// <param name="version"> the version of the protocol. </param>
        /// <param name="buf"> the buffer to read from. </param>
        /// <returns> true if success </returns>
        public bool readHeader(int version, ByteBuffer buf)
        {
            this.version = version;

            if (version == 16)
            {
                // compatibility mode with original protocol
                this.bpp = 16;

                // read actual values.
                this.size = buf.getInt();
                this.width = buf.getInt();
                this.height = buf.getInt();

                // create default values for the rest. Format is 565
                this.red_offset = 11;
                this.red_length = 5;
                this.green_offset = 5;
                this.green_length = 6;
                this.blue_offset = 0;
                this.blue_length = 5;
                this.alpha_offset = 0;
                this.alpha_length = 0;
            }
            else if (version == 1)
            {
                this.bpp = buf.getInt();
                this.size = buf.getInt();
                this.width = buf.getInt();
                this.height = buf.getInt();
                this.red_offset = buf.getInt();
                this.red_length = buf.getInt();
                this.blue_offset = buf.getInt();
                this.blue_length = buf.getInt();
                this.green_offset = buf.getInt();
                this.green_length = buf.getInt();
                this.alpha_offset = buf.getInt();
                this.alpha_length = buf.getInt();
            }
            else
            {
                // unsupported protocol!
                return false;
            }

            return true;
        }
Example #10
0
        /// <summary>
        /// Find the JDWP packet at the start of "buf".  The start is known,
        /// but the length has to be parsed out.
        /// 
        /// On entry, the packet data in "buf" must start at offset 0 and end
        /// at "position".  "limit" should be set to the buffer capacity.  This
        /// method does not alter "buf"s attributes.
        /// 
        /// Returns a new JdwpPacket if a full one is found in the buffer.  If
        /// not, returns null.  Throws an exception if the data doesn't look like
        /// a valid JDWP packet.
        /// </summary>
        internal static JdwpPacket findPacket(ByteBuffer buf)
        {
            int count = buf.position;
            int length, id, flags, cmdSet, cmd;

            if (count < JDWP_HEADER_LEN)
            {
                return null;
            }

            ByteOrder oldOrder = buf.order;
            buf.order =(ChunkHandler.CHUNK_ORDER);

            length = buf.getInt(0x00);
            id = buf.getInt(0x04);
            flags = buf.get(0x08) & 0xff;
            cmdSet = buf.get(0x09) & 0xff;
            cmd = buf.get(0x0a) & 0xff;

            buf.order = oldOrder;

            if (length < JDWP_HEADER_LEN)
            {
                throw new BadPacketException();
            }
            if (count < length)
            {
                return null;
            }

            JdwpPacket pkt = new JdwpPacket(buf);
            //pkt.mBuffer = buf;
            pkt.mLength = length;
            pkt.mId = id;
            pkt.mFlags = flags;

            if ((flags & REPLY_PACKET) == 0)
            {
                pkt.mCmdSet = cmdSet;
                pkt.mCmd = cmd;
                pkt.mErrCode = -1;
            }
            else
            {
                pkt.mCmdSet = -1;
                pkt.mCmd = -1;
                pkt.mErrCode = cmdSet | (cmd << 8);
            }

            return pkt;
        }
Example #11
0
		/// <summary>
		/// Parse an incoming STKL.
		/// </summary>
		private void handleSTKL(Client client, ByteBuffer data)
		{
			StackTraceElement[] trace;
			int i, threadId, stackDepth;
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @SuppressWarnings("unused") int future;
			int future;

            future = data.getInt();
            threadId = data.getInt();

			Log.v("ddms", "STKL: " + threadId);

			/* un-serialize the StackTraceElement[] */
            stackDepth = data.getInt();
			trace = new StackTraceElement[stackDepth];
			for (i = 0; i < stackDepth; i++)
			{
				string className, methodName, fileName;
				int len, lineNumber;

                len = data.getInt();
				className = getString(data, len);
                len = data.getInt();
				methodName = getString(data, len);
                len = data.getInt();
				if (len == 0)
				{
					fileName = null;
				}
				else
				{
					fileName = getString(data, len);
				}
                lineNumber = data.getInt();

				trace[i] = new StackTraceElement(className, methodName, fileName, lineNumber);
			}

			ThreadInfo threadInfo = client.clientData.getThread(threadId);
			if (threadInfo != null)
			{
				threadInfo.stackCall = trace;
				client.update(Client.CHANGE_THREAD_STACKTRACE);
			}
			else
			{
				Log.d("STKL", string.Format("Got stackcall for thread {0:D}, which does not exists (anymore?).", threadId)); //$NON-NLS-1$
			}
		}
Example #12
0
		/*
		 * Handle a THNM (THread NaMe) message.  We get one of these after
		 * somebody calls Thread.setName() on a running thread.
		 */
		private void handleTHNM(Client client, ByteBuffer data)
		{
			int threadId, nameLen;
			string name;

            threadId = data.getInt();
            nameLen = data.getInt();
			name = getString(data, nameLen);

			Log.v("ddm-thread", "THNM: " + threadId + " '" + name + "'");

			ThreadInfo threadInfo = client.clientData.getThread(threadId);
			if (threadInfo != null)
			{
				threadInfo.threadName = name;
				client.update(Client.CHANGE_THREAD_DATA);
			}
			else
			{
				Log.d("ddms", "Thread with id=" + threadId + " not found");
			}
		}
Example #13
0
		/*
		 * Handle a thread status update message.
		 *
		 * Response has:
		 *  (1b) header len
		 *  (1b) bytes per entry
		 *  (2b) thread count
		 * Then, for each thread:
		 *  (4b) threadId (matches value from THCR)
		 *  (1b) thread status
		 *  (4b) tid
		 *  (4b) utime
		 *  (4b) stime
		 */
		private void handleTHST(Client client, ByteBuffer data)
		{
			int headerLen, bytesPerEntry, extraPerEntry;
			int threadCount;

			headerLen = (data.get() & 0xff);
			bytesPerEntry = (data.get() & 0xff);
            threadCount = data.getShort();

			headerLen -= 4; // we've read 4 bytes
			while (headerLen-- > 0)
			{
				data.get();
			}

			extraPerEntry = bytesPerEntry - 18; // we want 18 bytes

			Log.v("ddm-thread", "THST: threadCount=" + threadCount);

			/*
			 * For each thread, extract the data, find the appropriate
			 * client, and add it to the ClientData.
			 */
			for (int i = 0; i < threadCount; i++)
			{
				int threadId, status, tid, utime, stime;
				bool isDaemon = false;

                threadId = data.getInt();
				status = data.get();
                tid = data.getInt();
                utime = data.getInt();
                stime = data.getInt();
				if (bytesPerEntry >= 18)
				{
					isDaemon = (data.get() != 0);
				}

				Log.v("ddm-thread", "  id=" + threadId + ", status=" + status + ", tid=" + tid + ", utime=" + utime + ", stime=" + stime);

				ClientData cd = client.clientData;
				ThreadInfo threadInfo = cd.getThread(threadId);
				if (threadInfo != null)
				{
					threadInfo.updateThread(status, tid, utime, stime, isDaemon);
				}
				else
				{
					Log.d("ddms", "Thread with id=" + threadId + " not found");
				}

				// slurp up any extra
				for (int slurp = extraPerEntry; slurp > 0; slurp--)
				{
					data.get();
				}
			}

			client.update(Client.CHANGE_THREAD_DATA);
		}
Example #14
0
		/*
		 * Handle a thread death message.
		 */
		private void handleTHDE(Client client, ByteBuffer data)
		{
			int threadId;

            threadId = data.getInt();
			Log.v("ddm-thread", "THDE: " + threadId);

			client.clientData.removeThread(threadId);
			client.update(Client.CHANGE_THREAD_DATA);
		}
Example #15
0
		/*
		 * Handle a thread creation message.
		 *
		 * We should be tolerant of receiving a duplicate create message.  (It
		 * shouldn't happen with the current implementation.)
		 */
		private void handleTHCR(Client client, ByteBuffer data)
		{
			int threadId, nameLen;
			string name;

			threadId = data.getInt();
            nameLen = data.getInt();
			name = getString(data, nameLen);

			Log.v("ddm-thread", "THCR: " + threadId + " '" + name + "'");

			client.clientData.addThread(threadId, name);
			client.update(Client.CHANGE_THREAD_DATA);
		}