/* * 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); }
/* * 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); }