Example #1
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 #2
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);
		}