1*795d594fSAndroid Build Coastguard Worker# Copyright (C) 2018 The Android Open Source Project 2*795d594fSAndroid Build Coastguard Worker# 3*795d594fSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 4*795d594fSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 5*795d594fSAndroid Build Coastguard Worker# You may obtain a copy of the License at 6*795d594fSAndroid Build Coastguard Worker# 7*795d594fSAndroid Build Coastguard Worker# http://www.apache.org/licenses/LICENSE-2.0 8*795d594fSAndroid Build Coastguard Worker# 9*795d594fSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 10*795d594fSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, 11*795d594fSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*795d594fSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and 13*795d594fSAndroid Build Coastguard Worker# limitations under the License. 14*795d594fSAndroid Build Coastguard Worker 15*795d594fSAndroid Build Coastguard Worker# usage: python hprofdump.py FILE 16*795d594fSAndroid Build Coastguard Worker# Dumps a binary heap dump file to text, to facilitate debugging of heap 17*795d594fSAndroid Build Coastguard Worker# dumps and heap dump viewers. 18*795d594fSAndroid Build Coastguard Worker 19*795d594fSAndroid Build Coastguard Workerimport time 20*795d594fSAndroid Build Coastguard Workerimport struct 21*795d594fSAndroid Build Coastguard Workerimport sys 22*795d594fSAndroid Build Coastguard Worker 23*795d594fSAndroid Build Coastguard Workerfilename = sys.argv[1] 24*795d594fSAndroid Build Coastguard Workerhprof = open(filename, "rb") 25*795d594fSAndroid Build Coastguard Worker 26*795d594fSAndroid Build Coastguard Workerdef readu1(hprof): 27*795d594fSAndroid Build Coastguard Worker return struct.unpack('!B', hprof.read(1))[0] 28*795d594fSAndroid Build Coastguard Worker 29*795d594fSAndroid Build Coastguard Workerdef readu2(hprof): 30*795d594fSAndroid Build Coastguard Worker return struct.unpack('!H', hprof.read(2))[0] 31*795d594fSAndroid Build Coastguard Worker 32*795d594fSAndroid Build Coastguard Workerdef readu4(hprof): 33*795d594fSAndroid Build Coastguard Worker return struct.unpack('!I', hprof.read(4))[0] 34*795d594fSAndroid Build Coastguard Worker 35*795d594fSAndroid Build Coastguard Workerdef readu8(hprof): 36*795d594fSAndroid Build Coastguard Worker return struct.unpack('!Q', hprof.read(8))[0] 37*795d594fSAndroid Build Coastguard Worker 38*795d594fSAndroid Build Coastguard Workerdef readN(n, hprof): 39*795d594fSAndroid Build Coastguard Worker if n == 1: 40*795d594fSAndroid Build Coastguard Worker return readu1(hprof) 41*795d594fSAndroid Build Coastguard Worker if n == 2: 42*795d594fSAndroid Build Coastguard Worker return readu2(hprof) 43*795d594fSAndroid Build Coastguard Worker if n == 4: 44*795d594fSAndroid Build Coastguard Worker return readu4(hprof) 45*795d594fSAndroid Build Coastguard Worker if n == 8: 46*795d594fSAndroid Build Coastguard Worker return readu8(hprof) 47*795d594fSAndroid Build Coastguard Worker raise Exception("Unsupported size of readN: %d" % n) 48*795d594fSAndroid Build Coastguard Worker 49*795d594fSAndroid Build Coastguard WorkerTY_OBJECT = 2 50*795d594fSAndroid Build Coastguard WorkerTY_BOOLEAN = 4 51*795d594fSAndroid Build Coastguard WorkerTY_CHAR = 5 52*795d594fSAndroid Build Coastguard WorkerTY_FLOAT = 6 53*795d594fSAndroid Build Coastguard WorkerTY_DOUBLE = 7 54*795d594fSAndroid Build Coastguard WorkerTY_BYTE = 8 55*795d594fSAndroid Build Coastguard WorkerTY_SHORT = 9 56*795d594fSAndroid Build Coastguard WorkerTY_INT = 10 57*795d594fSAndroid Build Coastguard WorkerTY_LONG = 11 58*795d594fSAndroid Build Coastguard Worker 59*795d594fSAndroid Build Coastguard Workerdef showty(ty): 60*795d594fSAndroid Build Coastguard Worker if ty == TY_OBJECT: 61*795d594fSAndroid Build Coastguard Worker return "Object" 62*795d594fSAndroid Build Coastguard Worker if ty == TY_BOOLEAN: 63*795d594fSAndroid Build Coastguard Worker return "boolean" 64*795d594fSAndroid Build Coastguard Worker if ty == TY_CHAR: 65*795d594fSAndroid Build Coastguard Worker return "char" 66*795d594fSAndroid Build Coastguard Worker if ty == TY_FLOAT: 67*795d594fSAndroid Build Coastguard Worker return "float" 68*795d594fSAndroid Build Coastguard Worker if ty == TY_DOUBLE: 69*795d594fSAndroid Build Coastguard Worker return "double" 70*795d594fSAndroid Build Coastguard Worker if ty == TY_BYTE: 71*795d594fSAndroid Build Coastguard Worker return "byte" 72*795d594fSAndroid Build Coastguard Worker if ty == TY_SHORT: 73*795d594fSAndroid Build Coastguard Worker return "short" 74*795d594fSAndroid Build Coastguard Worker if ty == TY_INT: 75*795d594fSAndroid Build Coastguard Worker return "int" 76*795d594fSAndroid Build Coastguard Worker if ty == TY_LONG: 77*795d594fSAndroid Build Coastguard Worker return "long" 78*795d594fSAndroid Build Coastguard Worker raise Exception("Unsupported type %d" % ty) 79*795d594fSAndroid Build Coastguard Worker 80*795d594fSAndroid Build Coastguard Workerstrs = { } 81*795d594fSAndroid Build Coastguard Workerdef showstr(id): 82*795d594fSAndroid Build Coastguard Worker if id in strs: 83*795d594fSAndroid Build Coastguard Worker return strs[id] 84*795d594fSAndroid Build Coastguard Worker return "STR[@%x]" % id 85*795d594fSAndroid Build Coastguard Worker 86*795d594fSAndroid Build Coastguard Workerloaded = { } 87*795d594fSAndroid Build Coastguard Workerdef showloaded(serial): 88*795d594fSAndroid Build Coastguard Worker if serial in loaded: 89*795d594fSAndroid Build Coastguard Worker return showstr(loaded[serial]) 90*795d594fSAndroid Build Coastguard Worker return "SERIAL[@%x]" % serial 91*795d594fSAndroid Build Coastguard Worker 92*795d594fSAndroid Build Coastguard Workerclassobjs = { } 93*795d594fSAndroid Build Coastguard Workerdef showclassobj(id): 94*795d594fSAndroid Build Coastguard Worker if id in classobjs: 95*795d594fSAndroid Build Coastguard Worker return "%s @%x" % (showstr(classobjs[id]), id) 96*795d594fSAndroid Build Coastguard Worker return "@%x" % id 97*795d594fSAndroid Build Coastguard Worker 98*795d594fSAndroid Build Coastguard Worker 99*795d594fSAndroid Build Coastguard Worker# [u1]* An initial NULL terminate series of bytes representing the format name 100*795d594fSAndroid Build Coastguard Worker# and version. 101*795d594fSAndroid Build Coastguard Workerversion = "" 102*795d594fSAndroid Build Coastguard Workerc = hprof.read(1) 103*795d594fSAndroid Build Coastguard Workerwhile (c != '\0'): 104*795d594fSAndroid Build Coastguard Worker version += c 105*795d594fSAndroid Build Coastguard Worker c = hprof.read(1) 106*795d594fSAndroid Build Coastguard Workerprint "Version: %s" % version 107*795d594fSAndroid Build Coastguard Worker 108*795d594fSAndroid Build Coastguard Worker# [u4] size of identifiers. 109*795d594fSAndroid Build Coastguard Workeridsize = readu4(hprof) 110*795d594fSAndroid Build Coastguard Workerprint "ID Size: %d bytes" % idsize 111*795d594fSAndroid Build Coastguard Workerdef readID(hprof): 112*795d594fSAndroid Build Coastguard Worker return readN(idsize, hprof) 113*795d594fSAndroid Build Coastguard Worker 114*795d594fSAndroid Build Coastguard Workerdef valsize(ty): 115*795d594fSAndroid Build Coastguard Worker if ty == TY_OBJECT: 116*795d594fSAndroid Build Coastguard Worker return idsize 117*795d594fSAndroid Build Coastguard Worker if ty == TY_BOOLEAN: 118*795d594fSAndroid Build Coastguard Worker return 1 119*795d594fSAndroid Build Coastguard Worker if ty == TY_CHAR: 120*795d594fSAndroid Build Coastguard Worker return 2 121*795d594fSAndroid Build Coastguard Worker if ty == TY_FLOAT: 122*795d594fSAndroid Build Coastguard Worker return 4 123*795d594fSAndroid Build Coastguard Worker if ty == TY_DOUBLE: 124*795d594fSAndroid Build Coastguard Worker return 8 125*795d594fSAndroid Build Coastguard Worker if ty == TY_BYTE: 126*795d594fSAndroid Build Coastguard Worker return 1 127*795d594fSAndroid Build Coastguard Worker if ty == TY_SHORT: 128*795d594fSAndroid Build Coastguard Worker return 2 129*795d594fSAndroid Build Coastguard Worker if ty == TY_INT: 130*795d594fSAndroid Build Coastguard Worker return 4 131*795d594fSAndroid Build Coastguard Worker if ty == TY_LONG: 132*795d594fSAndroid Build Coastguard Worker return 8 133*795d594fSAndroid Build Coastguard Worker raise Exception("Unsupported type %d" % ty) 134*795d594fSAndroid Build Coastguard Worker 135*795d594fSAndroid Build Coastguard Workerdef readval(ty, hprof): 136*795d594fSAndroid Build Coastguard Worker return readN(valsize(ty), hprof) 137*795d594fSAndroid Build Coastguard Worker 138*795d594fSAndroid Build Coastguard Worker# [u4] high word of number of ms since 0:00 GMT, 1/1/70 139*795d594fSAndroid Build Coastguard Worker# [u4] low word of number of ms since 0:00 GMT, 1/1/70 140*795d594fSAndroid Build Coastguard Workertimestamp = (readu4(hprof) << 32) | readu4(hprof) 141*795d594fSAndroid Build Coastguard Workers, ms = divmod(timestamp, 1000) 142*795d594fSAndroid Build Coastguard Workerprint "Date: %s.%03d" % (time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime(s)), ms) 143*795d594fSAndroid Build Coastguard Worker 144*795d594fSAndroid Build Coastguard Workerwhile hprof.read(1): 145*795d594fSAndroid Build Coastguard Worker hprof.seek(-1,1) 146*795d594fSAndroid Build Coastguard Worker pos = hprof.tell() 147*795d594fSAndroid Build Coastguard Worker tag = readu1(hprof) 148*795d594fSAndroid Build Coastguard Worker time = readu4(hprof) 149*795d594fSAndroid Build Coastguard Worker length = readu4(hprof) 150*795d594fSAndroid Build Coastguard Worker if tag == 0x01: 151*795d594fSAndroid Build Coastguard Worker id = readID(hprof) 152*795d594fSAndroid Build Coastguard Worker string = hprof.read(length - idsize) 153*795d594fSAndroid Build Coastguard Worker print "%d: STRING %x %s" % (pos, id, repr(string)) 154*795d594fSAndroid Build Coastguard Worker strs[id] = string 155*795d594fSAndroid Build Coastguard Worker elif tag == 0x02: 156*795d594fSAndroid Build Coastguard Worker serial = readu4(hprof) 157*795d594fSAndroid Build Coastguard Worker classobj = readID(hprof) 158*795d594fSAndroid Build Coastguard Worker stack = readu4(hprof) 159*795d594fSAndroid Build Coastguard Worker classname = readID(hprof) 160*795d594fSAndroid Build Coastguard Worker loaded[serial] = classname 161*795d594fSAndroid Build Coastguard Worker classobjs[classobj] = classname 162*795d594fSAndroid Build Coastguard Worker print "LOAD CLASS #%d %s @%x stack=@%x" % (serial, showstr(classname), classobj, stack) 163*795d594fSAndroid Build Coastguard Worker elif tag == 0x04: 164*795d594fSAndroid Build Coastguard Worker id = readID(hprof) 165*795d594fSAndroid Build Coastguard Worker method = readID(hprof) 166*795d594fSAndroid Build Coastguard Worker sig = readID(hprof) 167*795d594fSAndroid Build Coastguard Worker file = readID(hprof) 168*795d594fSAndroid Build Coastguard Worker serial = readu4(hprof) 169*795d594fSAndroid Build Coastguard Worker line = readu4(hprof); 170*795d594fSAndroid Build Coastguard Worker print "STACK FRAME %d '%s' '%s' '%s' line=%d classserial=%d" % (id, showstr(method), showstr(sig), showstr(file), line, serial) 171*795d594fSAndroid Build Coastguard Worker elif tag == 0x05: 172*795d594fSAndroid Build Coastguard Worker serial = readu4(hprof) 173*795d594fSAndroid Build Coastguard Worker print "STACK TRACE %d" % serial 174*795d594fSAndroid Build Coastguard Worker thread = readu4(hprof) 175*795d594fSAndroid Build Coastguard Worker frames = readu4(hprof) 176*795d594fSAndroid Build Coastguard Worker hprof.read(idsize * frames) 177*795d594fSAndroid Build Coastguard Worker elif tag == 0x06: 178*795d594fSAndroid Build Coastguard Worker print "ALLOC SITES" 179*795d594fSAndroid Build Coastguard Worker flags = readu2(hprof) 180*795d594fSAndroid Build Coastguard Worker cutoff_ratio = readu4(hprof) 181*795d594fSAndroid Build Coastguard Worker live_bytes = readu4(hprof) 182*795d594fSAndroid Build Coastguard Worker live_insts = readu4(hprof) 183*795d594fSAndroid Build Coastguard Worker alloc_bytes = readu8(hprof) 184*795d594fSAndroid Build Coastguard Worker alloc_insts = readu8(hprof) 185*795d594fSAndroid Build Coastguard Worker numsites = readu4(hprof) 186*795d594fSAndroid Build Coastguard Worker while numsites > 0: 187*795d594fSAndroid Build Coastguard Worker indicator = readu1(hprof) 188*795d594fSAndroid Build Coastguard Worker class_serial = readu4(hprof) 189*795d594fSAndroid Build Coastguard Worker stack = readu4(hprof) 190*795d594fSAndroid Build Coastguard Worker live_bytes = readu4(hprof) 191*795d594fSAndroid Build Coastguard Worker live_insts = readu4(hprof) 192*795d594fSAndroid Build Coastguard Worker alloc_bytes = readu4(hprof) 193*795d594fSAndroid Build Coastguard Worker alloc_insts = readu4(hprof) 194*795d594fSAndroid Build Coastguard Worker numsites -= 1 195*795d594fSAndroid Build Coastguard Worker elif tag == 0x0A: 196*795d594fSAndroid Build Coastguard Worker thread = readu4(hprof) 197*795d594fSAndroid Build Coastguard Worker object = readID(hprof) 198*795d594fSAndroid Build Coastguard Worker stack = readu4(hprof) 199*795d594fSAndroid Build Coastguard Worker name = readID(hprof) 200*795d594fSAndroid Build Coastguard Worker group_name = readID(hprof) 201*795d594fSAndroid Build Coastguard Worker pgroup_name = readID(hprof) 202*795d594fSAndroid Build Coastguard Worker print "START THREAD serial=%d" % thread 203*795d594fSAndroid Build Coastguard Worker elif tag == 0x0B: 204*795d594fSAndroid Build Coastguard Worker thread = readu4(hprof) 205*795d594fSAndroid Build Coastguard Worker print "END THREAD" 206*795d594fSAndroid Build Coastguard Worker elif tag == 0x0C or tag == 0x1C: 207*795d594fSAndroid Build Coastguard Worker if tag == 0x0C: 208*795d594fSAndroid Build Coastguard Worker print "HEAP DUMP" 209*795d594fSAndroid Build Coastguard Worker else: 210*795d594fSAndroid Build Coastguard Worker print "HEAP DUMP SEGMENT" 211*795d594fSAndroid Build Coastguard Worker 212*795d594fSAndroid Build Coastguard Worker while (length > 0): 213*795d594fSAndroid Build Coastguard Worker subtag = readu1(hprof) ; length -= 1 214*795d594fSAndroid Build Coastguard Worker if subtag == 0xFF: 215*795d594fSAndroid Build Coastguard Worker print " ROOT UNKNOWN" 216*795d594fSAndroid Build Coastguard Worker objid = readID(hprof) ; length -= idsize 217*795d594fSAndroid Build Coastguard Worker elif subtag == 0x01: 218*795d594fSAndroid Build Coastguard Worker print " ROOT JNI GLOBAL" 219*795d594fSAndroid Build Coastguard Worker objid = readID(hprof) ; length -= idsize 220*795d594fSAndroid Build Coastguard Worker ref = readID(hprof) ; length -= idsize 221*795d594fSAndroid Build Coastguard Worker elif subtag == 0x02: 222*795d594fSAndroid Build Coastguard Worker print " ROOT JNI LOCAL" 223*795d594fSAndroid Build Coastguard Worker objid = readID(hprof) ; length -= idsize 224*795d594fSAndroid Build Coastguard Worker thread = readu4(hprof) ; length -= 4 225*795d594fSAndroid Build Coastguard Worker frame = readu4(hprof) ; length -= 4 226*795d594fSAndroid Build Coastguard Worker elif subtag == 0x03: 227*795d594fSAndroid Build Coastguard Worker print " ROOT JAVA FRAME" 228*795d594fSAndroid Build Coastguard Worker objid = readID(hprof) ; length -= idsize 229*795d594fSAndroid Build Coastguard Worker serial = readu4(hprof) ; length -= 4 230*795d594fSAndroid Build Coastguard Worker frame = readu4(hprof) ; length -= 4 231*795d594fSAndroid Build Coastguard Worker elif subtag == 0x04: 232*795d594fSAndroid Build Coastguard Worker objid = readID(hprof) ; length -= idsize 233*795d594fSAndroid Build Coastguard Worker serial = readu4(hprof) ; length -= 4 234*795d594fSAndroid Build Coastguard Worker print " ROOT NATIVE STACK serial=%d" % serial 235*795d594fSAndroid Build Coastguard Worker elif subtag == 0x05: 236*795d594fSAndroid Build Coastguard Worker print " ROOT STICKY CLASS" 237*795d594fSAndroid Build Coastguard Worker objid = readID(hprof) ; length -= idsize 238*795d594fSAndroid Build Coastguard Worker elif subtag == 0x06: 239*795d594fSAndroid Build Coastguard Worker print " ROOT THREAD BLOCK" 240*795d594fSAndroid Build Coastguard Worker objid = readID(hprof) ; length -= idsize 241*795d594fSAndroid Build Coastguard Worker thread = readu4(hprof) ; length -= 4 242*795d594fSAndroid Build Coastguard Worker elif subtag == 0x07: 243*795d594fSAndroid Build Coastguard Worker print " ROOT MONITOR USED" 244*795d594fSAndroid Build Coastguard Worker objid = readID(hprof) ; length -= idsize 245*795d594fSAndroid Build Coastguard Worker elif subtag == 0x08: 246*795d594fSAndroid Build Coastguard Worker threadid = readID(hprof) ; length -= idsize 247*795d594fSAndroid Build Coastguard Worker serial = readu4(hprof) ; length -= 4 248*795d594fSAndroid Build Coastguard Worker stack = readu4(hprof) ; length -= 4 249*795d594fSAndroid Build Coastguard Worker print " ROOT THREAD OBJECT threadid=@%x serial=%d" % (threadid, serial) 250*795d594fSAndroid Build Coastguard Worker elif subtag == 0x20: 251*795d594fSAndroid Build Coastguard Worker print " CLASS DUMP" 252*795d594fSAndroid Build Coastguard Worker print " class class object ID: %s" % showclassobj(readID(hprof)) ; length -= idsize 253*795d594fSAndroid Build Coastguard Worker print " stack trace serial number: #%d" % readu4(hprof) ; length -= 4 254*795d594fSAndroid Build Coastguard Worker print " super class object ID: @%x" % readID(hprof) ; length -= idsize 255*795d594fSAndroid Build Coastguard Worker print " class loader object ID: @%x" % readID(hprof) ; length -= idsize 256*795d594fSAndroid Build Coastguard Worker print " signers object ID: @%x" % readID(hprof) ; length -= idsize 257*795d594fSAndroid Build Coastguard Worker print " protection domain object ID: @%x" % readID(hprof) ; length -= idsize 258*795d594fSAndroid Build Coastguard Worker print " reserved: @%x" % readID(hprof) ; length -= idsize 259*795d594fSAndroid Build Coastguard Worker print " reserved: @%x" % readID(hprof) ; length -= idsize 260*795d594fSAndroid Build Coastguard Worker print " instance size (in bytes): %d" % readu4(hprof) ; length -= 4 261*795d594fSAndroid Build Coastguard Worker print " constant pool:" 262*795d594fSAndroid Build Coastguard Worker poolsize = readu2(hprof) ; length -= 2 263*795d594fSAndroid Build Coastguard Worker while poolsize > 0: 264*795d594fSAndroid Build Coastguard Worker poolsize -= 1 265*795d594fSAndroid Build Coastguard Worker idx = readu2(hprof) ; length -= 2 266*795d594fSAndroid Build Coastguard Worker ty = readu1(hprof) ; length -= 1 267*795d594fSAndroid Build Coastguard Worker val = readval(ty, hprof) ; length -= valsize(ty) 268*795d594fSAndroid Build Coastguard Worker print " %d %s 0x%x" % (idx, showty(ty), val) 269*795d594fSAndroid Build Coastguard Worker numstatic = readu2(hprof) ; length -= 2 270*795d594fSAndroid Build Coastguard Worker print " static fields:" 271*795d594fSAndroid Build Coastguard Worker while numstatic > 0: 272*795d594fSAndroid Build Coastguard Worker numstatic -= 1 273*795d594fSAndroid Build Coastguard Worker nameid = readID(hprof) ; length -= idsize 274*795d594fSAndroid Build Coastguard Worker ty = readu1(hprof) ; length -= 1 275*795d594fSAndroid Build Coastguard Worker val = readval(ty, hprof) ; length -= valsize(ty) 276*795d594fSAndroid Build Coastguard Worker print " %s %s 0x%x" % (showstr(nameid), showty(ty), val) 277*795d594fSAndroid Build Coastguard Worker numinst = readu2(hprof) ; length -= 2 278*795d594fSAndroid Build Coastguard Worker print " instance fields:" 279*795d594fSAndroid Build Coastguard Worker while numinst > 0: 280*795d594fSAndroid Build Coastguard Worker numinst -= 1 281*795d594fSAndroid Build Coastguard Worker nameid = readID(hprof) ; length -= idsize 282*795d594fSAndroid Build Coastguard Worker ty = readu1(hprof) ; length -= 1 283*795d594fSAndroid Build Coastguard Worker print " %s %s" % (showstr(nameid), showty(ty)) 284*795d594fSAndroid Build Coastguard Worker elif subtag == 0x21: 285*795d594fSAndroid Build Coastguard Worker print " INSTANCE DUMP:" 286*795d594fSAndroid Build Coastguard Worker print " object ID: @%x" % readID(hprof) ; length -= idsize 287*795d594fSAndroid Build Coastguard Worker stack = readu4(hprof) ; length -= 4 288*795d594fSAndroid Build Coastguard Worker print " stack: %s" % stack 289*795d594fSAndroid Build Coastguard Worker print " class object ID: %s" % showclassobj(readID(hprof)) ; length -= idsize 290*795d594fSAndroid Build Coastguard Worker datalen = readu4(hprof) ; length -= 4 291*795d594fSAndroid Build Coastguard Worker print " %d bytes of instance data" % datalen 292*795d594fSAndroid Build Coastguard Worker data = hprof.read(datalen) ; length -= datalen 293*795d594fSAndroid Build Coastguard Worker elif subtag == 0x22: 294*795d594fSAndroid Build Coastguard Worker print " OBJECT ARRAY DUMP:" 295*795d594fSAndroid Build Coastguard Worker print " array object ID: @%x" % readID(hprof) ; length -= idsize 296*795d594fSAndroid Build Coastguard Worker stack = readu4(hprof) ; length -= 4 297*795d594fSAndroid Build Coastguard Worker print " stack: %s" % stack 298*795d594fSAndroid Build Coastguard Worker count = readu4(hprof) ; length -= 4 299*795d594fSAndroid Build Coastguard Worker print " array class object ID: %s" % showclassobj(readID(hprof)) ; length -= idsize 300*795d594fSAndroid Build Coastguard Worker hprof.read(idsize * count) ; length -= (idsize * count) 301*795d594fSAndroid Build Coastguard Worker elif subtag == 0x23: 302*795d594fSAndroid Build Coastguard Worker print " PRIMITIVE ARRAY DUMP:" 303*795d594fSAndroid Build Coastguard Worker print " array object ID: @%x" % readID(hprof) ; length -= idsize 304*795d594fSAndroid Build Coastguard Worker stack = readu4(hprof) ; length -= 4 305*795d594fSAndroid Build Coastguard Worker count = readu4(hprof) ; length -= 4 306*795d594fSAndroid Build Coastguard Worker ty = readu1(hprof) ; length -= 1 307*795d594fSAndroid Build Coastguard Worker hprof.read(valsize(ty)*count) ; length -= (valsize(ty)*count) 308*795d594fSAndroid Build Coastguard Worker elif subtag == 0x89: 309*795d594fSAndroid Build Coastguard Worker print " HPROF_ROOT_INTERNED_STRING" 310*795d594fSAndroid Build Coastguard Worker objid = readID(hprof) ; length -= idsize 311*795d594fSAndroid Build Coastguard Worker elif subtag == 0x8b: 312*795d594fSAndroid Build Coastguard Worker objid = readID(hprof) ; length -= idsize 313*795d594fSAndroid Build Coastguard Worker print " HPROF ROOT DEBUGGER @%x (at offset %d)" % (objid, hprof.tell() - (idsize + 1)) 314*795d594fSAndroid Build Coastguard Worker elif subtag == 0x8d: 315*795d594fSAndroid Build Coastguard Worker objid = readID(hprof) ; length -= idsize 316*795d594fSAndroid Build Coastguard Worker print " HPROF ROOT VM INTERNAL @%x" % objid 317*795d594fSAndroid Build Coastguard Worker elif subtag == 0xfe: 318*795d594fSAndroid Build Coastguard Worker hty = readu4(hprof) ; length -= 4 319*795d594fSAndroid Build Coastguard Worker hnameid = readID(hprof) ; length -= idsize 320*795d594fSAndroid Build Coastguard Worker print " HPROF_HEAP_DUMP_INFO %s" % showstr(hnameid) 321*795d594fSAndroid Build Coastguard Worker else: 322*795d594fSAndroid Build Coastguard Worker raise Exception("TODO: subtag %x" % subtag) 323*795d594fSAndroid Build Coastguard Worker elif tag == 0x0E: 324*795d594fSAndroid Build Coastguard Worker flags = readu4(hprof) 325*795d594fSAndroid Build Coastguard Worker depth = readu2(hprof) 326*795d594fSAndroid Build Coastguard Worker print "CONTROL SETTINGS %x %d" % (flags, depth) 327*795d594fSAndroid Build Coastguard Worker elif tag == 0x2C: 328*795d594fSAndroid Build Coastguard Worker print "HEAP DUMP END" 329*795d594fSAndroid Build Coastguard Worker else: 330*795d594fSAndroid Build Coastguard Worker raise Exception("TODO: TAG %x" % tag) 331*795d594fSAndroid Build Coastguard Worker 332