1e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch#!/usr/bin/env python 2e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch# 3e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch# Copyright 2011 the V8 project authors. All rights reserved. 4e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch# Redistribution and use in source and binary forms, with or without 5e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch# modification, are permitted provided that the following conditions are 6e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch# met: 7e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch# 8e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch# * Redistributions of source code must retain the above copyright 9e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch# notice, this list of conditions and the following disclaimer. 10e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch# * Redistributions in binary form must reproduce the above 11e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch# copyright notice, this list of conditions and the following 12e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch# disclaimer in the documentation and/or other materials provided 13e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch# with the distribution. 14e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch# * Neither the name of Google Inc. nor the names of its 15e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch# contributors may be used to endorse or promote products derived 16e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch# from this software without specific prior written permission. 17e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch# 18e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 30e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochimport ctypes 31e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochimport mmap 32e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochimport optparse 33e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochimport os 34e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochimport disasm 35e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochimport sys 36e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochimport types 37e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochimport codecs 38e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochimport re 39e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 40e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 41e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochUSAGE="""usage: %prog [OPTION]... 42e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 43e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochMinidump analyzer. 44e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 45e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochShows the processor state at the point of exception including the 46e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochstack of the active thread and the referenced objects in the V8 47e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochheap. Code objects are disassembled and the addresses linked from the 48e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochstack (pushed return addresses) are marked with "=>". 49e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 50e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 51e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochExamples: 52e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch $ %prog 12345678-1234-1234-1234-123456789abcd-full.dmp 53e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch""" 54e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 56e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochDEBUG=False 57e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 58e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 59e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochdef DebugPrint(s): 60e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if not DEBUG: return 61e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch print s 62e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 63e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 64e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochclass Descriptor(object): 65e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch """Descriptor of a structure in a memory.""" 66e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 67e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch def __init__(self, fields): 68e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch self.fields = fields 69e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch self.is_flexible = False 70e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch for _, type_or_func in fields: 71e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if isinstance(type_or_func, types.FunctionType): 72e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch self.is_flexible = True 73e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch break 74e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if not self.is_flexible: 75e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch self.ctype = Descriptor._GetCtype(fields) 76e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch self.size = ctypes.sizeof(self.ctype) 77e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 78e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch def Read(self, memory, offset): 79e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if self.is_flexible: 80e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch fields_copy = self.fields[:] 81e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch last = 0 82e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch for name, type_or_func in fields_copy: 83e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if isinstance(type_or_func, types.FunctionType): 84e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch partial_ctype = Descriptor._GetCtype(fields_copy[:last]) 85e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch partial_object = partial_ctype.from_buffer(memory, offset) 86e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch type = type_or_func(partial_object) 87e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if type is not None: 88e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch fields_copy[last] = (name, type) 89e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch last += 1 90e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch else: 91e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch last += 1 92e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch complete_ctype = Descriptor._GetCtype(fields_copy[:last]) 93e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch else: 94e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch complete_ctype = self.ctype 95e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return complete_ctype.from_buffer(memory, offset) 96e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 97e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch @staticmethod 98e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch def _GetCtype(fields): 99e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch class Raw(ctypes.Structure): 100e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch _fields_ = fields 101e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch _pack_ = 1 102e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 103e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch def __str__(self): 104e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return "{" + ", ".join("%s: %s" % (field, self.__getattribute__(field)) 105e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch for field, _ in Raw._fields_) + "}" 106e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return Raw 107e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 108e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 109e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch# Set of structures and constants that describe the layout of minidump 110e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch# files. Based on MSDN and Google Breakpad. 111e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 112e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochMINIDUMP_HEADER = Descriptor([ 113e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("signature", ctypes.c_uint32), 114e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("version", ctypes.c_uint32), 115e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("stream_count", ctypes.c_uint32), 116e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("stream_directories_rva", ctypes.c_uint32), 117e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("checksum", ctypes.c_uint32), 118e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("time_date_stampt", ctypes.c_uint32), 119e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("flags", ctypes.c_uint64) 120e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch]) 121e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 122e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochMINIDUMP_LOCATION_DESCRIPTOR = Descriptor([ 123e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("data_size", ctypes.c_uint32), 124e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("rva", ctypes.c_uint32) 125e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch]) 126e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 127e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochMINIDUMP_DIRECTORY = Descriptor([ 128e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("stream_type", ctypes.c_uint32), 129e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("location", MINIDUMP_LOCATION_DESCRIPTOR.ctype) 130e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch]) 131e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 132e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochMD_EXCEPTION_MAXIMUM_PARAMETERS = 15 133e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 134e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochMINIDUMP_EXCEPTION = Descriptor([ 135e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("code", ctypes.c_uint32), 136e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("flags", ctypes.c_uint32), 137e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("record", ctypes.c_uint64), 138e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("address", ctypes.c_uint64), 139e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("parameter_count", ctypes.c_uint32), 140e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("unused_alignment", ctypes.c_uint32), 141e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("information", ctypes.c_uint64 * MD_EXCEPTION_MAXIMUM_PARAMETERS) 142e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch]) 143e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 144e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochMINIDUMP_EXCEPTION_STREAM = Descriptor([ 145e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("thread_id", ctypes.c_uint32), 146e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("unused_alignment", ctypes.c_uint32), 147e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("exception", MINIDUMP_EXCEPTION.ctype), 148e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("thread_context", MINIDUMP_LOCATION_DESCRIPTOR.ctype) 149e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch]) 150e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 151e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch# Stream types. 152e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochMD_UNUSED_STREAM = 0 153e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochMD_RESERVED_STREAM_0 = 1 154e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochMD_RESERVED_STREAM_1 = 2 155e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochMD_THREAD_LIST_STREAM = 3 156e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochMD_MODULE_LIST_STREAM = 4 157e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochMD_MEMORY_LIST_STREAM = 5 158e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochMD_EXCEPTION_STREAM = 6 159e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochMD_SYSTEM_INFO_STREAM = 7 160e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochMD_THREAD_EX_LIST_STREAM = 8 161e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochMD_MEMORY_64_LIST_STREAM = 9 162e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochMD_COMMENT_STREAM_A = 10 163e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochMD_COMMENT_STREAM_W = 11 164e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochMD_HANDLE_DATA_STREAM = 12 165e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochMD_FUNCTION_TABLE_STREAM = 13 166e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochMD_UNLOADED_MODULE_LIST_STREAM = 14 167e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochMD_MISC_INFO_STREAM = 15 168e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochMD_MEMORY_INFO_LIST_STREAM = 16 169e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochMD_THREAD_INFO_LIST_STREAM = 17 170e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochMD_HANDLE_OPERATION_LIST_STREAM = 18 171e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 172e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochMD_FLOATINGSAVEAREA_X86_REGISTERAREA_SIZE = 80 173e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 174e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochMINIDUMP_FLOATING_SAVE_AREA_X86 = Descriptor([ 175e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("control_word", ctypes.c_uint32), 176e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("status_word", ctypes.c_uint32), 177e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("tag_word", ctypes.c_uint32), 178e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("error_offset", ctypes.c_uint32), 179e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("error_selector", ctypes.c_uint32), 180e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("data_offset", ctypes.c_uint32), 181e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("data_selector", ctypes.c_uint32), 182e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("register_area", ctypes.c_uint8 * MD_FLOATINGSAVEAREA_X86_REGISTERAREA_SIZE), 183e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("cr0_npx_state", ctypes.c_uint32) 184e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch]) 185e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 186e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochMD_CONTEXT_X86_EXTENDED_REGISTERS_SIZE = 512 187e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 188e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch# Context flags. 189e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochMD_CONTEXT_X86 = 0x00010000 190e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochMD_CONTEXT_X86_CONTROL = (MD_CONTEXT_X86 | 0x00000001) 191e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochMD_CONTEXT_X86_INTEGER = (MD_CONTEXT_X86 | 0x00000002) 192e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochMD_CONTEXT_X86_SEGMENTS = (MD_CONTEXT_X86 | 0x00000004) 193e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochMD_CONTEXT_X86_FLOATING_POINT = (MD_CONTEXT_X86 | 0x00000008) 194e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochMD_CONTEXT_X86_DEBUG_REGISTERS = (MD_CONTEXT_X86 | 0x00000010) 195e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochMD_CONTEXT_X86_EXTENDED_REGISTERS = (MD_CONTEXT_X86 | 0x00000020) 196e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 197e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochdef EnableOnFlag(type, flag): 198e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return lambda o: [None, type][int((o.context_flags & flag) != 0)] 199e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 200e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochMINIDUMP_CONTEXT_X86 = Descriptor([ 201e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("context_flags", ctypes.c_uint32), 202e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch # MD_CONTEXT_X86_DEBUG_REGISTERS. 203e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("dr0", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_DEBUG_REGISTERS)), 204e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("dr1", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_DEBUG_REGISTERS)), 205e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("dr2", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_DEBUG_REGISTERS)), 206e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("dr3", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_DEBUG_REGISTERS)), 207e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("dr6", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_DEBUG_REGISTERS)), 208e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("dr7", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_DEBUG_REGISTERS)), 209e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch # MD_CONTEXT_X86_FLOATING_POINT. 210e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("float_save", EnableOnFlag(MINIDUMP_FLOATING_SAVE_AREA_X86.ctype, 211e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch MD_CONTEXT_X86_FLOATING_POINT)), 212e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch # MD_CONTEXT_X86_SEGMENTS. 213e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("gs", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_SEGMENTS)), 214e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("fs", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_SEGMENTS)), 215e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("es", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_SEGMENTS)), 216e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("ds", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_SEGMENTS)), 217e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch # MD_CONTEXT_X86_INTEGER. 218e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("edi", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_INTEGER)), 219e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("esi", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_INTEGER)), 220e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("ebx", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_INTEGER)), 221e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("edx", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_INTEGER)), 222e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("ecx", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_INTEGER)), 223e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("eax", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_INTEGER)), 224e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch # MD_CONTEXT_X86_CONTROL. 225e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("ebp", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_CONTROL)), 226e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("eip", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_CONTROL)), 227e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("cs", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_CONTROL)), 228e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("eflags", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_CONTROL)), 229e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("esp", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_CONTROL)), 230e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("ss", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_CONTROL)), 231e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch # MD_CONTEXT_X86_EXTENDED_REGISTERS. 232e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("extended_registers", 233e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch EnableOnFlag(ctypes.c_uint8 * MD_CONTEXT_X86_EXTENDED_REGISTERS_SIZE, 234e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch MD_CONTEXT_X86_EXTENDED_REGISTERS)) 235e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch]) 236e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2373ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochMD_CONTEXT_AMD64 = 0x00100000 2383ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochMD_CONTEXT_AMD64_CONTROL = (MD_CONTEXT_AMD64 | 0x00000001) 2393ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochMD_CONTEXT_AMD64_INTEGER = (MD_CONTEXT_AMD64 | 0x00000002) 2403ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochMD_CONTEXT_AMD64_SEGMENTS = (MD_CONTEXT_AMD64 | 0x00000004) 2413ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochMD_CONTEXT_AMD64_FLOATING_POINT = (MD_CONTEXT_AMD64 | 0x00000008) 2423ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochMD_CONTEXT_AMD64_DEBUG_REGISTERS = (MD_CONTEXT_AMD64 | 0x00000010) 2433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2443ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochMINIDUMP_CONTEXT_AMD64 = Descriptor([ 2453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ("p1_home", ctypes.c_uint64), 2463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ("p2_home", ctypes.c_uint64), 2473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ("p3_home", ctypes.c_uint64), 2483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ("p4_home", ctypes.c_uint64), 2493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ("p5_home", ctypes.c_uint64), 2503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ("p6_home", ctypes.c_uint64), 2513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ("context_flags", ctypes.c_uint32), 2523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ("mx_csr", ctypes.c_uint32), 2533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch # MD_CONTEXT_AMD64_CONTROL. 2543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ("cs", EnableOnFlag(ctypes.c_uint16, MD_CONTEXT_AMD64_CONTROL)), 2553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch # MD_CONTEXT_AMD64_SEGMENTS 2563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ("ds", EnableOnFlag(ctypes.c_uint16, MD_CONTEXT_AMD64_SEGMENTS)), 2573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ("es", EnableOnFlag(ctypes.c_uint16, MD_CONTEXT_AMD64_SEGMENTS)), 2583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ("fs", EnableOnFlag(ctypes.c_uint16, MD_CONTEXT_AMD64_SEGMENTS)), 2593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ("gs", EnableOnFlag(ctypes.c_uint16, MD_CONTEXT_AMD64_SEGMENTS)), 2603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch # MD_CONTEXT_AMD64_CONTROL. 2613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ("ss", EnableOnFlag(ctypes.c_uint16, MD_CONTEXT_AMD64_CONTROL)), 2623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ("eflags", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_AMD64_CONTROL)), 2633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch # MD_CONTEXT_AMD64_DEBUG_REGISTERS. 2643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ("dr0", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_DEBUG_REGISTERS)), 2653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ("dr1", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_DEBUG_REGISTERS)), 2663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ("dr2", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_DEBUG_REGISTERS)), 2673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ("dr3", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_DEBUG_REGISTERS)), 2683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ("dr6", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_DEBUG_REGISTERS)), 2693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ("dr7", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_DEBUG_REGISTERS)), 2703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch # MD_CONTEXT_AMD64_INTEGER. 2713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ("rax", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_INTEGER)), 2723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ("rcx", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_INTEGER)), 2733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ("rdx", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_INTEGER)), 2743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ("rbx", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_INTEGER)), 2753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch # MD_CONTEXT_AMD64_CONTROL. 2763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ("rsp", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_CONTROL)), 2773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch # MD_CONTEXT_AMD64_INTEGER. 2783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ("rbp", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_INTEGER)), 2793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ("rsi", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_INTEGER)), 2803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ("rdi", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_INTEGER)), 2813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ("r8", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_INTEGER)), 2823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ("r9", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_INTEGER)), 2833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ("r10", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_INTEGER)), 2843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ("r11", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_INTEGER)), 2853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ("r12", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_INTEGER)), 2863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ("r13", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_INTEGER)), 2873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ("r14", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_INTEGER)), 2883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ("r15", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_INTEGER)), 2893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch # MD_CONTEXT_AMD64_CONTROL. 2903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ("rip", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_CONTROL)), 2913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch # MD_CONTEXT_AMD64_FLOATING_POINT 2923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ("sse_registers", EnableOnFlag(ctypes.c_uint8 * (16 * 26), 2933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MD_CONTEXT_AMD64_FLOATING_POINT)), 2943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ("vector_registers", EnableOnFlag(ctypes.c_uint8 * (16 * 26), 2953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MD_CONTEXT_AMD64_FLOATING_POINT)), 2963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ("vector_control", EnableOnFlag(ctypes.c_uint64, 2973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MD_CONTEXT_AMD64_FLOATING_POINT)), 2983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch # MD_CONTEXT_AMD64_DEBUG_REGISTERS. 2993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ("debug_control", EnableOnFlag(ctypes.c_uint64, 3003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MD_CONTEXT_AMD64_DEBUG_REGISTERS)), 3013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ("last_branch_to_rip", EnableOnFlag(ctypes.c_uint64, 3023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MD_CONTEXT_AMD64_DEBUG_REGISTERS)), 3033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ("last_branch_from_rip", EnableOnFlag(ctypes.c_uint64, 3043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MD_CONTEXT_AMD64_DEBUG_REGISTERS)), 3053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ("last_exception_to_rip", EnableOnFlag(ctypes.c_uint64, 3063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MD_CONTEXT_AMD64_DEBUG_REGISTERS)), 3073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ("last_exception_from_rip", EnableOnFlag(ctypes.c_uint64, 3083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MD_CONTEXT_AMD64_DEBUG_REGISTERS)) 3093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch]) 3103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 311e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochMINIDUMP_MEMORY_DESCRIPTOR = Descriptor([ 312e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("start", ctypes.c_uint64), 313e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("memory", MINIDUMP_LOCATION_DESCRIPTOR.ctype) 314e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch]) 315e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 316e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochMINIDUMP_MEMORY_DESCRIPTOR64 = Descriptor([ 317e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("start", ctypes.c_uint64), 318e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("size", ctypes.c_uint64) 319e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch]) 320e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 321e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochMINIDUMP_MEMORY_LIST = Descriptor([ 322e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("range_count", ctypes.c_uint32), 323e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("ranges", lambda m: MINIDUMP_MEMORY_DESCRIPTOR.ctype * m.range_count) 324e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch]) 325e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 326e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochMINIDUMP_MEMORY_LIST64 = Descriptor([ 327e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("range_count", ctypes.c_uint64), 328e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("base_rva", ctypes.c_uint64), 329e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("ranges", lambda m: MINIDUMP_MEMORY_DESCRIPTOR64.ctype * m.range_count) 330e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch]) 331e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 332e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochMINIDUMP_THREAD = Descriptor([ 333e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("id", ctypes.c_uint32), 334e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("suspend_count", ctypes.c_uint32), 335e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("priority_class", ctypes.c_uint32), 336e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("priority", ctypes.c_uint32), 337e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("ted", ctypes.c_uint64), 338e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("stack", MINIDUMP_MEMORY_DESCRIPTOR.ctype), 339e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("context", MINIDUMP_LOCATION_DESCRIPTOR.ctype) 340e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch]) 341e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 342e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochMINIDUMP_THREAD_LIST = Descriptor([ 343e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("thread_count", ctypes.c_uint32), 344e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ("threads", lambda t: MINIDUMP_THREAD.ctype * t.thread_count) 345e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch]) 346e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 3473ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochMINIDUMP_RAW_SYSTEM_INFO = Descriptor([ 3483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ("processor_architecture", ctypes.c_uint16) 3493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch]) 3503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3513ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochMD_CPU_ARCHITECTURE_X86 = 0 3523ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochMD_CPU_ARCHITECTURE_AMD64 = 9 353e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 354e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochclass MinidumpReader(object): 355e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch """Minidump (.dmp) reader.""" 356e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 357e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch _HEADER_MAGIC = 0x504d444d 358e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 359e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch def __init__(self, options, minidump_name): 360e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch self.minidump_name = minidump_name 361e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch self.minidump_file = open(minidump_name, "r") 362e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch self.minidump = mmap.mmap(self.minidump_file.fileno(), 0, mmap.MAP_PRIVATE) 363e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch self.header = MINIDUMP_HEADER.Read(self.minidump, 0) 364e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if self.header.signature != MinidumpReader._HEADER_MAGIC: 365e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch print >>sys.stderr, "Warning: unsupported minidump header magic" 366e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch DebugPrint(self.header) 367e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch directories = [] 368e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch offset = self.header.stream_directories_rva 369e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch for _ in xrange(self.header.stream_count): 370e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch directories.append(MINIDUMP_DIRECTORY.Read(self.minidump, offset)) 371e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch offset += MINIDUMP_DIRECTORY.size 3723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch self.arch = None 373e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch self.exception = None 374e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch self.exception_context = None 375e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch self.memory_list = None 3763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch self.memory_list64 = None 377e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch self.thread_map = {} 3783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch # Find MDRawSystemInfo stream and determine arch. 3803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for d in directories: 3813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if d.stream_type == MD_SYSTEM_INFO_STREAM: 3823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch system_info = MINIDUMP_RAW_SYSTEM_INFO.Read( 3833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch self.minidump, d.location.rva) 3843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch self.arch = system_info.processor_architecture 3853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch assert self.arch in [MD_CPU_ARCHITECTURE_AMD64, MD_CPU_ARCHITECTURE_X86] 3863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch assert not self.arch is None 3873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 388e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch for d in directories: 389e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch DebugPrint(d) 390e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if d.stream_type == MD_EXCEPTION_STREAM: 391e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch self.exception = MINIDUMP_EXCEPTION_STREAM.Read( 392e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch self.minidump, d.location.rva) 393e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch DebugPrint(self.exception) 3943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if self.arch == MD_CPU_ARCHITECTURE_X86: 3953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch self.exception_context = MINIDUMP_CONTEXT_X86.Read( 3963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch self.minidump, self.exception.thread_context.rva) 3973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch elif self.arch == MD_CPU_ARCHITECTURE_AMD64: 3983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch self.exception_context = MINIDUMP_CONTEXT_AMD64.Read( 3993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch self.minidump, self.exception.thread_context.rva) 400e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch DebugPrint(self.exception_context) 401e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch elif d.stream_type == MD_THREAD_LIST_STREAM: 402e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch thread_list = MINIDUMP_THREAD_LIST.Read(self.minidump, d.location.rva) 403e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch assert ctypes.sizeof(thread_list) == d.location.data_size 404e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch DebugPrint(thread_list) 405e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch for thread in thread_list.threads: 406e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch DebugPrint(thread) 407e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch self.thread_map[thread.id] = thread 408e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch elif d.stream_type == MD_MEMORY_LIST_STREAM: 409e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch print >>sys.stderr, "Warning: not a full minidump" 410e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch assert self.memory_list is None 4113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch self.memory_list = MINIDUMP_MEMORY_LIST.Read( 412e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch self.minidump, d.location.rva) 413e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch assert ctypes.sizeof(self.memory_list) == d.location.data_size 414e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch DebugPrint(self.memory_list) 4153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch elif d.stream_type == MD_MEMORY_64_LIST_STREAM: 4163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch assert self.memory_list64 is None 4173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch self.memory_list64 = MINIDUMP_MEMORY_LIST64.Read( 4183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch self.minidump, d.location.rva) 4193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch assert ctypes.sizeof(self.memory_list64) == d.location.data_size 4203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch DebugPrint(self.memory_list64) 421e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 422e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch def IsValidAddress(self, address): 423e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return self.FindLocation(address) is not None 424e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 425e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch def ReadU8(self, address): 426e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch location = self.FindLocation(address) 427e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return ctypes.c_uint8.from_buffer(self.minidump, location).value 428e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 429e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch def ReadU32(self, address): 430e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch location = self.FindLocation(address) 431e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return ctypes.c_uint32.from_buffer(self.minidump, location).value 432e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 4333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch def ReadU64(self, address): 4343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch location = self.FindLocation(address) 4353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return ctypes.c_uint64.from_buffer(self.minidump, location).value 4363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch def ReadUIntPtr(self, address): 4383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if self.arch == MD_CPU_ARCHITECTURE_AMD64: 4393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return self.ReadU64(address) 4403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch elif self.arch == MD_CPU_ARCHITECTURE_X86: 4413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return self.ReadU32(address) 4423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 443e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch def ReadBytes(self, address, size): 444e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch location = self.FindLocation(address) 445e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return self.minidump[location:location + size] 446e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 447e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch def FindLocation(self, address): 448e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch offset = 0 4493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if self.memory_list64 is not None: 4503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch for r in self.memory_list64.ranges: 4513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if r.start <= address < r.start + r.size: 4523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return self.memory_list64.base_rva + offset + address - r.start 45369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch offset += r.size 4543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if self.memory_list is not None: 4553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch for r in self.memory_list.ranges: 4563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if r.start <= address < r.start + r.memory.data_size: 4573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return r.memory.rva + address - r.start 458e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return None 459e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 460e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch def GetDisasmLines(self, address, size): 461e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch location = self.FindLocation(address) 462e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if location is None: return [] 4633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch arch = None 4643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if self.arch == MD_CPU_ARCHITECTURE_X86: 4653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch arch = "ia32" 4663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch elif self.arch == MD_CPU_ARCHITECTURE_AMD64: 4673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch arch = "x64" 468e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return disasm.GetDisasmLines(self.minidump_name, 469e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch location, 470e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch size, 4713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch arch, 472e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch False) 473e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 474e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 475e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch def Dispose(self): 476e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch self.minidump.close() 477e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch self.minidump_file.close() 478e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 4793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch def ExceptionIP(self): 4803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if self.arch == MD_CPU_ARCHITECTURE_AMD64: 4813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return self.exception_context.rip 4823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch elif self.arch == MD_CPU_ARCHITECTURE_X86: 4833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return self.exception_context.eip 4843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch def ExceptionSP(self): 4863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if self.arch == MD_CPU_ARCHITECTURE_AMD64: 4873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return self.exception_context.rsp 4883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch elif self.arch == MD_CPU_ARCHITECTURE_X86: 4893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return self.exception_context.esp 4903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch def FormatIntPtr(self, value): 4923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if self.arch == MD_CPU_ARCHITECTURE_AMD64: 4933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return "%016x" % value 4943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch elif self.arch == MD_CPU_ARCHITECTURE_X86: 4953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return "%08x" % value 4963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch def PointerSize(self): 4983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if self.arch == MD_CPU_ARCHITECTURE_AMD64: 4993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return 8 5003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch elif self.arch == MD_CPU_ARCHITECTURE_X86: 5013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return 4 5023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch def Register(self, name): 5043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return self.exception_context.__getattribute__(name) 5053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 506e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 507e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch# List of V8 instance types. Obtained by adding the code below to any .cc file. 508e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch# 5093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch# #define DUMP_TYPE(T) printf(" %d: \"%s\",\n", T, #T); 510e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch# struct P { 511e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch# P() { 5123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch# printf("INSTANCE_TYPES = {\n"); 513e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch# INSTANCE_TYPE_LIST(DUMP_TYPE) 514e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch# printf("}\n"); 515e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch# } 516e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch# }; 517e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch# static P p; 518e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochINSTANCE_TYPES = { 51969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 64: "SYMBOL_TYPE", 52069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 68: "ASCII_SYMBOL_TYPE", 52169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 65: "CONS_SYMBOL_TYPE", 52269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 69: "CONS_ASCII_SYMBOL_TYPE", 52369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 66: "EXTERNAL_SYMBOL_TYPE", 52469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 74: "EXTERNAL_SYMBOL_WITH_ASCII_DATA_TYPE", 52569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 70: "EXTERNAL_ASCII_SYMBOL_TYPE", 5263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 82: "SHORT_EXTERNAL_SYMBOL_TYPE", 5273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 90: "SHORT_EXTERNAL_SYMBOL_WITH_ASCII_DATA_TYPE", 5283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 86: "SHORT_EXTERNAL_ASCII_SYMBOL_TYPE", 52969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 0: "STRING_TYPE", 53069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 4: "ASCII_STRING_TYPE", 53169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 1: "CONS_STRING_TYPE", 53269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 5: "CONS_ASCII_STRING_TYPE", 5333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3: "SLICED_STRING_TYPE", 53469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 2: "EXTERNAL_STRING_TYPE", 53569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 10: "EXTERNAL_STRING_WITH_ASCII_DATA_TYPE", 53669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 6: "EXTERNAL_ASCII_STRING_TYPE", 5373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 18: "SHORT_EXTERNAL_STRING_TYPE", 5383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 26: "SHORT_EXTERNAL_STRING_WITH_ASCII_DATA_TYPE", 5393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 22: "SHORT_EXTERNAL_ASCII_STRING_TYPE", 54069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 6: "PRIVATE_EXTERNAL_ASCII_STRING_TYPE", 54169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 128: "MAP_TYPE", 54269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 129: "CODE_TYPE", 54369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 130: "ODDBALL_TYPE", 54469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 131: "JS_GLOBAL_PROPERTY_CELL_TYPE", 54569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 132: "HEAP_NUMBER_TYPE", 54669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 133: "FOREIGN_TYPE", 54769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 134: "BYTE_ARRAY_TYPE", 5483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 135: "FREE_SPACE_TYPE", 5493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 136: "EXTERNAL_BYTE_ARRAY_TYPE", 5503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 137: "EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE", 5513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 138: "EXTERNAL_SHORT_ARRAY_TYPE", 5523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 139: "EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE", 5533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 140: "EXTERNAL_INT_ARRAY_TYPE", 5543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 141: "EXTERNAL_UNSIGNED_INT_ARRAY_TYPE", 5553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 142: "EXTERNAL_FLOAT_ARRAY_TYPE", 5563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 144: "EXTERNAL_PIXEL_ARRAY_TYPE", 5573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 146: "FILLER_TYPE", 5583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 147: "ACCESSOR_INFO_TYPE", 5593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 148: "ACCESSOR_PAIR_TYPE", 5603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 149: "ACCESS_CHECK_INFO_TYPE", 5613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 150: "INTERCEPTOR_INFO_TYPE", 5623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 151: "CALL_HANDLER_INFO_TYPE", 5633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 152: "FUNCTION_TEMPLATE_INFO_TYPE", 5643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 153: "OBJECT_TEMPLATE_INFO_TYPE", 5653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 154: "SIGNATURE_INFO_TYPE", 5663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 155: "TYPE_SWITCH_INFO_TYPE", 5673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 156: "SCRIPT_TYPE", 5683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 157: "CODE_CACHE_TYPE", 5693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 158: "POLYMORPHIC_CODE_CACHE_TYPE", 5703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 161: "FIXED_ARRAY_TYPE", 5713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 145: "FIXED_DOUBLE_ARRAY_TYPE", 5723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 162: "SHARED_FUNCTION_INFO_TYPE", 5733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 163: "JS_MESSAGE_OBJECT_TYPE", 5743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 166: "JS_VALUE_TYPE", 5753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 167: "JS_OBJECT_TYPE", 5763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 168: "JS_CONTEXT_EXTENSION_OBJECT_TYPE", 5773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 169: "JS_GLOBAL_OBJECT_TYPE", 5783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 170: "JS_BUILTINS_OBJECT_TYPE", 5793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 171: "JS_GLOBAL_PROXY_TYPE", 5803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 172: "JS_ARRAY_TYPE", 5813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 165: "JS_PROXY_TYPE", 5823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 175: "JS_WEAK_MAP_TYPE", 5833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 176: "JS_REGEXP_TYPE", 5843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 177: "JS_FUNCTION_TYPE", 5853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 164: "JS_FUNCTION_PROXY_TYPE", 5863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 159: "DEBUG_INFO_TYPE", 5873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 160: "BREAK_POINT_INFO_TYPE", 588e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 589e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 590e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 591e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochclass Printer(object): 592e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch """Printer with indentation support.""" 593e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 594e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch def __init__(self): 595e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch self.indent = 0 596e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 597e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch def Indent(self): 598e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch self.indent += 2 599e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 600e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch def Dedent(self): 601e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch self.indent -= 2 602e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 603e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch def Print(self, string): 604e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch print "%s%s" % (self._IndentString(), string) 605e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 606e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch def PrintLines(self, lines): 607e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch indent = self._IndentString() 608e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch print "\n".join("%s%s" % (indent, line) for line in lines) 609e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 610e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch def _IndentString(self): 611e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return self.indent * " " 612e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 613e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 614e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochADDRESS_RE = re.compile(r"0x[0-9a-fA-F]+") 615e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 616e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 617e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochdef FormatDisasmLine(start, heap, line): 618e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch line_address = start + line[0] 619e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch stack_slot = heap.stack_map.get(line_address) 620e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch marker = " " 621e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if stack_slot: 622e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch marker = "=>" 623e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch code = AnnotateAddresses(heap, line[1]) 624e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return "%s%08x %08x: %s" % (marker, line_address, line[0], code) 625e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 626e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 627e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochdef AnnotateAddresses(heap, line): 628e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch extra = [] 629e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch for m in ADDRESS_RE.finditer(line): 630e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch maybe_address = int(m.group(0), 16) 631e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch object = heap.FindObject(maybe_address) 632e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if not object: continue 633e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch extra.append(str(object)) 634e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if len(extra) == 0: return line 635e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return "%s ;; %s" % (line, ", ".join(extra)) 636e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 637e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 638e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochclass HeapObject(object): 639e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch def __init__(self, heap, map, address): 640e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch self.heap = heap 641e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch self.map = map 642e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch self.address = address 643e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 644e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch def Is(self, cls): 645e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return isinstance(self, cls) 646e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 647e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch def Print(self, p): 648e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch p.Print(str(self)) 649e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 650e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch def __str__(self): 6513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return "HeapObject(%s, %s)" % (self.heap.reader.FormatIntPtr(self.address), 6523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch INSTANCE_TYPES[self.map.instance_type]) 653e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 654e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch def ObjectField(self, offset): 6553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch field_value = self.heap.reader.ReadUIntPtr(self.address + offset) 656e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return self.heap.FindObjectOrSmi(field_value) 657e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 658e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch def SmiField(self, offset): 6593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch field_value = self.heap.reader.ReadUIntPtr(self.address + offset) 660e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch assert (field_value & 1) == 0 661e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return field_value / 2 662e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 663e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 664e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochclass Map(HeapObject): 6653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch def InstanceTypeOffset(self): 6663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return self.heap.PointerSize() + self.heap.IntSize() 667e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 668e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch def __init__(self, heap, map, address): 669e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch HeapObject.__init__(self, heap, map, address) 670e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch self.instance_type = \ 6713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch heap.reader.ReadU8(self.address + self.InstanceTypeOffset()) 672e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 673e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 674e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochclass String(HeapObject): 6753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch def LengthOffset(self): 6763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return self.heap.PointerSize() 677e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 678e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch def __init__(self, heap, map, address): 679e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch HeapObject.__init__(self, heap, map, address) 6803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch self.length = self.SmiField(self.LengthOffset()) 681e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 682e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch def GetChars(self): 683e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return "?string?" 684e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 685e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch def Print(self, p): 686e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch p.Print(str(self)) 687e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 688e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch def __str__(self): 689e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return "\"%s\"" % self.GetChars() 690e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 691e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 692e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochclass SeqString(String): 6933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch def CharsOffset(self): 6943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return self.heap.PointerSize() * 3 695e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 696e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch def __init__(self, heap, map, address): 697e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch String.__init__(self, heap, map, address) 6983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch self.chars = heap.reader.ReadBytes(self.address + self.CharsOffset(), 699e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch self.length) 700e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 701e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch def GetChars(self): 702e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return self.chars 703e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 704e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 705e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochclass ExternalString(String): 7063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch # TODO(vegorov) fix ExternalString for X64 architecture 707e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch RESOURCE_OFFSET = 12 708e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 709e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch WEBKIT_RESOUCE_STRING_IMPL_OFFSET = 4 710e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch WEBKIT_STRING_IMPL_CHARS_OFFSET = 8 711e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 712e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch def __init__(self, heap, map, address): 713e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch String.__init__(self, heap, map, address) 714e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch reader = heap.reader 715e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch self.resource = \ 716e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch reader.ReadU32(self.address + ExternalString.RESOURCE_OFFSET) 717e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch self.chars = "?external string?" 718e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if not reader.IsValidAddress(self.resource): return 719e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch string_impl_address = self.resource + \ 720e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ExternalString.WEBKIT_RESOUCE_STRING_IMPL_OFFSET 721e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if not reader.IsValidAddress(string_impl_address): return 722e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch string_impl = reader.ReadU32(string_impl_address) 723e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch chars_ptr_address = string_impl + \ 724e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ExternalString.WEBKIT_STRING_IMPL_CHARS_OFFSET 725e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if not reader.IsValidAddress(chars_ptr_address): return 726e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch chars_ptr = reader.ReadU32(chars_ptr_address) 727e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if not reader.IsValidAddress(chars_ptr): return 728e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch raw_chars = reader.ReadBytes(chars_ptr, 2 * self.length) 729e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch self.chars = codecs.getdecoder("utf16")(raw_chars)[0] 730e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 731e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch def GetChars(self): 732e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return self.chars 733e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 734e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 735e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochclass ConsString(String): 7363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch def LeftOffset(self): 7373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return self.heap.PointerSize() * 3 7383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch def RightOffset(self): 7403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return self.heap.PointerSize() * 4 741e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 742e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch def __init__(self, heap, map, address): 743e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch String.__init__(self, heap, map, address) 7443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch self.left = self.ObjectField(self.LeftOffset()) 7453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch self.right = self.ObjectField(self.RightOffset()) 746e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 747e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch def GetChars(self): 748e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return self.left.GetChars() + self.right.GetChars() 749e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 750e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 751e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochclass Oddball(HeapObject): 7523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch def ToStringOffset(self): 7533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return self.heap.PointerSize() 754e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 755e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch def __init__(self, heap, map, address): 756e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch HeapObject.__init__(self, heap, map, address) 7573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch self.to_string = self.ObjectField(self.ToStringOffset()) 758e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 759e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch def Print(self, p): 760e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch p.Print(str(self)) 761e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 762e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch def __str__(self): 763e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return "<%s>" % self.to_string.GetChars() 764e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 765e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 766e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochclass FixedArray(HeapObject): 7673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch def LengthOffset(self): 7683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return self.heap.PointerSize() 7693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch def ElementsOffset(self): 7713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return self.heap.PointerSize() * 2 772e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 773e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch def __init__(self, heap, map, address): 774e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch HeapObject.__init__(self, heap, map, address) 7753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch self.length = self.SmiField(self.LengthOffset()) 776e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 777e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch def Print(self, p): 7783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch p.Print("FixedArray(%s) {" % self.heap.reader.FormatIntPtr(self.address)) 779e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch p.Indent() 780e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch p.Print("length: %d" % self.length) 7813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch base_offset = self.ElementsOffset() 782e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch for i in xrange(self.length): 7833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch offset = base_offset + 4 * i 784e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch p.Print("[%08d] = %s" % (i, self.ObjectField(offset))) 785e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch p.Dedent() 786e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch p.Print("}") 787e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 788e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch def __str__(self): 789e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return "FixedArray(%08x, length=%d)" % (self.address, self.length) 790e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 791e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 792e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochclass JSFunction(HeapObject): 7933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch def CodeEntryOffset(self): 7943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return 3 * self.heap.PointerSize() 7953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch def SharedOffset(self): 7973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return 5 * self.heap.PointerSize() 798e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 799e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch def __init__(self, heap, map, address): 800e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch HeapObject.__init__(self, heap, map, address) 801e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch code_entry = \ 8023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch heap.reader.ReadU32(self.address + self.CodeEntryOffset()) 8033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch self.code = heap.FindObject(code_entry - Code.HeaderSize(heap) + 1) 8043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch self.shared = self.ObjectField(self.SharedOffset()) 805e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 806e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch def Print(self, p): 807e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch source = "\n".join(" %s" % line for line in self._GetSource().split("\n")) 8083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch p.Print("JSFunction(%s) {" % self.heap.reader.FormatIntPtr(self.address)) 809e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch p.Indent() 810e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch p.Print("inferred name: %s" % self.shared.inferred_name) 811e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if self.shared.script.Is(Script) and self.shared.script.name.Is(String): 812e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch p.Print("script name: %s" % self.shared.script.name) 813e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch p.Print("source:") 814e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch p.PrintLines(self._GetSource().split("\n")) 815e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch p.Print("code:") 816e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch self.code.Print(p) 817e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if self.code != self.shared.code: 818e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch p.Print("unoptimized code:") 819e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch self.shared.code.Print(p) 820e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch p.Dedent() 821e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch p.Print("}") 822e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 823e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch def __str__(self): 824e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch inferred_name = "" 825e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if self.shared.Is(SharedFunctionInfo): 826e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch inferred_name = self.shared.inferred_name 8273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return "JSFunction(%s, %s)" % \ 8283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch (self.heap.reader.FormatIntPtr(self.address), inferred_name) 829e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 830e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch def _GetSource(self): 831e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch source = "?source?" 832e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch start = self.shared.start_position 833e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch end = self.shared.end_position 834e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if not self.shared.script.Is(Script): return source 835e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch script_source = self.shared.script.source 836e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if not script_source.Is(String): return source 837e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return script_source.GetChars()[start:end] 838e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 839e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 840e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochclass SharedFunctionInfo(HeapObject): 8413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch def CodeOffset(self): 8423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return 2 * self.heap.PointerSize() 8433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 8443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch def ScriptOffset(self): 8453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return 7 * self.heap.PointerSize() 8463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 8473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch def InferredNameOffset(self): 8483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return 9 * self.heap.PointerSize() 8493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 8503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch def EndPositionOffset(self): 8513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return 12 * self.heap.PointerSize() + 4 * self.heap.IntSize() 8523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 8533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch def StartPositionAndTypeOffset(self): 8543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return 12 * self.heap.PointerSize() + 5 * self.heap.IntSize() 855e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 856e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch def __init__(self, heap, map, address): 857e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch HeapObject.__init__(self, heap, map, address) 8583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch self.code = self.ObjectField(self.CodeOffset()) 8593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch self.script = self.ObjectField(self.ScriptOffset()) 8603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch self.inferred_name = self.ObjectField(self.InferredNameOffset()) 8613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if heap.PointerSize() == 8: 8623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch start_position_and_type = \ 8633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch heap.reader.ReadU32(self.StartPositionAndTypeOffset()) 8643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch self.start_position = start_position_and_type >> 2 8653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch pseudo_smi_end_position = \ 8663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch heap.reader.ReadU32(self.EndPositionOffset()) 8673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch self.end_position = pseudo_smi_end_position >> 2 8683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch else: 8693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch start_position_and_type = \ 8703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch self.SmiField(self.StartPositionAndTypeOffset()) 8713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch self.start_position = start_position_and_type >> 2 8723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch self.end_position = \ 8733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch self.SmiField(self.EndPositionOffset()) 874e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 875e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 876e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochclass Script(HeapObject): 8773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch def SourceOffset(self): 8783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return self.heap.PointerSize() 8793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 8803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch def NameOffset(self): 8813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return self.SourceOffset() + self.heap.PointerSize() 882e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 883e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch def __init__(self, heap, map, address): 884e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch HeapObject.__init__(self, heap, map, address) 8853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch self.source = self.ObjectField(self.SourceOffset()) 8863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch self.name = self.ObjectField(self.NameOffset()) 887e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 888e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 889e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochclass Code(HeapObject): 8903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CODE_ALIGNMENT_MASK = (1 << 5) - 1 8913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 8923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch def InstructionSizeOffset(self): 8933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return self.heap.PointerSize() 8943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 8953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch @staticmethod 8963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch def HeaderSize(heap): 8973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return (heap.PointerSize() + heap.IntSize() + \ 8983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4 * heap.PointerSize() + 3 * heap.IntSize() + \ 8993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code.CODE_ALIGNMENT_MASK) & ~Code.CODE_ALIGNMENT_MASK 900e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 901e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch def __init__(self, heap, map, address): 902e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch HeapObject.__init__(self, heap, map, address) 9033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch self.entry = self.address + Code.HeaderSize(heap) 904e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch self.instruction_size = \ 9053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch heap.reader.ReadU32(self.address + self.InstructionSizeOffset()) 906e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 907e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch def Print(self, p): 908e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch lines = self.heap.reader.GetDisasmLines(self.entry, self.instruction_size) 9093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch p.Print("Code(%s) {" % self.heap.reader.FormatIntPtr(self.address)) 910e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch p.Indent() 911e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch p.Print("instruction_size: %d" % self.instruction_size) 912e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch p.PrintLines(self._FormatLine(line) for line in lines) 913e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch p.Dedent() 914e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch p.Print("}") 915e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 916e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch def _FormatLine(self, line): 917e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return FormatDisasmLine(self.entry, self.heap, line) 918e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 919e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 920e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochclass V8Heap(object): 921e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch CLASS_MAP = { 922e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch "SYMBOL_TYPE": SeqString, 923e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch "ASCII_SYMBOL_TYPE": SeqString, 924e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch "CONS_SYMBOL_TYPE": ConsString, 925e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch "CONS_ASCII_SYMBOL_TYPE": ConsString, 926e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch "EXTERNAL_SYMBOL_TYPE": ExternalString, 927e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch "EXTERNAL_SYMBOL_WITH_ASCII_DATA_TYPE": ExternalString, 928e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch "EXTERNAL_ASCII_SYMBOL_TYPE": ExternalString, 9293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "SHORT_EXTERNAL_SYMBOL_TYPE": ExternalString, 9303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "SHORT_EXTERNAL_SYMBOL_WITH_ASCII_DATA_TYPE": ExternalString, 9313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "SHORT_EXTERNAL_ASCII_SYMBOL_TYPE": ExternalString, 932e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch "STRING_TYPE": SeqString, 933e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch "ASCII_STRING_TYPE": SeqString, 934e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch "CONS_STRING_TYPE": ConsString, 935e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch "CONS_ASCII_STRING_TYPE": ConsString, 936e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch "EXTERNAL_STRING_TYPE": ExternalString, 937e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch "EXTERNAL_STRING_WITH_ASCII_DATA_TYPE": ExternalString, 938e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch "EXTERNAL_ASCII_STRING_TYPE": ExternalString, 939e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 940e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch "MAP_TYPE": Map, 941e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch "ODDBALL_TYPE": Oddball, 942e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch "FIXED_ARRAY_TYPE": FixedArray, 943e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch "JS_FUNCTION_TYPE": JSFunction, 944e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch "SHARED_FUNCTION_INFO_TYPE": SharedFunctionInfo, 945e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch "SCRIPT_TYPE": Script, 946e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch "CODE_TYPE": Code 947e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 948e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 949e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch def __init__(self, reader, stack_map): 950e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch self.reader = reader 951e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch self.stack_map = stack_map 952e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch self.objects = {} 953e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 954e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch def FindObjectOrSmi(self, tagged_address): 955e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (tagged_address & 1) == 0: return tagged_address / 2 956e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return self.FindObject(tagged_address) 957e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 958e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch def FindObject(self, tagged_address): 959e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if tagged_address in self.objects: 960e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return self.objects[tagged_address] 9613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (tagged_address & self.ObjectAlignmentMask()) != 1: return None 962e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch address = tagged_address - 1 963e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if not self.reader.IsValidAddress(address): return None 9643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch map_tagged_address = self.reader.ReadUIntPtr(address) 965e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if tagged_address == map_tagged_address: 966e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch # Meta map? 967e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch meta_map = Map(self, None, address) 968e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch instance_type_name = INSTANCE_TYPES.get(meta_map.instance_type) 969e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if instance_type_name != "MAP_TYPE": return None 970e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch meta_map.map = meta_map 971e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch object = meta_map 972e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch else: 9733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch map = self.FindMap(map_tagged_address) 974e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if map is None: return None 975e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch instance_type_name = INSTANCE_TYPES.get(map.instance_type) 976e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if instance_type_name is None: return None 977e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch cls = V8Heap.CLASS_MAP.get(instance_type_name, HeapObject) 978e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch object = cls(self, map, address) 979e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch self.objects[tagged_address] = object 980e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return object 981e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 9823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch def FindMap(self, tagged_address): 9833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (tagged_address & self.MapAlignmentMask()) != 1: return None 9843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch address = tagged_address - 1 9853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if not self.reader.IsValidAddress(address): return None 9863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch object = Map(self, None, address) 9873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return object 9883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 9893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch def IntSize(self): 9903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return 4 9913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 9923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch def PointerSize(self): 9933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return self.reader.PointerSize() 9943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 9953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch def ObjectAlignmentMask(self): 9963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return self.PointerSize() - 1 9973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 9983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch def MapAlignmentMask(self): 9993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if self.reader.arch == MD_CPU_ARCHITECTURE_AMD64: 10003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return (1 << 4) - 1 10013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch elif self.reader.arch == MD_CPU_ARCHITECTURE_X86: 10023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return (1 << 5) - 1 10033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1004e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1005e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochEIP_PROXIMITY = 64 1006e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 10073ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochCONTEXT_FOR_ARCH = { 10083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MD_CPU_ARCHITECTURE_AMD64: 10093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ['rax', 'rbx', 'rcx', 'rdx', 'rdi', 'rsi', 'rbp', 'rsp', 'rip'], 10103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MD_CPU_ARCHITECTURE_X86: 10113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ['eax', 'ebx', 'ecx', 'edx', 'edi', 'esi', 'ebp', 'esp', 'eip'] 10123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 1013e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1014e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochdef AnalyzeMinidump(options, minidump_name): 1015e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch reader = MinidumpReader(options, minidump_name) 1016e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch DebugPrint("========================================") 1017e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if reader.exception is None: 1018e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch print "Minidump has no exception info" 1019e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return 1020e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch print "Exception info:" 1021e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch exception_thread = reader.thread_map[reader.exception.thread_id] 1022e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch print " thread id: %d" % exception_thread.id 1023e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch print " code: %08X" % reader.exception.exception.code 1024e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch print " context:" 10253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for r in CONTEXT_FOR_ARCH[reader.arch]: 10263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch print " %s: %s" % (r, reader.FormatIntPtr(reader.Register(r))) 1027e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch # TODO(vitalyr): decode eflags. 1028e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch print " eflags: %s" % bin(reader.exception_context.eflags)[2:] 1029e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch print 1030e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 10313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch stack_top = reader.ExceptionSP() 1032e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch stack_bottom = exception_thread.stack.start + \ 1033e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch exception_thread.stack.memory.data_size 10343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch stack_map = {reader.ExceptionIP(): -1} 10353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for slot in xrange(stack_top, stack_bottom, reader.PointerSize()): 10363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch maybe_address = reader.ReadUIntPtr(slot) 1037e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if not maybe_address in stack_map: 1038e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch stack_map[maybe_address] = slot 1039e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch heap = V8Heap(reader, stack_map) 1040e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1041e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch print "Disassembly around exception.eip:" 10423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch start = reader.ExceptionIP() - EIP_PROXIMITY 1043e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch lines = reader.GetDisasmLines(start, 2 * EIP_PROXIMITY) 1044e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch for line in lines: 1045e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch print FormatDisasmLine(start, heap, line) 1046e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch print 1047e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1048e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch print "Annotated stack (from exception.esp to bottom):" 10493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for slot in xrange(stack_top, stack_bottom, reader.PointerSize()): 10503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch maybe_address = reader.ReadUIntPtr(slot) 1051e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch heap_object = heap.FindObject(maybe_address) 10523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch print "%s: %s" % (reader.FormatIntPtr(slot), 10533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch reader.FormatIntPtr(maybe_address)) 1054e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if heap_object: 1055e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch heap_object.Print(Printer()) 1056e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch print 1057e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1058e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch reader.Dispose() 1059e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1060e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1061e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochif __name__ == "__main__": 1062e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch parser = optparse.OptionParser(USAGE) 1063e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch options, args = parser.parse_args() 1064e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if len(args) != 1: 1065e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch parser.print_help() 1066e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch sys.exit(1) 1067e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch AnalyzeMinidump(options, args[0]) 1068