11320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci# Copyright 2014 The Chromium Authors. All rights reserved. 21320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci# Use of this source code is governed by a BSD-style license that can be 31320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci# found in the LICENSE file. 41320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci"""This parser turns the heap_dump output into a |NativeHeap| object.""" 61320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciimport json 81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccifrom memory_inspector.core import native_heap 101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccifrom memory_inspector.core import stacktrace 111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci# These are defined in heap_profiler/heap_profiler.h 141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciFLAGS_MALLOC = 1 151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciFLAGS_MMAP = 2 161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciFLAGS_MMAP_FILE = 4 171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciFLAGS_IN_ZYGOTE = 8 181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccidef Parse(content): 211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci """Parses the output of the heap_dump binary (part of libheap_profiler). 221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci heap_dump provides a conveniente JSON output. 241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci See the header of tools/android/heap_profiler/heap_dump.c for more details. 251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Args: 271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci content: string containing the command output. 281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Returns: 301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci An instance of |native_heap.NativeHeap|. 311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci """ 321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci data = json.loads(content) 331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci assert('allocs' in data), 'Need to run heap_dump with the -x (extended) arg.' 341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci nativeheap = native_heap.NativeHeap() 351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci strace_by_index = {} # index (str) -> |stacktrace.Stacktrace| 361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci for index, entry in data['stacks'].iteritems(): 381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci strace = stacktrace.Stacktrace() 391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci for absolute_addr in entry['f']: 401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci strace.Add(nativeheap.GetStackFrame(absolute_addr)) 411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci strace_by_index[index] = strace 421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci for start_addr, entry in data['allocs'].iteritems(): 441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci flags = int(entry['f']) 451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci # TODO(primiano): For the moment we just skip completely the allocations 461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci # made in the Zygote (pre-fork) because this is usually reasonable. In the 471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci # near future we will expose them with some UI to selectively filter them. 481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if flags & FLAGS_IN_ZYGOTE: 491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci continue 501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci nativeheap.Add(native_heap.Allocation( 511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci size=entry['l'], 521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci stack_trace=strace_by_index[entry['s']], 531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci start=int(start_addr, 16), 541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci flags=flags)) 551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return nativeheap 57