#!/usr/bin/env python
#
# Copyright 2012 the V8 project authors. All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
#     * Redistributions of source code must retain the above copyright
#       notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above
#       copyright notice, this list of conditions and the following
#       disclaimer in the documentation and/or other materials provided
#       with the distribution.
#     * Neither the name of Google Inc. nor the names of its
#       contributors may be used to endorse or promote products derived
#       from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

import BaseHTTPServer
import bisect
import cgi
import cmd
import codecs
import ctypes
import datetime
import disasm
import inspect
import mmap
import optparse
import os
import re
import StringIO
import sys
import types
import urllib
import urlparse
import v8heapconst
import webbrowser

PORT_NUMBER = 8081


USAGE="""usage: %prog [OPTIONS] [DUMP-FILE]

Minidump analyzer.

Shows the processor state at the point of exception including the
stack of the active thread and the referenced objects in the V8
heap. Code objects are disassembled and the addresses linked from the
stack (e.g. pushed return addresses) are marked with "=>".

Examples:
  $ %prog 12345678-1234-1234-1234-123456789abcd-full.dmp"""


DEBUG=False


def DebugPrint(s):
  if not DEBUG: return
  print s


class Descriptor(object):
  """Descriptor of a structure in a memory."""

  def __init__(self, fields):
    self.fields = fields
    self.is_flexible = False
    for _, type_or_func in fields:
      if isinstance(type_or_func, types.FunctionType):
        self.is_flexible = True
        break
    if not self.is_flexible:
      self.ctype = Descriptor._GetCtype(fields)
      self.size = ctypes.sizeof(self.ctype)

  def Read(self, memory, offset):
    if self.is_flexible:
      fields_copy = self.fields[:]
      last = 0
      for name, type_or_func in fields_copy:
        if isinstance(type_or_func, types.FunctionType):
          partial_ctype = Descriptor._GetCtype(fields_copy[:last])
          partial_object = partial_ctype.from_buffer(memory, offset)
          type = type_or_func(partial_object)
          if type is not None:
            fields_copy[last] = (name, type)
            last += 1
        else:
          last += 1
      complete_ctype = Descriptor._GetCtype(fields_copy[:last])
    else:
      complete_ctype = self.ctype
    return complete_ctype.from_buffer(memory, offset)

  @staticmethod
  def _GetCtype(fields):
    class Raw(ctypes.Structure):
      _fields_ = fields
      _pack_ = 1

      def __str__(self):
        return "{" + ", ".join("%s: %s" % (field, self.__getattribute__(field))
                               for field, _ in Raw._fields_) + "}"
    return Raw


def FullDump(reader, heap):
  """Dump all available memory regions."""
  def dump_region(reader, start, size, location):
    print
    while start & 3 != 0:
      start += 1
      size -= 1
      location += 1
    is_executable = reader.IsProbableExecutableRegion(location, size)
    is_ascii = reader.IsProbableASCIIRegion(location, size)

    if is_executable is not False:
      lines = reader.GetDisasmLines(start, size)
      for line in lines:
        print FormatDisasmLine(start, heap, line)
      print

    if is_ascii is not False:
      # Output in the same format as the Unix hd command
      addr = start
      for i in xrange(0, size, 16):
        slot = i + location
        hex_line = ""
        asc_line = ""
        for i in xrange(16):
          if slot + i < location + size:
            byte = ctypes.c_uint8.from_buffer(reader.minidump, slot + i).value
            if byte >= 0x20 and byte < 0x7f:
              asc_line += chr(byte)
            else:
              asc_line += "."
            hex_line += " %02x" % (byte)
          else:
            hex_line += "   "
          if i == 7:
            hex_line += " "
        print "%s  %s |%s|" % (reader.FormatIntPtr(addr),
                               hex_line,
                               asc_line)
        addr += 16

    if is_executable is not True and is_ascii is not True:
      print "%s - %s" % (reader.FormatIntPtr(start),
                         reader.FormatIntPtr(start + size))
      print start + size + 1;
      for i in xrange(0, size, reader.PointerSize()):
        slot = start + i
        maybe_address = reader.ReadUIntPtr(slot)
        heap_object = heap.FindObject(maybe_address)
        print "%s: %s" % (reader.FormatIntPtr(slot),
                          reader.FormatIntPtr(maybe_address))
        if heap_object:
          heap_object.Print(Printer())
          print

  reader.ForEachMemoryRegion(dump_region)

# Heap constants generated by 'make grokdump' in v8heapconst module.
INSTANCE_TYPES = v8heapconst.INSTANCE_TYPES
KNOWN_MAPS = v8heapconst.KNOWN_MAPS
KNOWN_OBJECTS = v8heapconst.KNOWN_OBJECTS
FRAME_MARKERS = v8heapconst.FRAME_MARKERS

# Markers pushed on the stack by PushStackTraceAndDie
MAGIC_MARKER_PAIRS = (
    (0xbbbbbbbb, 0xbbbbbbbb),
    (0xfefefefe, 0xfefefeff),
)
# See StackTraceFailureMessage in isolate.h
STACK_TRACE_MARKER = 0xdecade30
# See FailureMessage in logging.cc
ERROR_MESSAGE_MARKER = 0xdecade10

# Set of structures and constants that describe the layout of minidump
# files. Based on MSDN and Google Breakpad.

MINIDUMP_HEADER = Descriptor([
  ("signature", ctypes.c_uint32),
  ("version", ctypes.c_uint32),
  ("stream_count", ctypes.c_uint32),
  ("stream_directories_rva", ctypes.c_uint32),
  ("checksum", ctypes.c_uint32),
  ("time_date_stampt", ctypes.c_uint32),
  ("flags", ctypes.c_uint64)
])

MINIDUMP_LOCATION_DESCRIPTOR = Descriptor([
  ("data_size", ctypes.c_uint32),
  ("rva", ctypes.c_uint32)
])

MINIDUMP_STRING = Descriptor([
  ("length", ctypes.c_uint32),
  ("buffer", lambda t: ctypes.c_uint8 * (t.length + 2))
])

MINIDUMP_DIRECTORY = Descriptor([
  ("stream_type", ctypes.c_uint32),
  ("location", MINIDUMP_LOCATION_DESCRIPTOR.ctype)
])

MD_EXCEPTION_MAXIMUM_PARAMETERS = 15

MINIDUMP_EXCEPTION = Descriptor([
  ("code", ctypes.c_uint32),
  ("flags", ctypes.c_uint32),
  ("record", ctypes.c_uint64),
  ("address", ctypes.c_uint64),
  ("parameter_count", ctypes.c_uint32),
  ("unused_alignment", ctypes.c_uint32),
  ("information", ctypes.c_uint64 * MD_EXCEPTION_MAXIMUM_PARAMETERS)
])

MINIDUMP_EXCEPTION_STREAM = Descriptor([
  ("thread_id", ctypes.c_uint32),
  ("unused_alignment", ctypes.c_uint32),
  ("exception", MINIDUMP_EXCEPTION.ctype),
  ("thread_context", MINIDUMP_LOCATION_DESCRIPTOR.ctype)
])

# Stream types.
MD_UNUSED_STREAM = 0
MD_RESERVED_STREAM_0 = 1
MD_RESERVED_STREAM_1 = 2
MD_THREAD_LIST_STREAM = 3
MD_MODULE_LIST_STREAM = 4
MD_MEMORY_LIST_STREAM = 5
MD_EXCEPTION_STREAM = 6
MD_SYSTEM_INFO_STREAM = 7
MD_THREAD_EX_LIST_STREAM = 8
MD_MEMORY_64_LIST_STREAM = 9
MD_COMMENT_STREAM_A = 10
MD_COMMENT_STREAM_W = 11
MD_HANDLE_DATA_STREAM = 12
MD_FUNCTION_TABLE_STREAM = 13
MD_UNLOADED_MODULE_LIST_STREAM = 14
MD_MISC_INFO_STREAM = 15
MD_MEMORY_INFO_LIST_STREAM = 16
MD_THREAD_INFO_LIST_STREAM = 17
MD_HANDLE_OPERATION_LIST_STREAM = 18

MD_FLOATINGSAVEAREA_X86_REGISTERAREA_SIZE = 80

MINIDUMP_FLOATING_SAVE_AREA_X86 = Descriptor([
  ("control_word", ctypes.c_uint32),
  ("status_word", ctypes.c_uint32),
  ("tag_word", ctypes.c_uint32),
  ("error_offset", ctypes.c_uint32),
  ("error_selector", ctypes.c_uint32),
  ("data_offset", ctypes.c_uint32),
  ("data_selector", ctypes.c_uint32),
  ("register_area", ctypes.c_uint8 * MD_FLOATINGSAVEAREA_X86_REGISTERAREA_SIZE),
  ("cr0_npx_state", ctypes.c_uint32)
])

MD_CONTEXT_X86_EXTENDED_REGISTERS_SIZE = 512

# Context flags.
MD_CONTEXT_X86 = 0x00010000
MD_CONTEXT_X86_CONTROL = (MD_CONTEXT_X86 | 0x00000001)
MD_CONTEXT_X86_INTEGER = (MD_CONTEXT_X86 | 0x00000002)
MD_CONTEXT_X86_SEGMENTS = (MD_CONTEXT_X86 | 0x00000004)
MD_CONTEXT_X86_FLOATING_POINT = (MD_CONTEXT_X86 | 0x00000008)
MD_CONTEXT_X86_DEBUG_REGISTERS = (MD_CONTEXT_X86 | 0x00000010)
MD_CONTEXT_X86_EXTENDED_REGISTERS = (MD_CONTEXT_X86 | 0x00000020)

def EnableOnFlag(type, flag):
  return lambda o: [None, type][int((o.context_flags & flag) != 0)]

MINIDUMP_CONTEXT_X86 = Descriptor([
  ("context_flags", ctypes.c_uint32),
  # MD_CONTEXT_X86_DEBUG_REGISTERS.
  ("dr0", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_DEBUG_REGISTERS)),
  ("dr1", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_DEBUG_REGISTERS)),
  ("dr2", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_DEBUG_REGISTERS)),
  ("dr3", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_DEBUG_REGISTERS)),
  ("dr6", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_DEBUG_REGISTERS)),
  ("dr7", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_DEBUG_REGISTERS)),
  # MD_CONTEXT_X86_FLOATING_POINT.
  ("float_save", EnableOnFlag(MINIDUMP_FLOATING_SAVE_AREA_X86.ctype,
                              MD_CONTEXT_X86_FLOATING_POINT)),
  # MD_CONTEXT_X86_SEGMENTS.
  ("gs", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_SEGMENTS)),
  ("fs", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_SEGMENTS)),
  ("es", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_SEGMENTS)),
  ("ds", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_SEGMENTS)),
  # MD_CONTEXT_X86_INTEGER.
  ("edi", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_INTEGER)),
  ("esi", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_INTEGER)),
  ("ebx", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_INTEGER)),
  ("edx", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_INTEGER)),
  ("ecx", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_INTEGER)),
  ("eax", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_INTEGER)),
  # MD_CONTEXT_X86_CONTROL.
  ("ebp", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_CONTROL)),
  ("eip", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_CONTROL)),
  ("cs", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_CONTROL)),
  ("eflags", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_CONTROL)),
  ("esp", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_CONTROL)),
  ("ss", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_CONTROL)),
  # MD_CONTEXT_X86_EXTENDED_REGISTERS.
  ("extended_registers",
   EnableOnFlag(ctypes.c_uint8 * MD_CONTEXT_X86_EXTENDED_REGISTERS_SIZE,
                MD_CONTEXT_X86_EXTENDED_REGISTERS))
])

MD_CONTEXT_ARM = 0x40000000
MD_CONTEXT_ARM_INTEGER = (MD_CONTEXT_ARM | 0x00000002)
MD_CONTEXT_ARM_FLOATING_POINT = (MD_CONTEXT_ARM | 0x00000004)
MD_FLOATINGSAVEAREA_ARM_FPR_COUNT = 32
MD_FLOATINGSAVEAREA_ARM_FPEXTRA_COUNT = 8

MINIDUMP_FLOATING_SAVE_AREA_ARM = Descriptor([
  ("fpscr", ctypes.c_uint64),
  ("regs", ctypes.c_uint64 * MD_FLOATINGSAVEAREA_ARM_FPR_COUNT),
  ("extra", ctypes.c_uint64 * MD_FLOATINGSAVEAREA_ARM_FPEXTRA_COUNT)
])

MINIDUMP_CONTEXT_ARM = Descriptor([
  ("context_flags", ctypes.c_uint32),
  # MD_CONTEXT_ARM_INTEGER.
  ("r0", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)),
  ("r1", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)),
  ("r2", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)),
  ("r3", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)),
  ("r4", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)),
  ("r5", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)),
  ("r6", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)),
  ("r7", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)),
  ("r8", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)),
  ("r9", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)),
  ("r10", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)),
  ("r11", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)),
  ("r12", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)),
  ("sp", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)),
  ("lr", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)),
  ("pc", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)),
  ("cpsr", ctypes.c_uint32),
  ("float_save", EnableOnFlag(MINIDUMP_FLOATING_SAVE_AREA_ARM.ctype,
                              MD_CONTEXT_ARM_FLOATING_POINT))
])


MD_CONTEXT_ARM64 =  0x80000000
MD_CONTEXT_ARM64_INTEGER = (MD_CONTEXT_ARM64 | 0x00000002)
MD_CONTEXT_ARM64_FLOATING_POINT = (MD_CONTEXT_ARM64 | 0x00000004)
MD_FLOATINGSAVEAREA_ARM64_FPR_COUNT = 64

MINIDUMP_FLOATING_SAVE_AREA_ARM = Descriptor([
  ("fpscr", ctypes.c_uint64),
  ("regs", ctypes.c_uint64 * MD_FLOATINGSAVEAREA_ARM64_FPR_COUNT),
])

MINIDUMP_CONTEXT_ARM64 = Descriptor([
  ("context_flags", ctypes.c_uint64),
  # MD_CONTEXT_ARM64_INTEGER.
  ("r0", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)),
  ("r1", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)),
  ("r2", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)),
  ("r3", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)),
  ("r4", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)),
  ("r5", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)),
  ("r6", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)),
  ("r7", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)),
  ("r8", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)),
  ("r9", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)),
  ("r10", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)),
  ("r11", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)),
  ("r12", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)),
  ("r13", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)),
  ("r14", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)),
  ("r15", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)),
  ("r16", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)),
  ("r17", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)),
  ("r18", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)),
  ("r19", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)),
  ("r20", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)),
  ("r21", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)),
  ("r22", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)),
  ("r23", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)),
  ("r24", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)),
  ("r25", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)),
  ("r26", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)),
  ("r27", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)),
  ("r28", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)),
  ("fp", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)),
  ("lr", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)),
  ("sp", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)),
  ("pc", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)),
  ("cpsr", ctypes.c_uint32),
  ("float_save", EnableOnFlag(MINIDUMP_FLOATING_SAVE_AREA_ARM.ctype,
                              MD_CONTEXT_ARM64_FLOATING_POINT))
])


MD_CONTEXT_AMD64 = 0x00100000
MD_CONTEXT_AMD64_CONTROL = (MD_CONTEXT_AMD64 | 0x00000001)
MD_CONTEXT_AMD64_INTEGER = (MD_CONTEXT_AMD64 | 0x00000002)
MD_CONTEXT_AMD64_SEGMENTS = (MD_CONTEXT_AMD64 | 0x00000004)
MD_CONTEXT_AMD64_FLOATING_POINT = (MD_CONTEXT_AMD64 | 0x00000008)
MD_CONTEXT_AMD64_DEBUG_REGISTERS = (MD_CONTEXT_AMD64 | 0x00000010)

MINIDUMP_CONTEXT_AMD64 = Descriptor([
  ("p1_home", ctypes.c_uint64),
  ("p2_home", ctypes.c_uint64),
  ("p3_home", ctypes.c_uint64),
  ("p4_home", ctypes.c_uint64),
  ("p5_home", ctypes.c_uint64),
  ("p6_home", ctypes.c_uint64),
  ("context_flags", ctypes.c_uint32),
  ("mx_csr", ctypes.c_uint32),
  # MD_CONTEXT_AMD64_CONTROL.
  ("cs", EnableOnFlag(ctypes.c_uint16, MD_CONTEXT_AMD64_CONTROL)),
  # MD_CONTEXT_AMD64_SEGMENTS
  ("ds", EnableOnFlag(ctypes.c_uint16, MD_CONTEXT_AMD64_SEGMENTS)),
  ("es", EnableOnFlag(ctypes.c_uint16, MD_CONTEXT_AMD64_SEGMENTS)),
  ("fs", EnableOnFlag(ctypes.c_uint16, MD_CONTEXT_AMD64_SEGMENTS)),
  ("gs", EnableOnFlag(ctypes.c_uint16, MD_CONTEXT_AMD64_SEGMENTS)),
  # MD_CONTEXT_AMD64_CONTROL.
  ("ss", EnableOnFlag(ctypes.c_uint16, MD_CONTEXT_AMD64_CONTROL)),
  ("eflags", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_AMD64_CONTROL)),
  # MD_CONTEXT_AMD64_DEBUG_REGISTERS.
  ("dr0", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_DEBUG_REGISTERS)),
  ("dr1", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_DEBUG_REGISTERS)),
  ("dr2", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_DEBUG_REGISTERS)),
  ("dr3", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_DEBUG_REGISTERS)),
  ("dr6", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_DEBUG_REGISTERS)),
  ("dr7", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_DEBUG_REGISTERS)),
  # MD_CONTEXT_AMD64_INTEGER.
  ("rax", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_INTEGER)),
  ("rcx", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_INTEGER)),
  ("rdx", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_INTEGER)),
  ("rbx", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_INTEGER)),
  # MD_CONTEXT_AMD64_CONTROL.
  ("rsp", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_CONTROL)),
  # MD_CONTEXT_AMD64_INTEGER.
  ("rbp", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_INTEGER)),
  ("rsi", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_INTEGER)),
  ("rdi", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_INTEGER)),
  ("r8", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_INTEGER)),
  ("r9", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_INTEGER)),
  ("r10", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_INTEGER)),
  ("r11", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_INTEGER)),
  ("r12", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_INTEGER)),
  ("r13", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_INTEGER)),
  ("r14", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_INTEGER)),
  ("r15", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_INTEGER)),
  # MD_CONTEXT_AMD64_CONTROL.
  ("rip", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_CONTROL)),
  # MD_CONTEXT_AMD64_FLOATING_POINT
  ("sse_registers", EnableOnFlag(ctypes.c_uint8 * (16 * 26),
                                 MD_CONTEXT_AMD64_FLOATING_POINT)),
  ("vector_registers", EnableOnFlag(ctypes.c_uint8 * (16 * 26),
                                    MD_CONTEXT_AMD64_FLOATING_POINT)),
  ("vector_control", EnableOnFlag(ctypes.c_uint64,
                                  MD_CONTEXT_AMD64_FLOATING_POINT)),
  # MD_CONTEXT_AMD64_DEBUG_REGISTERS.
  ("debug_control", EnableOnFlag(ctypes.c_uint64,
                                 MD_CONTEXT_AMD64_DEBUG_REGISTERS)),
  ("last_branch_to_rip", EnableOnFlag(ctypes.c_uint64,
                                      MD_CONTEXT_AMD64_DEBUG_REGISTERS)),
  ("last_branch_from_rip", EnableOnFlag(ctypes.c_uint64,
                                        MD_CONTEXT_AMD64_DEBUG_REGISTERS)),
  ("last_exception_to_rip", EnableOnFlag(ctypes.c_uint64,
                                         MD_CONTEXT_AMD64_DEBUG_REGISTERS)),
  ("last_exception_from_rip", EnableOnFlag(ctypes.c_uint64,
                                           MD_CONTEXT_AMD64_DEBUG_REGISTERS))
])

MINIDUMP_MEMORY_DESCRIPTOR = Descriptor([
  ("start", ctypes.c_uint64),
  ("memory", MINIDUMP_LOCATION_DESCRIPTOR.ctype)
])

MINIDUMP_MEMORY_DESCRIPTOR64 = Descriptor([
  ("start", ctypes.c_uint64),
  ("size", ctypes.c_uint64)
])

MINIDUMP_MEMORY_LIST = Descriptor([
  ("range_count", ctypes.c_uint32),
  ("ranges", lambda m: MINIDUMP_MEMORY_DESCRIPTOR.ctype * m.range_count)
])

MINIDUMP_MEMORY_LIST_Mac = Descriptor([
  ("range_count", ctypes.c_uint32),
  ("junk", ctypes.c_uint32),
  ("ranges", lambda m: MINIDUMP_MEMORY_DESCRIPTOR.ctype * m.range_count)
])

MINIDUMP_MEMORY_LIST64 = Descriptor([
  ("range_count", ctypes.c_uint64),
  ("base_rva", ctypes.c_uint64),
  ("ranges", lambda m: MINIDUMP_MEMORY_DESCRIPTOR64.ctype * m.range_count)
])

MINIDUMP_THREAD = Descriptor([
  ("id", ctypes.c_uint32),
  ("suspend_count", ctypes.c_uint32),
  ("priority_class", ctypes.c_uint32),
  ("priority", ctypes.c_uint32),
  ("ted", ctypes.c_uint64),
  ("stack", MINIDUMP_MEMORY_DESCRIPTOR.ctype),
  ("context", MINIDUMP_LOCATION_DESCRIPTOR.ctype)
])

MINIDUMP_THREAD_LIST = Descriptor([
  ("thread_count", ctypes.c_uint32),
  ("threads", lambda t: MINIDUMP_THREAD.ctype * t.thread_count)
])

MINIDUMP_THREAD_LIST_Mac = Descriptor([
  ("thread_count", ctypes.c_uint32),
  ("junk", ctypes.c_uint32),
  ("threads", lambda t: MINIDUMP_THREAD.ctype * t.thread_count)
])

MINIDUMP_VS_FIXEDFILEINFO = Descriptor([
  ("dwSignature", ctypes.c_uint32),
  ("dwStrucVersion", ctypes.c_uint32),
  ("dwFileVersionMS", ctypes.c_uint32),
  ("dwFileVersionLS", ctypes.c_uint32),
  ("dwProductVersionMS", ctypes.c_uint32),
  ("dwProductVersionLS", ctypes.c_uint32),
  ("dwFileFlagsMask", ctypes.c_uint32),
  ("dwFileFlags", ctypes.c_uint32),
  ("dwFileOS", ctypes.c_uint32),
  ("dwFileType", ctypes.c_uint32),
  ("dwFileSubtype", ctypes.c_uint32),
  ("dwFileDateMS", ctypes.c_uint32),
  ("dwFileDateLS", ctypes.c_uint32)
])

MINIDUMP_RAW_MODULE = Descriptor([
  ("base_of_image", ctypes.c_uint64),
  ("size_of_image", ctypes.c_uint32),
  ("checksum", ctypes.c_uint32),
  ("time_date_stamp", ctypes.c_uint32),
  ("module_name_rva", ctypes.c_uint32),
  ("version_info", MINIDUMP_VS_FIXEDFILEINFO.ctype),
  ("cv_record", MINIDUMP_LOCATION_DESCRIPTOR.ctype),
  ("misc_record", MINIDUMP_LOCATION_DESCRIPTOR.ctype),
  ("reserved0", ctypes.c_uint32 * 2),
  ("reserved1", ctypes.c_uint32 * 2)
])

MINIDUMP_MODULE_LIST = Descriptor([
  ("number_of_modules", ctypes.c_uint32),
  ("modules", lambda t: MINIDUMP_RAW_MODULE.ctype * t.number_of_modules)
])

MINIDUMP_MODULE_LIST_Mac = Descriptor([
  ("number_of_modules", ctypes.c_uint32),
  ("junk", ctypes.c_uint32),
  ("modules", lambda t: MINIDUMP_RAW_MODULE.ctype * t.number_of_modules)
])

MINIDUMP_RAW_SYSTEM_INFO = Descriptor([
  ("processor_architecture", ctypes.c_uint16)
])

MD_CPU_ARCHITECTURE_X86 = 0
MD_CPU_ARCHITECTURE_ARM = 5
MD_CPU_ARCHITECTURE_ARM64 = 0x8003
MD_CPU_ARCHITECTURE_AMD64 = 9

OBJDUMP_BIN = None
DEFAULT_OBJDUMP_BIN = '/usr/bin/objdump'

class FuncSymbol:
  def __init__(self, start, size, name):
    self.start = start
    self.end = self.start + size
    self.name = name

  def __cmp__(self, other):
    if isinstance(other, FuncSymbol):
      return self.start - other.start
    return self.start - other

  def Covers(self, addr):
    return (self.start <= addr) and (addr < self.end)

class MinidumpReader(object):
  """Minidump (.dmp) reader."""

  _HEADER_MAGIC = 0x504d444d

  def __init__(self, options, minidump_name):
    self.minidump_name = minidump_name
    self.minidump_file = open(minidump_name, "r")
    self.minidump = mmap.mmap(self.minidump_file.fileno(), 0, mmap.MAP_PRIVATE)
    self.header = MINIDUMP_HEADER.Read(self.minidump, 0)
    if self.header.signature != MinidumpReader._HEADER_MAGIC:
      print >>sys.stderr, "Warning: Unsupported minidump header magic!"
    DebugPrint(self.header)
    directories = []
    offset = self.header.stream_directories_rva
    for _ in xrange(self.header.stream_count):
      directories.append(MINIDUMP_DIRECTORY.Read(self.minidump, offset))
      offset += MINIDUMP_DIRECTORY.size
    self.arch = None
    self.exception = None
    self.exception_context = None
    self.memory_list = None
    self.memory_list64 = None
    self.module_list = None
    self.thread_map = {}

    self.symdir = options.symdir
    self.modules_with_symbols = []
    self.symbols = []

    self._ReadArchitecture(directories)
    self._ReadDirectories(directories)
    self._FindObjdump(options)

  def _ReadArchitecture(self, directories):
    # Find MDRawSystemInfo stream and determine arch.
    for d in directories:
      if d.stream_type == MD_SYSTEM_INFO_STREAM:
        system_info = MINIDUMP_RAW_SYSTEM_INFO.Read(
            self.minidump, d.location.rva)
        self.arch = system_info.processor_architecture
        assert self.arch in [MD_CPU_ARCHITECTURE_AMD64,
                             MD_CPU_ARCHITECTURE_ARM,
                             MD_CPU_ARCHITECTURE_ARM64,
                             MD_CPU_ARCHITECTURE_X86]
    assert not self.arch is None

  def _ReadDirectories(self, directories):
    for d in directories:
      DebugPrint(d)
      if d.stream_type == MD_EXCEPTION_STREAM:
        self.exception = MINIDUMP_EXCEPTION_STREAM.Read(
          self.minidump, d.location.rva)
        DebugPrint(self.exception)
        self.exception_context = self.ContextDescriptor().Read(
            self.minidump, self.exception.thread_context.rva)
        DebugPrint(self.exception_context)
      elif d.stream_type == MD_THREAD_LIST_STREAM:
        thread_list = MINIDUMP_THREAD_LIST.Read(self.minidump, d.location.rva)
        if ctypes.sizeof(thread_list) + 4 == d.location.data_size:
          thread_list = MINIDUMP_THREAD_LIST_Mac.Read(
              self.minidump, d.location.rva)
        assert ctypes.sizeof(thread_list) == d.location.data_size
        DebugPrint(thread_list)
        for thread in thread_list.threads:
          DebugPrint(thread)
          self.thread_map[thread.id] = thread
      elif d.stream_type == MD_MODULE_LIST_STREAM:
        assert self.module_list is None
        self.module_list = MINIDUMP_MODULE_LIST.Read(
          self.minidump, d.location.rva)
        if ctypes.sizeof(self.module_list) + 4 == d.location.data_size:
          self.module_list = MINIDUMP_MODULE_LIST_Mac.Read(
              self.minidump, d.location.rva)
        assert ctypes.sizeof(self.module_list) == d.location.data_size
        DebugPrint(self.module_list)
      elif d.stream_type == MD_MEMORY_LIST_STREAM:
        print >>sys.stderr, "Warning: This is not a full minidump!"
        assert self.memory_list is None
        self.memory_list = MINIDUMP_MEMORY_LIST.Read(
          self.minidump, d.location.rva)
        if ctypes.sizeof(self.memory_list) + 4 == d.location.data_size:
          self.memory_list = MINIDUMP_MEMORY_LIST_Mac.Read(
              self.minidump, d.location.rva)
        assert ctypes.sizeof(self.memory_list) == d.location.data_size
        DebugPrint(self.memory_list)
      elif d.stream_type == MD_MEMORY_64_LIST_STREAM:
        assert self.memory_list64 is None
        self.memory_list64 = MINIDUMP_MEMORY_LIST64.Read(
          self.minidump, d.location.rva)
        assert ctypes.sizeof(self.memory_list64) == d.location.data_size
        DebugPrint(self.memory_list64)

  def _FindObjdump(self, options):
    if options.objdump:
        objdump_bin = options.objdump
    else:
      objdump_bin = self._FindThirdPartyObjdump()
    if not objdump_bin or not os.path.exists(objdump_bin):
      print "# Cannot find '%s', falling back to default objdump '%s'" % (
          objdump_bin, DEFAULT_OBJDUMP_BIN)
      objdump_bin  = DEFAULT_OBJDUMP_BIN
    global OBJDUMP_BIN
    OBJDUMP_BIN = objdump_bin
    disasm.OBJDUMP_BIN = objdump_bin

  def _FindThirdPartyObjdump(self):
      # Try to find the platform specific objdump
      third_party_dir = os.path.join(
          os.path.dirname(os.path.dirname(__file__)), 'third_party')
      objdumps = []
      for root, dirs, files in os.walk(third_party_dir):
        for file in files:
          if file.endswith("objdump"):
            objdumps.append(os.path.join(root, file))
      if self.arch == MD_CPU_ARCHITECTURE_ARM:
        platform_filter = 'arm-linux'
      elif self.arch == MD_CPU_ARCHITECTURE_ARM64:
        platform_filter = 'aarch64'
      else:
        # use default otherwise
        return None
      print ("# Looking for platform specific (%s) objdump in "
             "third_party directory.") % platform_filter
      objdumps = filter(lambda file: platform_filter in file >= 0, objdumps)
      if len(objdumps) == 0:
        print "# Could not find platform specific objdump in third_party."
        print "# Make sure you installed the correct SDK."
        return None
      return objdumps[0]

  def ContextDescriptor(self):
    if self.arch == MD_CPU_ARCHITECTURE_X86:
      return MINIDUMP_CONTEXT_X86
    elif self.arch == MD_CPU_ARCHITECTURE_AMD64:
      return MINIDUMP_CONTEXT_AMD64
    elif self.arch == MD_CPU_ARCHITECTURE_ARM:
      return MINIDUMP_CONTEXT_ARM
    elif self.arch == MD_CPU_ARCHITECTURE_ARM64:
      return MINIDUMP_CONTEXT_ARM64
    else:
      return None

  def IsValidAlignedAddress(self, address):
    return self.IsAlignedAddress(address) and self.IsValidAddress(address)

  def IsValidAddress(self, address):
    return self.FindLocation(address) is not None

  def IsAlignedAddress(self, address):
    return (address % self.PointerSize()) == 0

  def IsExceptionStackAddress(self, address):
    if not self.IsAlignedAddress(address): return False
    return self.IsAnyExceptionStackAddress(address)

  def IsAnyExceptionStackAddress(self, address):
    return self.StackTop() <= address <= self.StackBottom()

  def IsValidExceptionStackAddress(self, address):
    if not self.IsValidAddress(address): return False
    return self.IsExceptionStackAddress(address)

  def IsModuleAddress(self, address):
    return self.GetModuleForAddress(address) != None

  def GetModuleForAddress(self, address):
    for module in self.module_list.modules:
      start = module.base_of_image
      end = start + module.size_of_image
      if start <= address < end: return module
    return None

  def ReadU8(self, address):
    location = self.FindLocation(address)
    return ctypes.c_uint8.from_buffer(self.minidump, location).value

  def ReadU32(self, address):
    location = self.FindLocation(address)
    return ctypes.c_uint32.from_buffer(self.minidump, location).value

  def ReadU64(self, address):
    location = self.FindLocation(address)
    return ctypes.c_uint64.from_buffer(self.minidump, location).value

  def Is64(self):
    return (self.arch == MD_CPU_ARCHITECTURE_ARM64 or
            self.arch == MD_CPU_ARCHITECTURE_AMD64)

  def ReadUIntPtr(self, address):
    if self.Is64():
      return self.ReadU64(address)
    return self.ReadU32(address)

  def ReadBytes(self, address, size):
    location = self.FindLocation(address)
    return self.minidump[location:location + size]

  def _ReadWord(self, location):
    if self.Is64():
      return ctypes.c_uint64.from_buffer(self.minidump, location).value
    return ctypes.c_uint32.from_buffer(self.minidump, location).value

  def ReadAsciiPtr(self, address):
    ascii_content = [c if c >= '\x20' and c <  '\x7f' else '.'
                       for c in self.ReadBytes(address, self.PointerSize())]
    return ''.join(ascii_content)

  def ReadAsciiString(self, address):
    string = ""
    while self.IsValidAddress(address):
      code = self.ReadU8(address)
      if 0 < code < 128:
        string += chr(code)
      else:
        break
      address += 1
    return string

  def IsProbableASCIIRegion(self, location, length):
    ascii_bytes = 0
    non_ascii_bytes = 0
    for i in xrange(length):
      loc = location + i
      byte = ctypes.c_uint8.from_buffer(self.minidump, loc).value
      if byte >= 0x7f:
        non_ascii_bytes += 1
      if byte < 0x20 and byte != 0:
        non_ascii_bytes += 1
      if byte < 0x7f and byte >= 0x20:
        ascii_bytes += 1
      if byte == 0xa:  # newline
        ascii_bytes += 1
    if ascii_bytes * 10 <= length:
      return False
    if length > 0 and ascii_bytes > non_ascii_bytes * 7:
      return True
    if ascii_bytes > non_ascii_bytes * 3:
      return None  # Maybe
    return False

  def IsProbableExecutableRegion(self, location, length):
    opcode_bytes = 0
    sixty_four = self.Is64()
    for i in xrange(length):
      loc = location + i
      byte = ctypes.c_uint8.from_buffer(self.minidump, loc).value
      if (byte == 0x8b or           # mov
          byte == 0x89 or           # mov reg-reg
          (byte & 0xf0) == 0x50 or  # push/pop
          (sixty_four and (byte & 0xf0) == 0x40) or  # rex prefix
          byte == 0xc3 or           # return
          byte == 0x74 or           # jeq
          byte == 0x84 or           # jeq far
          byte == 0x75 or           # jne
          byte == 0x85 or           # jne far
          byte == 0xe8 or           # call
          byte == 0xe9 or           # jmp far
          byte == 0xeb):            # jmp near
        opcode_bytes += 1
    opcode_percent = (opcode_bytes * 100) / length
    threshold = 20
    if opcode_percent > threshold + 2:
      return True
    if opcode_percent > threshold - 2:
      return None  # Maybe
    return False

  def FindRegion(self, addr):
    answer = [-1, -1]
    def is_in(reader, start, size, location):
      if addr >= start and addr < start + size:
        answer[0] = start
        answer[1] = size
    self.ForEachMemoryRegion(is_in)
    if answer[0] == -1:
      return None
    return answer

  def ForEachMemoryRegion(self, cb):
    if self.memory_list64 is not None:
      for r in self.memory_list64.ranges:
        location = self.memory_list64.base_rva + offset
        cb(self, r.start, r.size, location)
        offset += r.size

    if self.memory_list is not None:
      for r in self.memory_list.ranges:
        cb(self, r.start, r.memory.data_size, r.memory.rva)

  def FindWord(self, word, alignment=0):
    def search_inside_region(reader, start, size, location):
      location = (location + alignment) & ~alignment
      for i in xrange(size - self.PointerSize()):
        loc = location + i
        if reader._ReadWord(loc) == word:
          slot = start + (loc - location)
          print "%s: %s" % (reader.FormatIntPtr(slot),
                            reader.FormatIntPtr(word))
    self.ForEachMemoryRegion(search_inside_region)

  def FindWordList(self, word):
    aligned_res = []
    unaligned_res = []
    def search_inside_region(reader, start, size, location):
      for i in xrange(size - self.PointerSize()):
        loc = location + i
        if reader._ReadWord(loc) == word:
          slot = start + (loc - location)
          if self.IsAlignedAddress(slot):
            aligned_res.append(slot)
          else:
            unaligned_res.append(slot)
    self.ForEachMemoryRegion(search_inside_region)
    return (aligned_res, unaligned_res)

  def FindLocation(self, address):
    offset = 0
    if self.memory_list64 is not None:
      for r in self.memory_list64.ranges:
        if r.start <= address < r.start + r.size:
          return self.memory_list64.base_rva + offset + address - r.start
        offset += r.size
    if self.memory_list is not None:
      for r in self.memory_list.ranges:
        if r.start <= address < r.start + r.memory.data_size:
          return r.memory.rva + address - r.start
    return None

  def GetDisasmLines(self, address, size):
    def CountUndefinedInstructions(lines):
      pattern = "<UNDEFINED>"
      return sum([line.count(pattern) for (ignore, line) in lines])

    location = self.FindLocation(address)
    if location is None: return []
    arch = None
    possible_objdump_flags = [""]
    if self.arch == MD_CPU_ARCHITECTURE_X86:
      arch = "ia32"
    elif self.arch == MD_CPU_ARCHITECTURE_ARM:
      arch = "arm"
      possible_objdump_flags = ["", "--disassembler-options=force-thumb"]
    elif self.arch == MD_CPU_ARCHITECTURE_ARM64:
      arch = "arm64"
      possible_objdump_flags = ["", "--disassembler-options=force-thumb"]
    elif self.arch == MD_CPU_ARCHITECTURE_AMD64:
      arch = "x64"
    results = [ disasm.GetDisasmLines(self.minidump_name,
                                     location,
                                     size,
                                     arch,
                                     False,
                                     objdump_flags)
                for objdump_flags in possible_objdump_flags ]
    return min(results, key=CountUndefinedInstructions)


  def Dispose(self):
    self.minidump.close()
    self.minidump_file.close()

  def ExceptionIP(self):
    if self.arch == MD_CPU_ARCHITECTURE_AMD64:
      return self.exception_context.rip
    elif self.arch == MD_CPU_ARCHITECTURE_ARM:
      return self.exception_context.pc
    elif self.arch == MD_CPU_ARCHITECTURE_ARM64:
      return self.exception_context.pc
    elif self.arch == MD_CPU_ARCHITECTURE_X86:
      return self.exception_context.eip

  def ExceptionSP(self):
    if self.arch == MD_CPU_ARCHITECTURE_AMD64:
      return self.exception_context.rsp
    elif self.arch == MD_CPU_ARCHITECTURE_ARM:
      return self.exception_context.sp
    elif self.arch == MD_CPU_ARCHITECTURE_ARM64:
      return self.exception_context.sp
    elif self.arch == MD_CPU_ARCHITECTURE_X86:
      return self.exception_context.esp

  def ExceptionFP(self):
    if self.arch == MD_CPU_ARCHITECTURE_AMD64:
      return self.exception_context.rbp
    elif self.arch == MD_CPU_ARCHITECTURE_ARM:
      return None
    elif self.arch == MD_CPU_ARCHITECTURE_ARM64:
      return self.exception_context.fp
    elif self.arch == MD_CPU_ARCHITECTURE_X86:
      return self.exception_context.ebp

  def ExceptionThread(self):
    return self.thread_map[self.exception.thread_id]

  def StackTop(self):
    return self.ExceptionSP()

  def StackBottom(self):
    exception_thread = self.ExceptionThread()
    return exception_thread.stack.start + \
        exception_thread.stack.memory.data_size

  def FormatIntPtr(self, value):
    if self.Is64():
      return "%016x" % value
    return "%08x" % value

  def PointerSize(self):
    if self.Is64():
      return 8
    return 4

  def Register(self, name):
    return self.exception_context.__getattribute__(name)

  def ReadMinidumpString(self, rva):
    string = bytearray(MINIDUMP_STRING.Read(self.minidump, rva).buffer)
    string = string.decode("utf16")
    return string[0:len(string) - 1]

  # Load FUNC records from a BreakPad symbol file
  #
  #    http://code.google.com/p/google-breakpad/wiki/SymbolFiles
  #
  def _LoadSymbolsFrom(self, symfile, baseaddr):
    print "Loading symbols from %s" % (symfile)
    funcs = []
    with open(symfile) as f:
      for line in f:
        result = re.match(
            r"^FUNC ([a-f0-9]+) ([a-f0-9]+) ([a-f0-9]+) (.*)$", line)
        if result is not None:
          start = int(result.group(1), 16)
          size = int(result.group(2), 16)
          name = result.group(4).rstrip()
          bisect.insort_left(self.symbols,
                             FuncSymbol(baseaddr + start, size, name))
    print " ... done"

  def TryLoadSymbolsFor(self, modulename, module):
    try:
      symfile = os.path.join(self.symdir,
                             modulename.replace('.', '_') + ".pdb.sym")
      if os.path.isfile(symfile):
        self._LoadSymbolsFrom(symfile, module.base_of_image)
        self.modules_with_symbols.append(module)
    except Exception as e:
      print "  ... failure (%s)" % (e)

  # Returns true if address is covered by some module that has loaded symbols.
  def _IsInModuleWithSymbols(self, addr):
    for module in self.modules_with_symbols:
      start = module.base_of_image
      end = start + module.size_of_image
      if (start <= addr) and (addr < end):
        return True
    return False

  # Find symbol covering the given address and return its name in format
  #     <symbol name>+<offset from the start>
  def FindSymbol(self, addr):
    if not self._IsInModuleWithSymbols(addr):
      return None

    i = bisect.bisect_left(self.symbols, addr)
    symbol = None
    if (0 < i) and self.symbols[i - 1].Covers(addr):
      symbol = self.symbols[i - 1]
    elif (i < len(self.symbols)) and self.symbols[i].Covers(addr):
      symbol = self.symbols[i]
    else:
      return None
    diff = addr - symbol.start
    return "%s+0x%x" % (symbol.name, diff)


class Printer(object):
  """Printer with indentation support."""

  def __init__(self):
    self.indent = 0

  def Indent(self):
    self.indent += 2

  def Dedent(self):
    self.indent -= 2

  def Print(self, string):
    print "%s%s" % (self._IndentString(), string)

  def PrintLines(self, lines):
    indent = self._IndentString()
    print "\n".join("%s%s" % (indent, line) for line in lines)

  def _IndentString(self):
    return self.indent * " "


ADDRESS_RE = re.compile(r"0x[0-9a-fA-F]+")


def FormatDisasmLine(start, heap, line):
  line_address = start + line[0]
  stack_slot = heap.stack_map.get(line_address)
  marker = "  "
  if stack_slot:
    marker = "=>"
  code = AnnotateAddresses(heap, line[1])

  # Compute the actual call target which the disassembler is too stupid
  # to figure out (it adds the call offset to the disassembly offset rather
  # than the absolute instruction address).
  if heap.reader.arch == MD_CPU_ARCHITECTURE_X86:
    if code.startswith("e8"):
      words = code.split()
      if len(words) > 6 and words[5] == "call":
        offset = int(words[4] + words[3] + words[2] + words[1], 16)
        target = (line_address + offset + 5) & 0xFFFFFFFF
        code = code.replace(words[6], "0x%08x" % target)
  # TODO(jkummerow): port this hack to ARM and x64.

  return "%s%08x %08x: %s" % (marker, line_address, line[0], code)


def AnnotateAddresses(heap, line):
  extra = []
  for m in ADDRESS_RE.finditer(line):
    maybe_address = int(m.group(0), 16)
    object = heap.FindObject(maybe_address)
    if not object: continue
    extra.append(str(object))
  if len(extra) == 0: return line
  return "%s  ;; %s" % (line, ", ".join(extra))


class HeapObject(object):
  def __init__(self, heap, map, address):
    self.heap = heap
    self.map = map
    self.address = address

  def Is(self, cls):
    return isinstance(self, cls)

  def Print(self, p):
    p.Print(str(self))

  def __str__(self):
    instance_type = "???"
    if self.map is not None:
      instance_type = INSTANCE_TYPES[self.map.instance_type]
    return "%s(%s, %s)" % (self.__class__.__name__,
                           self.heap.reader.FormatIntPtr(self.address),
                           instance_type)

  def ObjectField(self, offset):
    field_value = self.heap.reader.ReadUIntPtr(self.address + offset)
    return self.heap.FindObjectOrSmi(field_value)

  def SmiField(self, offset):
    field_value = self.heap.reader.ReadUIntPtr(self.address + offset)
    if self.heap.IsSmi(field_value):
      return self.heap.SmiUntag(field_value)
    return None


class Map(HeapObject):
  def Decode(self, offset, size, value):
    return (value >> offset) & ((1 << size) - 1)

  # Instance Sizes
  def InstanceSizesOffset(self):
    return self.heap.PointerSize()

  def InstanceSizeOffset(self):
    return self.InstanceSizesOffset()

  def InObjectProperties(self):
    return self.InstanceSizeOffset() + 1

  def UnusedByte(self):
    return self.InObjectProperties() + 1

  def VisitorId(self):
    return self.UnusedByte() + 1

  # Instance Attributes
  def InstanceAttributesOffset(self):
    return self.InstanceSizesOffset() + self.heap.IntSize()

  def InstanceTypeOffset(self):
    return self.InstanceAttributesOffset()

  def BitFieldOffset(self):
    return self.InstanceTypeOffset() + 1

  def BitField2Offset(self):
    return self.BitFieldOffset() + 1

  def UnusedPropertyFieldsOffset(self):
    return self.BitField2Offset() + 1

  # Other fields
  def BitField3Offset(self):
    return self.InstanceAttributesOffset() + self.heap.IntSize()

  def PrototypeOffset(self):
    return self.BitField3Offset() + self.heap.PointerSize()

  def ConstructorOrBackPointerOffset(self):
    return self.PrototypeOffset() + self.heap.PointerSize()

  def TransitionsOrPrototypeInfoOffset(self):
    return self.ConstructorOrBackPointerOffset() + self.heap.PointerSize()

  def DescriptorsOffset(self):
    return self.TransitionsOrPrototypeInfoOffset() + self.heap.PointerSize()

  def LayoutDescriptorOffset(self):
    return self.DescriptorsOffset() + self.heap.PointerSize()

  def CodeCacheOffset(self):
    if (self.heap.reader.Is64()):
      return self.LayoutDescriptorOffset() + self.heap.PointerSize()
    return self.DescriptorsOffset() + self.heap.PointerSize()

  def DependentCodeOffset(self):
    return self.CodeCacheOffset() + self.heap.PointerSize()

  def ReadByte(self, offset):
    return self.heap.reader.ReadU8(self.address + offset)

  def ReadWord(self, offset):
    return self.heap.reader.ReadUIntPtr(self.address + offset)

  def Print(self, p):
    p.Print("Map(%08x)" % (self.address))
    p.Print("  - size: %d, inobject: %d, (unused: %d), visitor: %d" % (
        self.ReadByte(self.InstanceSizeOffset()),
        self.ReadByte(self.InObjectProperties()),
        self.ReadByte(self.UnusedByte()),
        self.VisitorId()))

    instance_type = INSTANCE_TYPES[self.ReadByte(self.InstanceTypeOffset())]
    bitfield = self.ReadByte(self.BitFieldOffset())
    bitfield2 = self.ReadByte(self.BitField2Offset())
    unused = self.ReadByte(self.UnusedPropertyFieldsOffset())
    p.Print("  - %s, bf: %d, bf2: %d, unused: %d" % (
        instance_type, bitfield, bitfield2, unused))

    p.Print("  - kind: %s" % (self.Decode(3, 5, bitfield2)))

    bitfield3 = self.ReadWord(self.BitField3Offset())

    p.Print(
        "  - EnumLength: %d NumberOfOwnDescriptors: %d OwnsDescriptors: %s" % (
            self.Decode(0, 10, bitfield3),
            self.Decode(10, 10, bitfield3),
            self.Decode(21, 1, bitfield3)))
    p.Print("  - DictionaryMap: %s" % (self.Decode(20, 1, bitfield3)))
    p.Print("  - Deprecated: %s" % (self.Decode(23, 1, bitfield3)))
    p.Print("  - IsUnstable: %s" % (self.Decode(24, 1, bitfield3)))
    p.Print("  - NewTargetIsBase: %s" % (self.Decode(27, 1, bitfield3)))

    descriptors = self.ObjectField(self.DescriptorsOffset())
    if descriptors.__class__ == FixedArray:
      DescriptorArray(descriptors).Print(p)
    else:
      p.Print("  - Descriptors: %s" % (descriptors))

    transitions = self.ObjectField(self.TransitionsOrPrototypeInfoOffset())
    if transitions.__class__ == FixedArray:
      TransitionArray(transitions).Print(p)
    else:
      p.Print("  - TransitionsOrPrototypeInfo: %s" % (transitions))

    p.Print("  - Prototype: %s" % self.ObjectField(self.PrototypeOffset()))

  def __init__(self, heap, map, address):
    HeapObject.__init__(self, heap, map, address)
    self.instance_type = \
        heap.reader.ReadU8(self.address + self.InstanceTypeOffset())


class String(HeapObject):
  def LengthOffset(self):
    # First word after the map is the hash, the second is the length.
    return self.heap.PointerSize() * 2

  def __init__(self, heap, map, address):
    HeapObject.__init__(self, heap, map, address)
    self.length = self.SmiField(self.LengthOffset())

  def GetChars(self):
    return "?string?"

  def Print(self, p):
    p.Print(str(self))

  def __str__(self):
    return "\"%s\"" % self.GetChars()


class SeqString(String):
  def CharsOffset(self):
    return self.heap.PointerSize() * 3

  def __init__(self, heap, map, address):
    String.__init__(self, heap, map, address)
    self.chars = heap.reader.ReadBytes(self.address + self.CharsOffset(),
                                       self.length)

  def GetChars(self):
    return self.chars


class ExternalString(String):
  # TODO(vegorov) fix ExternalString for X64 architecture
  RESOURCE_OFFSET = 12

  WEBKIT_RESOUCE_STRING_IMPL_OFFSET = 4
  WEBKIT_STRING_IMPL_CHARS_OFFSET = 8

  def __init__(self, heap, map, address):
    String.__init__(self, heap, map, address)
    reader = heap.reader
    self.resource = \
        reader.ReadU32(self.address + ExternalString.RESOURCE_OFFSET)
    self.chars = "?external string?"
    if not reader.IsValidAddress(self.resource): return
    string_impl_address = self.resource + \
        ExternalString.WEBKIT_RESOUCE_STRING_IMPL_OFFSET
    if not reader.IsValidAddress(string_impl_address): return
    string_impl = reader.ReadU32(string_impl_address)
    chars_ptr_address = string_impl + \
        ExternalString.WEBKIT_STRING_IMPL_CHARS_OFFSET
    if not reader.IsValidAddress(chars_ptr_address): return
    chars_ptr = reader.ReadU32(chars_ptr_address)
    if not reader.IsValidAddress(chars_ptr): return
    raw_chars = reader.ReadBytes(chars_ptr, 2 * self.length)
    self.chars = codecs.getdecoder("utf16")(raw_chars)[0]

  def GetChars(self):
    return self.chars


class ConsString(String):
  def LeftOffset(self):
    return self.heap.PointerSize() * 3

  def RightOffset(self):
    return self.heap.PointerSize() * 4

  def __init__(self, heap, map, address):
    String.__init__(self, heap, map, address)
    self.left = self.ObjectField(self.LeftOffset())
    self.right = self.ObjectField(self.RightOffset())

  def GetChars(self):
    try:
      return self.left.GetChars() + self.right.GetChars()
    except:
      return "***CAUGHT EXCEPTION IN GROKDUMP***"


class Oddball(HeapObject):
  #Should match declarations in objects.h
  KINDS = [
    "False",
    "True",
    "TheHole",
    "Null",
    "ArgumentMarker",
    "Undefined",
    "Other"
  ]

  def ToStringOffset(self):
    return self.heap.PointerSize()

  def ToNumberOffset(self):
    return self.ToStringOffset() + self.heap.PointerSize()

  def KindOffset(self):
    return self.ToNumberOffset() + self.heap.PointerSize()

  def __init__(self, heap, map, address):
    HeapObject.__init__(self, heap, map, address)
    self.to_string = self.ObjectField(self.ToStringOffset())
    self.kind = self.SmiField(self.KindOffset())

  def Print(self, p):
    p.Print(str(self))

  def __str__(self):
    if self.to_string:
      return "Oddball(%08x, <%s>)" % (self.address, str(self.to_string))
    else:
      kind = "???"
      if 0 <= self.kind < len(Oddball.KINDS):
        kind = Oddball.KINDS[self.kind]
      return "Oddball(%08x, kind=%s)" % (self.address, kind)


class FixedArray(HeapObject):
  def LengthOffset(self):
    return self.heap.PointerSize()

  def ElementsOffset(self):
    return self.heap.PointerSize() * 2

  def MemberOffset(self, i):
    return self.ElementsOffset() + self.heap.PointerSize() * i

  def Get(self, i):
    return self.ObjectField(self.MemberOffset(i))

  def __init__(self, heap, map, address):
    HeapObject.__init__(self, heap, map, address)
    self.length = self.SmiField(self.LengthOffset())

  def Print(self, p):
    p.Print("FixedArray(%s) {" % self.heap.reader.FormatIntPtr(self.address))
    p.Indent()
    p.Print("length: %d" % self.length)
    base_offset = self.ElementsOffset()
    for i in xrange(self.length):
      offset = base_offset + 4 * i
      try:
        p.Print("[%08d] = %s" % (i, self.ObjectField(offset)))
      except TypeError:
        p.Dedent()
        p.Print("...")
        p.Print("}")
        return
    p.Dedent()
    p.Print("}")

  def __str__(self):
    return "FixedArray(%08x, length=%d)" % (self.address, self.length)


class DescriptorArray(object):
  def __init__(self, array):
    self.array = array

  def Length(self):
    return self.array.Get(0)

  def Decode(self, offset, size, value):
    return (value >> offset) & ((1 << size) - 1)

  TYPES = [
      "normal",
      "field",
      "function",
      "callbacks"
  ]

  def Type(self, value):
    return DescriptorArray.TYPES[self.Decode(0, 3, value)]

  def Attributes(self, value):
    attributes = self.Decode(3, 3, value)
    result = []
    if (attributes & 0): result += ["ReadOnly"]
    if (attributes & 1): result += ["DontEnum"]
    if (attributes & 2): result += ["DontDelete"]
    return "[" + (",".join(result)) + "]"

  def Deleted(self, value):
    return self.Decode(6, 1, value) == 1

  def FieldIndex(self, value):
    return self.Decode(20, 11, value)

  def Pointer(self, value):
    return self.Decode(6, 11, value)

  def Details(self, di, value):
    return (
        di,
        self.Type(value),
        self.Attributes(value),
        self.FieldIndex(value),
        self.Pointer(value)
    )


  def Print(self, p):
    length = self.Length()
    array = self.array

    p.Print("Descriptors(%08x, length=%d)" % (array.address, length))
    p.Print("[et] %s" % (array.Get(1)))

    for di in xrange(length):
      i = 2 + di * 3
      p.Print("0x%x" % (array.address + array.MemberOffset(i)))
      p.Print("[%i] name:    %s" % (di, array.Get(i + 0)))
      p.Print("[%i] details: %s %s field-index %i pointer %i" % \
              self.Details(di, array.Get(i + 1)))
      p.Print("[%i] value:   %s" % (di, array.Get(i + 2)))

    end = self.array.length // 3
    if length != end:
      p.Print("[%i-%i] slack descriptors" % (length, end))


class TransitionArray(object):
  def __init__(self, array):
    self.array = array

  def IsSimpleTransition(self):
    return self.array.length <= 2

  def Length(self):
    # SimpleTransition cases
    if self.IsSimpleTransition():
      return self.array.length - 1
    return (self.array.length - 3) // 2

  def Print(self, p):
    length = self.Length()
    array = self.array

    p.Print("Transitions(%08x, length=%d)" % (array.address, length))
    p.Print("[backpointer] %s" % (array.Get(0)))
    if self.IsSimpleTransition():
      if length == 1:
        p.Print("[simple target] %s" % (array.Get(1)))
      return

    elements = array.Get(1)
    if elements is not None:
      p.Print("[elements   ] %s" % (elements))

    prototype = array.Get(2)
    if prototype is not None:
      p.Print("[prototype  ] %s" % (prototype))

    for di in xrange(length):
      i = 3 + di * 2
      p.Print("[%i] symbol: %s" % (di, array.Get(i + 0)))
      p.Print("[%i] target: %s" % (di, array.Get(i + 1)))


class JSFunction(HeapObject):
  def CodeEntryOffset(self):
    return 3 * self.heap.PointerSize()

  def SharedOffset(self):
    return 5 * self.heap.PointerSize()

  def __init__(self, heap, map, address):
    HeapObject.__init__(self, heap, map, address)
    code_entry = \
        heap.reader.ReadU32(self.address + self.CodeEntryOffset())
    self.code = heap.FindObject(code_entry - Code.HeaderSize(heap) + 1)
    self.shared = self.ObjectField(self.SharedOffset())

  def Print(self, p):
    source = "\n".join("  %s" % line for line in self._GetSource().split("\n"))
    p.Print("JSFunction(%s) {" % self.heap.reader.FormatIntPtr(self.address))
    p.Indent()
    p.Print("inferred name: %s" % self.shared.inferred_name)
    if self.shared.script.Is(Script) and self.shared.script.name.Is(String):
      p.Print("script name: %s" % self.shared.script.name)
    p.Print("source:")
    p.PrintLines(self._GetSource().split("\n"))
    p.Print("code:")
    self.code.Print(p)
    if self.code != self.shared.code:
      p.Print("unoptimized code:")
      self.shared.code.Print(p)
    p.Dedent()
    p.Print("}")

  def __str__(self):
    inferred_name = ""
    if self.shared is not None and self.shared.Is(SharedFunctionInfo):
      inferred_name = self.shared.inferred_name
    return "JSFunction(%s, %s) " % \
          (self.heap.reader.FormatIntPtr(self.address), inferred_name)

  def _GetSource(self):
    source = "?source?"
    start = self.shared.start_position
    end = self.shared.end_position
    if not self.shared.script.Is(Script): return source
    script_source = self.shared.script.source
    if not script_source.Is(String): return source
    if start and end:
      source = script_source.GetChars()[start:end]
    return source


class SharedFunctionInfo(HeapObject):
  def CodeOffset(self):
    return 2 * self.heap.PointerSize()

  def ScriptOffset(self):
    return 7 * self.heap.PointerSize()

  def InferredNameOffset(self):
    return 9 * self.heap.PointerSize()

  def EndPositionOffset(self):
    return 12 * self.heap.PointerSize() + 4 * self.heap.IntSize()

  def StartPositionAndTypeOffset(self):
    return 12 * self.heap.PointerSize() + 5 * self.heap.IntSize()

  def __init__(self, heap, map, address):
    HeapObject.__init__(self, heap, map, address)
    try:
      self.code = self.ObjectField(self.CodeOffset())
      self.script = self.ObjectField(self.ScriptOffset())
      self.inferred_name = self.ObjectField(self.InferredNameOffset())
      if heap.PointerSize() == 8:
        start_position_and_type = \
            heap.reader.ReadU32(self.StartPositionAndTypeOffset())
        self.start_position = start_position_and_type >> 2
        pseudo_smi_end_position = \
            heap.reader.ReadU32(self.EndPositionOffset())
        self.end_position = pseudo_smi_end_position >> 2
      else:
        start_position_and_type = \
            self.SmiField(self.StartPositionAndTypeOffset())
        if start_position_and_type:
          self.start_position = start_position_and_type >> 2
        else:
          self.start_position = None
        self.end_position = \
            self.SmiField(self.EndPositionOffset())
    except:
      print("*** Error while reading SharedFunctionInfo")


class Script(HeapObject):
  def SourceOffset(self):
    return self.heap.PointerSize()

  def NameOffset(self):
    return self.SourceOffset() + self.heap.PointerSize()

  def __init__(self, heap, map, address):
    HeapObject.__init__(self, heap, map, address)
    self.source = self.ObjectField(self.SourceOffset())
    self.name = self.ObjectField(self.NameOffset())


class CodeCache(HeapObject):
  def DefaultCacheOffset(self):
    return self.heap.PointerSize()

  def NormalTypeCacheOffset(self):
    return self.DefaultCacheOffset() + self.heap.PointerSize()

  def __init__(self, heap, map, address):
    HeapObject.__init__(self, heap, map, address)
    self.default_cache = self.ObjectField(self.DefaultCacheOffset())
    self.normal_type_cache = self.ObjectField(self.NormalTypeCacheOffset())

  def Print(self, p):
    p.Print("CodeCache(%s) {" % self.heap.reader.FormatIntPtr(self.address))
    p.Indent()
    p.Print("default cache: %s" % self.default_cache)
    p.Print("normal type cache: %s" % self.normal_type_cache)
    p.Dedent()
    p.Print("}")


class Code(HeapObject):
  CODE_ALIGNMENT_MASK = (1 << 5) - 1

  def InstructionSizeOffset(self):
    return self.heap.PointerSize()

  @staticmethod
  def HeaderSize(heap):
    return (heap.PointerSize() + heap.IntSize() + \
        4 * heap.PointerSize() + 3 * heap.IntSize() + \
        Code.CODE_ALIGNMENT_MASK) & ~Code.CODE_ALIGNMENT_MASK

  def __init__(self, heap, map, address):
    HeapObject.__init__(self, heap, map, address)
    self.entry = self.address + Code.HeaderSize(heap)
    self.instruction_size = \
        heap.reader.ReadU32(self.address + self.InstructionSizeOffset())

  def Print(self, p):
    lines = self.heap.reader.GetDisasmLines(self.entry, self.instruction_size)
    p.Print("Code(%s) {" % self.heap.reader.FormatIntPtr(self.address))
    p.Indent()
    p.Print("instruction_size: %d" % self.instruction_size)
    p.PrintLines(self._FormatLine(line) for line in lines)
    p.Dedent()
    p.Print("}")

  def _FormatLine(self, line):
    return FormatDisasmLine(self.entry, self.heap, line)


class V8Heap(object):
  CLASS_MAP = {
    "SYMBOL_TYPE": SeqString,
    "ONE_BYTE_SYMBOL_TYPE": SeqString,
    "CONS_SYMBOL_TYPE": ConsString,
    "CONS_ONE_BYTE_SYMBOL_TYPE": ConsString,
    "EXTERNAL_SYMBOL_TYPE": ExternalString,
    "EXTERNAL_SYMBOL_WITH_ONE_BYTE_DATA_TYPE": ExternalString,
    "EXTERNAL_ONE_BYTE_SYMBOL_TYPE": ExternalString,
    "UNCACHED_EXTERNAL_SYMBOL_TYPE": ExternalString,
    "UNCACHED_EXTERNAL_SYMBOL_WITH_ONE_BYTE_DATA_TYPE": ExternalString,
    "UNCACHED_EXTERNAL_ONE_BYTE_SYMBOL_TYPE": ExternalString,
    "STRING_TYPE": SeqString,
    "ONE_BYTE_STRING_TYPE": SeqString,
    "CONS_STRING_TYPE": ConsString,
    "CONS_ONE_BYTE_STRING_TYPE": ConsString,
    "EXTERNAL_STRING_TYPE": ExternalString,
    "EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE": ExternalString,
    "EXTERNAL_ONE_BYTE_STRING_TYPE": ExternalString,
    "MAP_TYPE": Map,
    "ODDBALL_TYPE": Oddball,
    "FIXED_ARRAY_TYPE": FixedArray,
    "HASH_TABLE_TYPE": FixedArray,
    "OBJECT_BOILERPLATE_DESCRIPTION_TYPE": FixedArray,
    "SCOPE_INFO_TYPE": FixedArray,
    "JS_FUNCTION_TYPE": JSFunction,
    "SHARED_FUNCTION_INFO_TYPE": SharedFunctionInfo,
    "SCRIPT_TYPE": Script,
    "CODE_CACHE_TYPE": CodeCache,
    "CODE_TYPE": Code,
  }

  def __init__(self, reader, stack_map):
    self.reader = reader
    self.stack_map = stack_map
    self.objects = {}

  def FindObjectOrSmi(self, tagged_address):
    if self.IsSmi(tagged_address): return self.SmiUntag(tagged_address)
    return self.FindObject(tagged_address)

  def FindObject(self, tagged_address):
    if tagged_address in self.objects:
      return self.objects[tagged_address]
    if not self.IsTaggedObjectAddress(tagged_address): return None
    address = tagged_address - 1
    if not self.reader.IsValidAddress(address): return None
    map_tagged_address = self.reader.ReadUIntPtr(address)
    if tagged_address == map_tagged_address:
      # Meta map?
      meta_map = Map(self, None, address)
      instance_type_name = INSTANCE_TYPES.get(meta_map.instance_type)
      if instance_type_name != "MAP_TYPE": return None
      meta_map.map = meta_map
      object = meta_map
    else:
      map = self.FindMap(map_tagged_address)
      if map is None: return None
      instance_type_name = INSTANCE_TYPES.get(map.instance_type)
      if instance_type_name is None: return None
      cls = V8Heap.CLASS_MAP.get(instance_type_name, HeapObject)
      object = cls(self, map, address)
    self.objects[tagged_address] = object
    return object

  def FindMap(self, tagged_address):
    address = self.FindMapAddress(tagged_address)
    if not address: return None
    object = Map(self, None, address)
    return object

  def FindMapAddress(self, tagged_address):
    if not self.IsTaggedMapAddress(tagged_address): return None
    address = tagged_address - 1
    if not self.reader.IsValidAddress(address): return None
    return address

  def IntSize(self):
    return 4

  def PointerSize(self):
    return self.reader.PointerSize()

  def ObjectAlignmentMask(self):
    return self.PointerSize() - 1

  def IsTaggedObjectAddress(self, address):
    return (address & self.ObjectAlignmentMask()) == 1

  def IsValidTaggedObjectAddress(self, address):
    if not self.IsTaggedObjectAddress(address): return False
    return self.reader.IsValidAddress(address)

  def IsTaggedMapAddress(self, address):
    return (address & self.MapAlignmentMask()) == 1

  def MapAlignmentMask(self):
    if self.reader.arch == MD_CPU_ARCHITECTURE_AMD64:
      return (1 << 4) - 1
    elif self.reader.arch == MD_CPU_ARCHITECTURE_ARM:
      return (1 << 4) - 1
    elif self.reader.arch == MD_CPU_ARCHITECTURE_ARM64:
      return (1 << 4) - 1
    elif self.reader.arch == MD_CPU_ARCHITECTURE_X86:
      return (1 << 5) - 1

  def PageAlignmentMask(self):
    return (1 << 19) - 1

  def IsTaggedAddress(self, address):
    return (address & self.ObjectAlignmentMask()) == 1

  def IsSmi(self, tagged_address):
    if self.reader.Is64():
      return (tagged_address & 0xFFFFFFFF) == 0
    return not self.IsTaggedAddress(tagged_address)

  def SmiUntag(self, tagged_address):
    if self.reader.Is64(): return tagged_address >> 32
    return tagged_address >> 1

  def AddressTypeMarker(self, address):
    if not self.reader.IsValidAddress(address): return " "
    if self.reader.IsExceptionStackAddress(address): return "S"
    if self.reader.IsModuleAddress(address): return "C"
    if self.IsTaggedAddress(address):
      # Cannot have an tagged pointer into the stack
      if self.reader.IsAnyExceptionStackAddress(address): return "s"
      return "T"
    return "*"

  def FormatIntPtr(self, address):
    marker = self.AddressTypeMarker(address)
    address = self.reader.FormatIntPtr(address)
    if marker == " ": return address
    return "%s %s" % (address, marker)

  def RelativeOffset(self, slot, address):
    if not self.reader.IsValidAlignedAddress(slot): return None
    if self.IsTaggedObjectAddress(address):
      address -= 1
    if not self.reader.IsValidAlignedAddress(address): return None
    offset = (address - slot) / self.PointerSize()

    lower_limit = -32
    upper_limit = 128
    if self.reader.IsExceptionStackAddress(address):
      upper_limit = 0xFFFFFF

    if offset < lower_limit or upper_limit < offset: return None
    target_address = self.reader.ReadUIntPtr(address)
    return "[%+02d]=%s %s" % (offset, self.reader.FormatIntPtr(target_address),
                             self.AddressTypeMarker(target_address))

  def FindObjectPointers(self, start=0, end=0):
    objects = set()
    def find_object_in_region(reader, start, size, location):
      for slot in range(start, start+size, self.reader.PointerSize()):
        if not self.reader.IsValidAddress(slot): break
        # Collect only tagged pointers (object) to tagged pointers (map)
        tagged_address = self.reader.ReadUIntPtr(slot)
        if not self.IsValidTaggedObjectAddress(tagged_address): continue
        map_address = self.reader.ReadUIntPtr(tagged_address - 1)
        if not self.IsTaggedMapAddress(map_address): continue
        objects.add(tagged_address)

    if not start and not end:
      self.reader.ForEachMemoryRegion(find_object_in_region)
    else:
      find_object_in_region(self.reader, start, end-start, None)

    return objects

class KnownObject(HeapObject):
  def __init__(self, heap, known_name):
    HeapObject.__init__(self, heap, None, None)
    self.known_name = known_name

  def __str__(self):
    return "<%s>" % self.known_name


class KnownMap(HeapObject):
  def __init__(self, heap, known_name, instance_type):
    HeapObject.__init__(self, heap, None, None)
    self.instance_type = instance_type
    self.known_name = known_name

  def __str__(self):
    return "<%s>" % self.known_name


COMMENT_RE = re.compile(r"^C (0x[0-9a-fA-F]+) (.*)$")
PAGEADDRESS_RE = re.compile(
    r"^P (mappage|oldpage) (0x[0-9a-fA-F]+)$")


class InspectionInfo(object):
  def __init__(self, minidump_name, reader):
    self.comment_file = minidump_name + ".comments"
    self.address_comments = {}
    self.page_address = {}
    if os.path.exists(self.comment_file):
      with open(self.comment_file, "r") as f:
        lines = f.readlines()
        f.close()

        for l in lines:
          m = COMMENT_RE.match(l)
          if m:
            self.address_comments[int(m.group(1), 0)] = m.group(2)
          m = PAGEADDRESS_RE.match(l)
          if m:
            self.page_address[m.group(1)] = int(m.group(2), 0)
    self.reader = reader
    self.styles = {}
    self.color_addresses()
    return

  def get_page_address(self, page_kind):
    return self.page_address.get(page_kind, 0)

  def save_page_address(self, page_kind, address):
    with open(self.comment_file, "a") as f:
      f.write("P %s 0x%x\n" % (page_kind, address))
      f.close()

  def color_addresses(self):
    # Color all stack addresses.
    exception_thread = self.reader.thread_map[self.reader.exception.thread_id]
    stack_top = self.reader.ExceptionSP()
    stack_bottom = exception_thread.stack.start + \
        exception_thread.stack.memory.data_size
    frame_pointer = self.reader.ExceptionFP()
    self.styles[frame_pointer] = "frame"
    for slot in xrange(stack_top, stack_bottom, self.reader.PointerSize()):
      # stack address
      self.styles[slot] = "sa"
    for slot in xrange(stack_top, stack_bottom, self.reader.PointerSize()):
      maybe_address = self.reader.ReadUIntPtr(slot)
      # stack value
      self.styles[maybe_address] = "sv"
      if slot == frame_pointer:
        self.styles[slot] = "frame"
        frame_pointer = maybe_address
    self.styles[self.reader.ExceptionIP()] = "pc"

  def get_style_class(self, address):
    return self.styles.get(address, None)

  def get_style_class_string(self, address):
    style = self.get_style_class(address)
    if style != None:
      return " class=%s " % style
    else:
      return ""

  def set_comment(self, address, comment):
    self.address_comments[address] = comment
    with open(self.comment_file, "a") as f:
      f.write("C 0x%x %s\n" % (address, comment))
      f.close()

  def get_comment(self, address):
    return self.address_comments.get(address, "")


class InspectionPadawan(object):
  """The padawan can improve annotations by sensing well-known objects."""
  def __init__(self, reader, heap):
    self.reader = reader
    self.heap = heap
    self.known_first_map_page = 0
    self.known_first_old_page = 0
    self.context = None

  def __getattr__(self, name):
    """An InspectionPadawan can be used instead of V8Heap, even though
       it does not inherit from V8Heap (aka. mixin)."""
    return getattr(self.heap, name)

  def GetPageOffset(self, tagged_address):
    return tagged_address & self.heap.PageAlignmentMask()

  def IsInKnownMapSpace(self, tagged_address):
    page_address = tagged_address & ~self.heap.PageAlignmentMask()
    return page_address == self.known_first_map_page

  def IsInKnownOldSpace(self, tagged_address):
    page_address = tagged_address & ~self.heap.PageAlignmentMask()
    return page_address == self.known_first_old_page

  def ContainingKnownOldSpaceName(self, tagged_address):
    page_address = tagged_address & ~self.heap.PageAlignmentMask()
    if page_address == self.known_first_old_page: return "OLD_SPACE"
    return None

  def FrameMarkerName(self, value):
    # The frame marker is Smi-tagged but not Smi encoded and 0 is not a valid
    # frame type.
    value = (value >> 1) - 1
    if 0 <= value < len(FRAME_MARKERS):
      return "Possibly %s frame marker" % FRAME_MARKERS[value]
    return None

  def IsFrameMarker(self, slot, address):
    if not slot: return False
    # Frame markers only occur directly after a frame pointer and only on the
    # stack.
    if not self.reader.IsExceptionStackAddress(slot): return False
    next_slot = slot + self.reader.PointerSize()
    if not self.reader.IsValidAddress(next_slot): return False
    next_address = self.reader.ReadUIntPtr(next_slot)
    return self.reader.IsExceptionStackAddress(next_address)

  def FormatSmi(self, address):
    value = self.heap.SmiUntag(address)
    # On 32-bit systems almost everything looks like a Smi.
    if not self.reader.Is64() or value == 0: return None
    return "Smi(%d)" % value

  def SenseObject(self, address, slot=None):
    if self.IsFrameMarker(slot, address):
      return self.FrameMarkerName(address)
    if self.heap.IsSmi(address):
      return self.FormatSmi(address)
    if not self.heap.IsTaggedAddress(address): return None
    tagged_address = address
    if self.IsInKnownOldSpace(tagged_address):
      offset = self.GetPageOffset(tagged_address)
      lookup_key = (self.ContainingKnownOldSpaceName(tagged_address), offset)
      known_obj_name = KNOWN_OBJECTS.get(lookup_key)
      if known_obj_name:
        return KnownObject(self, known_obj_name)
    if self.IsInKnownMapSpace(tagged_address):
      known_map = self.SenseMap(tagged_address)
      if known_map:
        return known_map
    found_obj = self.heap.FindObject(tagged_address)
    if found_obj: return found_obj
    address = tagged_address - 1
    if self.reader.IsValidAddress(address):
      map_tagged_address = self.reader.ReadUIntPtr(address)
      map = self.SenseMap(map_tagged_address)
      if map is None: return None
      instance_type_name = INSTANCE_TYPES.get(map.instance_type)
      if instance_type_name is None: return None
      cls = V8Heap.CLASS_MAP.get(instance_type_name, HeapObject)
      return cls(self, map, address)
    return None

  def SenseMap(self, tagged_address):
    if self.IsInKnownMapSpace(tagged_address):
      offset = self.GetPageOffset(tagged_address)
      lookup_key = ("MAP_SPACE", offset)
      known_map_info = KNOWN_MAPS.get(lookup_key)
      if known_map_info:
        known_map_type, known_map_name = known_map_info
        return KnownMap(self, known_map_name, known_map_type)
    found_map = self.heap.FindMap(tagged_address)
    if found_map: return found_map
    return None

  def FindObjectOrSmi(self, tagged_address):
    """When used as a mixin in place of V8Heap."""
    found_obj = self.SenseObject(tagged_address)
    if found_obj: return found_obj
    if self.IsSmi(tagged_address):
      return self.FormatSmi(tagged_address)
    else:
      return "Unknown(%s)" % self.reader.FormatIntPtr(tagged_address)

  def FindObject(self, tagged_address):
    """When used as a mixin in place of V8Heap."""
    raise NotImplementedError

  def FindMap(self, tagged_address):
    """When used as a mixin in place of V8Heap."""
    raise NotImplementedError

  def PrintKnowledge(self):
    print "  known_first_map_page = %s\n"\
          "  known_first_old_page = %s" % (
          self.reader.FormatIntPtr(self.known_first_map_page),
          self.reader.FormatIntPtr(self.known_first_old_page))

  def FindFirstAsciiString(self, start, end=None, min_length=32):
    """ Walk the memory until we find a large string """
    if not end: end = start + 64
    for slot in xrange(start, end):
      if not self.reader.IsValidAddress(slot): break
      message = self.reader.ReadAsciiString(slot)
      if len(message) > min_length:
        return (slot, message)
    return (None,None)

  def PrintStackTraceMessage(self, start=None, print_message=True):
    """
    Try to print a possible message from PushStackTraceAndDie.
    Returns the first address where the normal stack starts again.
    """
    # Only look at the first 1k words on the stack
    ptr_size = self.reader.PointerSize()
    if start is None: start = self.reader.ExceptionSP()
    if not self.reader.IsValidAddress(start): return start
    end = start + ptr_size * 1024 * 4
    magic1 = None
    for slot in xrange(start, end, ptr_size):
      if not self.reader.IsValidAddress(slot + ptr_size): break
      magic1 = self.reader.ReadUIntPtr(slot)
      magic2 = self.reader.ReadUIntPtr(slot + ptr_size)
      pair = (magic1 & 0xFFFFFFFF, magic2 & 0xFFFFFFFF)
      if pair in MAGIC_MARKER_PAIRS:
        return self.TryExtractOldStyleStackTrace(slot, start, end,
                                                 print_message)
      if pair[0] == STACK_TRACE_MARKER:
        return self.TryExtractStackTrace(slot, start, end, print_message)
      elif pair[0] == ERROR_MESSAGE_MARKER:
        return self.TryExtractErrorMessage(slot, start, end, print_message)
    # Simple fallback in case not stack trace object was found
    return self.TryExtractOldStyleStackTrace(0, start, end,
                                             print_message)

  def TryExtractStackTrace(self, slot, start, end, print_message):
    ptr_size = self.reader.PointerSize()
    assert self.reader.ReadUIntPtr(slot) & 0xFFFFFFFF == STACK_TRACE_MARKER
    end_marker = STACK_TRACE_MARKER + 1;
    header_size = 10
    # Look for the end marker after the fields and the message buffer.
    end_search = start + (32 * 1024) + (header_size * ptr_size);
    end_slot = self.FindPtr(end_marker, end_search, end_search + ptr_size * 512)
    if not end_slot: return start
    print "Stack Message (start=%s):" % self.heap.FormatIntPtr(slot)
    slot += ptr_size
    for name in ("isolate","ptr1", "ptr2", "ptr3", "ptr4", "codeObject1",
                 "codeObject2", "codeObject3", "codeObject4"):
      value = self.reader.ReadUIntPtr(slot)
      print " %s: %s" % (name.rjust(14), self.heap.FormatIntPtr(value))
      slot += ptr_size
    print "  message start: %s" % self.heap.FormatIntPtr(slot)
    stack_start = end_slot + ptr_size
    print "  stack_start:   %s" % self.heap.FormatIntPtr(stack_start)
    (message_start, message) = self.FindFirstAsciiString(slot)
    self.FormatStackTrace(message, print_message)
    return stack_start

  def FindPtr(self, expected_value, start, end):
    ptr_size = self.reader.PointerSize()
    for slot in xrange(start, end, ptr_size):
      if not self.reader.IsValidAddress(slot): return None
      value = self.reader.ReadUIntPtr(slot)
      if value == expected_value: return slot
    return None

  def TryExtractErrorMessage(self, slot, start, end, print_message):
    ptr_size = self.reader.PointerSize()
    end_marker = ERROR_MESSAGE_MARKER + 1;
    header_size = 1
    end_search = start + 1024 + (header_size * ptr_size);
    end_slot = self.FindPtr(end_marker, end_search, end_search + ptr_size * 512)
    if not end_slot: return start
    print "Error Message (start=%s):" % self.heap.FormatIntPtr(slot)
    slot += ptr_size
    (message_start, message) = self.FindFirstAsciiString(slot)
    self.FormatStackTrace(message, print_message)
    stack_start = end_slot + ptr_size
    return stack_start

  def TryExtractOldStyleStackTrace(self, message_slot, start, end,
                                   print_message):
    ptr_size = self.reader.PointerSize()
    if message_slot == 0:
      """
      On Mac we don't always get proper magic markers, so just try printing
      the first long ascii string found on the stack.
      """
      magic1 = None
      magic2 = None
      message_start, message = self.FindFirstAsciiString(start, end, 128)
      if message_start is None: return start
    else:
      message_start = self.reader.ReadUIntPtr(message_slot + ptr_size * 4)
      message = self.reader.ReadAsciiString(message_start)
    stack_start = message_start + len(message) + 1
    # Make sure the address is word aligned
    stack_start =  stack_start - (stack_start % ptr_size)
    if magic1 is None:
      print "Stack Message:"
      print "  message start: %s" % self.heap.FormatIntPtr(message_start)
      print "  stack_start:   %s" % self.heap.FormatIntPtr(stack_start )
    else:
      ptr1 = self.reader.ReadUIntPtr(slot + ptr_size * 2)
      ptr2 = self.reader.ReadUIntPtr(slot + ptr_size * 3)
      print "Stack Message:"
      print "  magic1:        %s" % self.heap.FormatIntPtr(magic1)
      print "  magic2:        %s" % self.heap.FormatIntPtr(magic2)
      print "  ptr1:          %s" % self.heap.FormatIntPtr(ptr1)
      print "  ptr2:          %s" % self.heap.FormatIntPtr(ptr2)
      print "  message start: %s" % self.heap.FormatIntPtr(message_start)
      print "  stack_start:   %s" % self.heap.FormatIntPtr(stack_start )
      print ""
    self.FormatStackTrace(message, print_message)
    return stack_start

  def FormatStackTrace(self, message, print_message):
    if not print_message:
      print "  Use `dsa` to print the message with annotated addresses."
      print ""
      return
    ptr_size = self.reader.PointerSize()
    # Annotate all addresses in the dumped message
    prog = re.compile("[0-9a-fA-F]{%s}" % ptr_size*2)
    addresses = list(set(prog.findall(message)))
    for i in range(len(addresses)):
      address_org = addresses[i]
      address = self.heap.FormatIntPtr(int(address_org, 16))
      if address_org != address:
        message = message.replace(address_org, address)
    print "Message:"
    print "="*80
    print message
    print "="*80
    print ""


  def TryInferFramePointer(self, slot, address):
    """ Assume we have a framepointer if we find 4 consecutive links """
    for i in range(0, 4):
      if not self.reader.IsExceptionStackAddress(address): return 0
      next_address = self.reader.ReadUIntPtr(address)
      if next_address == address: return 0
      address = next_address
    return slot

  def TryInferContext(self, address):
    if self.context: return
    ptr_size = self.reader.PointerSize()
    possible_context = dict()
    count = 0
    while self.reader.IsExceptionStackAddress(address):
      prev_addr = self.reader.ReadUIntPtr(address-ptr_size)
      if self.heap.IsTaggedObjectAddress(prev_addr):
        if prev_addr in possible_context:
          possible_context[prev_addr] += 1
        else:
          possible_context[prev_addr] = 1
      address = self.reader.ReadUIntPtr(address)
      count += 1
    if count <= 5 or len(possible_context) == 0: return
    # Find entry with highest count
    possible_context = possible_context.items()
    possible_context.sort(key=lambda pair: pair[1])
    address,count = possible_context[-1]
    if count <= 4: return
    self.context = address

  def InterpretMemory(self, start, end):
    # On 64 bit we omit frame pointers, so we have to do some more guesswork.
    frame_pointer = 0
    if not self.reader.Is64():
      frame_pointer = self.reader.ExceptionFP()
      # Follow the framepointer into the address range
      while frame_pointer and frame_pointer < start:
        frame_pointer = self.reader.ReadUIntPtr(frame_pointer)
        if not self.reader.IsExceptionStackAddress(frame_pointer) or \
            not frame_pointer:
          frame_pointer = 0
          break
    in_oom_dump_area  = False
    is_stack = self.reader.IsExceptionStackAddress(start)
    free_space_end = 0
    ptr_size = self.reader.PointerSize()

    for slot in xrange(start, end, ptr_size):
      if not self.reader.IsValidAddress(slot):
        print "%s: Address is not contained within the minidump!" % slot
        return
      maybe_address = self.reader.ReadUIntPtr(slot)
      address_info = []
      # Mark continuous free space objects
      if slot == free_space_end:
        address_info.append("+")
      elif slot <= free_space_end:
        address_info.append("|")
      else:
        free_space_end = 0

      heap_object = self.SenseObject(maybe_address, slot)
      if heap_object:
        # Detect Free-space ranges
        if isinstance(heap_object, KnownMap) and \
            heap_object.known_name == "FreeSpaceMap":
          # The free-space length is is stored as a Smi in the next slot.
          length = self.reader.ReadUIntPtr(slot + ptr_size)
          if self.heap.IsSmi(length):
            length = self.heap.SmiUntag(length)
            free_space_end = slot + length - ptr_size
        address_info.append(str(heap_object))
      relative_offset = self.heap.RelativeOffset(slot, maybe_address)
      if relative_offset:
        address_info.append(relative_offset)
      if maybe_address == self.context:
        address_info.append("CONTEXT")

      maybe_address_contents = None
      if is_stack:
        if self.reader.IsExceptionStackAddress(maybe_address):
          maybe_address_contents = \
              self.reader.ReadUIntPtr(maybe_address) & 0xFFFFFFFF
          if maybe_address_contents == 0xdecade00:
            in_oom_dump_area = True
          if frame_pointer == 0:
            frame_pointer = self.TryInferFramePointer(slot, maybe_address)
            if frame_pointer != 0:
              self.TryInferContext(slot)
        maybe_symbol = self.reader.FindSymbol(maybe_address)
        if in_oom_dump_area:
          if maybe_address_contents == 0xdecade00:
            address_info = ["<==== HeapStats start marker"]
          elif maybe_address_contents == 0xdecade01:
            address_info = ["<==== HeapStats end marker"]
          elif maybe_address_contents is not None:
            address_info = [" %d (%d Mbytes)" % (maybe_address_contents,
                                                 maybe_address_contents >> 20)]
        if slot == frame_pointer:
          if not self.reader.IsExceptionStackAddress(maybe_address):
            address_info.append("<==== BAD frame pointer")
            frame_pointer = 0
          else:
            address_info.append("<==== Frame pointer")
          frame_pointer = maybe_address
      address_type_marker = self.heap.AddressTypeMarker(maybe_address)
      string_value = self.reader.ReadAsciiPtr(slot)
      print "%s: %s %s %s %s" % (self.reader.FormatIntPtr(slot),
                           self.reader.FormatIntPtr(maybe_address),
                           address_type_marker,
                           string_value,
                           ' | '.join(address_info))
      if maybe_address_contents == 0xdecade01:
        in_oom_dump_area = False
      heap_object = self.heap.FindObject(maybe_address)
      if heap_object:
        heap_object.Print(Printer())
        print ""

WEB_HEADER = """
<!DOCTYPE html>
<html>
<head>
<meta content="text/html; charset=utf-8" http-equiv="content-type">
<style media="screen" type="text/css">

.code {
  font-family: monospace;
}

.dmptable {
  border-collapse : collapse;
  border-spacing : 0px;
  table-layout: fixed;
}

.codedump {
  border-collapse : collapse;
  border-spacing : 0px;
  table-layout: fixed;
}

.addrcomments {
  border : 0px;
}

.register {
  padding-right : 1em;
}

.header {
  clear : both;
}

.header .navigation {
  float : left;
}

.header .dumpname {
  float : right;
}

tr.highlight-line {
  background-color : yellow;
}

.highlight {
  background-color : magenta;
}

tr.inexact-highlight-line {
  background-color : pink;
}

input {
  background-color: inherit;
  border: 1px solid LightGray;
}

.dumpcomments {
  border : 1px solid LightGray;
  width : 32em;
}

.regions td {
  padding:0 15px 0 15px;
}

.stackframe td {
  background-color : cyan;
}

.stackaddress, .sa {
  background-color : LightGray;
}

.stackval, .sv {
  background-color : LightCyan;
}

.frame {
  background-color : cyan;
}

.commentinput, .ci {
  width : 20em;
}

/* a.nodump */
a.nd:visited {
  color : black;
  text-decoration : none;
}

a.nd:link {
  color : black;
  text-decoration : none;
}

a:visited {
  color : blueviolet;
}

a:link {
  color : blue;
}

.disasmcomment {
  color : DarkGreen;
}

</style>

<script type="application/javascript">

var address_str = "address-";
var address_len = address_str.length;

function comment() {
  var s = event.srcElement.id;
  var index = s.indexOf(address_str);
  if (index >= 0) {
    send_comment(s.substring(index + address_len), event.srcElement.value);
  }
}
var c = comment;

function send_comment(address, comment) {
  xmlhttp = new XMLHttpRequest();
  address = encodeURIComponent(address)
  comment = encodeURIComponent(comment)
  xmlhttp.open("GET",
      "setcomment?%(query_dump)s&address=" + address +
      "&comment=" + comment, true);
  xmlhttp.send();
}

var dump_str = "dump-";
var dump_len = dump_str.length;

function dump_comment() {
  var s = event.srcElement.id;
  var index = s.indexOf(dump_str);
  if (index >= 0) {
    send_dump_desc(s.substring(index + dump_len), event.srcElement.value);
  }
}

function send_dump_desc(name, desc) {
  xmlhttp = new XMLHttpRequest();
  name = encodeURIComponent(name)
  desc = encodeURIComponent(desc)
  xmlhttp.open("GET",
      "setdumpdesc?dump=" + name +
      "&description=" + desc, true);
  xmlhttp.send();
}

function onpage(kind, address) {
  xmlhttp = new XMLHttpRequest();
  kind = encodeURIComponent(kind)
  address = encodeURIComponent(address)
  xmlhttp.onreadystatechange = function() {
    if (xmlhttp.readyState==4 && xmlhttp.status==200) {
      location.reload(true)
    }
  };
  xmlhttp.open("GET",
      "setpageaddress?%(query_dump)s&kind=" + kind +
      "&address=" + address);
  xmlhttp.send();
}

</script>

<title>Dump %(dump_name)s</title>
</head>

<body>
  <div class="header">
    <form class="navigation" action="search.html">
      <a href="summary.html?%(query_dump)s">Context info</a>&nbsp;&nbsp;&nbsp;
      <a href="info.html?%(query_dump)s">Dump info</a>&nbsp;&nbsp;&nbsp;
      <a href="modules.html?%(query_dump)s">Modules</a>&nbsp;&nbsp;&nbsp;
      &nbsp;
      <input type="search" name="val">
      <input type="submit" name="search" value="Search">
      <input type="hidden" name="dump" value="%(dump_name)s">
    </form>
    <form class="navigation" action="disasm.html#highlight">
      &nbsp;
      &nbsp;
      &nbsp;
      <input type="search" name="val">
      <input type="submit" name="disasm" value="Disasm">
      &nbsp;
      &nbsp;
      &nbsp;
      <a href="dumps.html">Dumps...</a>
    </form>
  </div>
  <br>
  <hr>
"""


WEB_FOOTER = """
</body>
</html>
"""


class WebParameterError(Exception):
  def __init__(self, message):
    Exception.__init__(self, message)


class InspectionWebHandler(BaseHTTPServer.BaseHTTPRequestHandler):
  def formatter(self, query_components):
    name = query_components.get("dump", [None])[0]
    return self.server.get_dump_formatter(name)

  def send_success_html_headers(self):
    self.send_response(200)
    self.send_header("Cache-Control", "no-cache, no-store, must-revalidate")
    self.send_header("Pragma", "no-cache")
    self.send_header("Expires", "0")
    self.send_header('Content-type','text/html')
    self.end_headers()
    return

  def do_GET(self):
    try:
      parsedurl = urlparse.urlparse(self.path)
      query_components = urlparse.parse_qs(parsedurl.query)
      if parsedurl.path == "/dumps.html":
        self.send_success_html_headers()
        out_buffer = StringIO.StringIO()
        self.server.output_dumps(out_buffer)
        self.wfile.write(out_buffer.getvalue())
      elif parsedurl.path == "/summary.html":
        self.send_success_html_headers()
        out_buffer = StringIO.StringIO()
        self.formatter(query_components).output_summary(out_buffer)
        self.wfile.write(out_buffer.getvalue())
      elif parsedurl.path == "/info.html":
        self.send_success_html_headers()
        out_buffer = StringIO.StringIO()
        self.formatter(query_components).output_info(out_buffer)
        self.wfile.write(out_buffer.getvalue())
      elif parsedurl.path == "/modules.html":
        self.send_success_html_headers()
        out_buffer = StringIO.StringIO()
        self.formatter(query_components).output_modules(out_buffer)
        self.wfile.write(out_buffer.getvalue())
      elif parsedurl.path == "/search.html" or parsedurl.path == "/s":
        address = query_components.get("val", [])
        if len(address) != 1:
          self.send_error(404, "Invalid params")
          return
        self.send_success_html_headers()
        out_buffer = StringIO.StringIO()
        self.formatter(query_components).output_search_res(
            out_buffer, address[0])
        self.wfile.write(out_buffer.getvalue())
      elif parsedurl.path == "/disasm.html":
        address = query_components.get("val", [])
        exact = query_components.get("exact", ["on"])
        if len(address) != 1:
          self.send_error(404, "Invalid params")
          return
        self.send_success_html_headers()
        out_buffer = StringIO.StringIO()
        self.formatter(query_components).output_disasm(
            out_buffer, address[0], exact[0])
        self.wfile.write(out_buffer.getvalue())
      elif parsedurl.path == "/data.html":
        address = query_components.get("val", [])
        datakind = query_components.get("type", ["address"])
        if len(address) == 1 and len(datakind) == 1:
          self.send_success_html_headers()
          out_buffer = StringIO.StringIO()
          self.formatter(query_components).output_data(
              out_buffer, address[0], datakind[0])
          self.wfile.write(out_buffer.getvalue())
        else:
          self.send_error(404,'Invalid params')
      elif parsedurl.path == "/setdumpdesc":
        name = query_components.get("dump", [""])
        description = query_components.get("description", [""])
        if len(name) == 1 and len(description) == 1:
          name = name[0]
          description = description[0]
          if self.server.set_dump_desc(name, description):
            self.send_success_html_headers()
            self.wfile.write("OK")
            return
        self.send_error(404,'Invalid params')
      elif parsedurl.path == "/setcomment":
        address = query_components.get("address", [])
        comment = query_components.get("comment", [""])
        if len(address) == 1 and len(comment) == 1:
          address = address[0]
          comment = comment[0]
          self.formatter(query_components).set_comment(address, comment)
          self.send_success_html_headers()
          self.wfile.write("OK")
        else:
          self.send_error(404,'Invalid params')
      elif parsedurl.path == "/setpageaddress":
        kind = query_components.get("kind", [])
        address = query_components.get("address", [""])
        if len(kind) == 1 and len(address) == 1:
          kind = kind[0]
          address = address[0]
          self.formatter(query_components).set_page_address(kind, address)
          self.send_success_html_headers()
          self.wfile.write("OK")
        else:
          self.send_error(404,'Invalid params')
      else:
        self.send_error(404,'File Not Found: %s' % self.path)

    except IOError:
      self.send_error(404,'File Not Found: %s' % self.path)

    except WebParameterError as e:
      self.send_error(404, 'Web parameter error: %s' % e.message)


HTML_REG_FORMAT = "<span class=\"register\"><b>%s</b>:&nbsp;%s</span><br/>\n"


class InspectionWebFormatter(object):
  CONTEXT_FULL = 0
  CONTEXT_SHORT = 1

  def __init__(self, switches, minidump_name, http_server):
    self.dumpfilename = os.path.split(minidump_name)[1]
    self.encfilename = urllib.urlencode({ 'dump' : self.dumpfilename })
    self.reader = MinidumpReader(switches, minidump_name)
    self.server = http_server

    # Set up the heap
    exception_thread = self.reader.thread_map[self.reader.exception.thread_id]
    stack_top = self.reader.ExceptionSP()
    stack_bottom = exception_thread.stack.start + \
        exception_thread.stack.memory.data_size
    stack_map = {self.reader.ExceptionIP(): -1}
    for slot in xrange(stack_top, stack_bottom, self.reader.PointerSize()):
      maybe_address = self.reader.ReadUIntPtr(slot)
      if not maybe_address in stack_map:
        stack_map[maybe_address] = slot
    self.heap = V8Heap(self.reader, stack_map)

    self.padawan = InspectionPadawan(self.reader, self.heap)
    self.comments = InspectionInfo(minidump_name, self.reader)
    self.padawan.known_first_old_page = (
        self.comments.get_page_address("oldpage"))
    self.padawan.known_first_map_page = (
        self.comments.get_page_address("mappage"))

  def set_comment(self, straddress, comment):
    try:
      address = int(straddress, 0)
      self.comments.set_comment(address, comment)
    except ValueError:
      print "Invalid address"

  def set_page_address(self, kind, straddress):
    try:
      address = int(straddress, 0)
      if kind == "oldpage":
        self.padawan.known_first_old_page = address
      elif kind == "mappage":
        self.padawan.known_first_map_page = address
      self.comments.save_page_address(kind, address)
    except ValueError:
      print "Invalid address"

  def td_from_address(self, f, address):
    f.write("<td %s>" % self.comments.get_style_class_string(address))

  def format_address(self, maybeaddress, straddress = None):
    if maybeaddress is None:
      return "not in dump"
    else:
      if straddress is None:
        straddress = "0x" + self.reader.FormatIntPtr(maybeaddress)
      style_class = ""
      if not self.reader.IsValidAddress(maybeaddress):
        style_class = "class=nd"
      return ("<a %s href=s?%s&amp;val=%s>%s</a>" %
              (style_class, self.encfilename, straddress, straddress))

  def output_header(self, f):
    f.write(WEB_HEADER %
        { "query_dump" : self.encfilename,
          "dump_name"  : cgi.escape(self.dumpfilename) })

  def output_footer(self, f):
    f.write(WEB_FOOTER)

  MAX_CONTEXT_STACK = 2048

  def output_summary(self, f):
    self.output_header(f)
    f.write('<div class="code">')
    self.output_context(f, InspectionWebFormatter.CONTEXT_SHORT)
    self.output_disasm_pc(f)

    # Output stack
    exception_thread = self.reader.thread_map[self.reader.exception.thread_id]
    stack_top = self.reader.ExceptionSP()
    stack_bottom = min(exception_thread.stack.start + \
        exception_thread.stack.memory.data_size,
        stack_top + self.MAX_CONTEXT_STACK)
    self.output_words(f, stack_top - 16, stack_bottom, stack_top, "Stack")

    f.write('</div>')
    self.output_footer(f)
    return

  def output_info(self, f):
    self.output_header(f)
    f.write("<h3>Dump info</h3>")
    f.write("Description: ")
    self.server.output_dump_desc_field(f, self.dumpfilename)
    f.write("<br>")
    f.write("Filename: ")
    f.write("<span class=\"code\">%s</span><br>" % (self.dumpfilename))
    dt = datetime.datetime.fromtimestamp(self.reader.header.time_date_stampt)
    f.write("Timestamp: %s<br>" % dt.strftime('%Y-%m-%d %H:%M:%S'))
    self.output_context(f, InspectionWebFormatter.CONTEXT_FULL)
    self.output_address_ranges(f)
    self.output_footer(f)
    return

  def output_address_ranges(self, f):
    regions = {}
    def print_region(_reader, start, size, _location):
      regions[start] = size
    self.reader.ForEachMemoryRegion(print_region)
    f.write("<h3>Available memory regions</h3>")
    f.write('<div class="code">')
    f.write("<table class=\"regions\">")
    f.write("<thead><tr>")
    f.write("<th>Start address</th>")
    f.write("<th>End address</th>")
    f.write("<th>Number of bytes</th>")
    f.write("</tr></thead>")
    for start in sorted(regions):
      size = regions[start]
      f.write("<tr>")
      f.write("<td>%s</td>" % self.format_address(start))
      f.write("<td>&nbsp;%s</td>" % self.format_address(start + size))
      f.write("<td>&nbsp;%d</td>" % size)
      f.write("</tr>")
    f.write("</table>")
    f.write('</div>')
    return

  def output_module_details(self, f, module):
    f.write("<b>%s</b>" % GetModuleName(self.reader, module))
    file_version = GetVersionString(module.version_info.dwFileVersionMS,
                                    module.version_info.dwFileVersionLS)
    product_version = GetVersionString(module.version_info.dwProductVersionMS,
                                       module.version_info.dwProductVersionLS)
    f.write("<br>&nbsp;&nbsp;")
    f.write("base: %s" % self.reader.FormatIntPtr(module.base_of_image))
    f.write("<br>&nbsp;&nbsp;")
    f.write("  end: %s" % self.reader.FormatIntPtr(module.base_of_image +
                                            module.size_of_image))
    f.write("<br>&nbsp;&nbsp;")
    f.write("  file version: %s" % file_version)
    f.write("<br>&nbsp;&nbsp;")
    f.write("  product version: %s" % product_version)
    f.write("<br>&nbsp;&nbsp;")
    time_date_stamp = datetime.datetime.fromtimestamp(module.time_date_stamp)
    f.write("  timestamp: %s" % time_date_stamp)
    f.write("<br>");

  def output_modules(self, f):
    self.output_header(f)
    f.write('<div class="code">')
    for module in self.reader.module_list.modules:
      self.output_module_details(f, module)
    f.write("</div>")
    self.output_footer(f)
    return

  def output_context(self, f, details):
    exception_thread = self.reader.thread_map[self.reader.exception.thread_id]
    f.write("<h3>Exception context</h3>")
    f.write('<div class="code">')
    f.write("Thread id: %d" % exception_thread.id)
    f.write("&nbsp;&nbsp; Exception code: %08X<br/>" %
            self.reader.exception.exception.code)
    if details == InspectionWebFormatter.CONTEXT_FULL:
      if self.reader.exception.exception.parameter_count > 0:
        f.write("&nbsp;&nbsp; Exception parameters: ")
        for i in xrange(0, self.reader.exception.exception.parameter_count):
          f.write("%08x" % self.reader.exception.exception.information[i])
        f.write("<br><br>")

    for r in CONTEXT_FOR_ARCH[self.reader.arch]:
      f.write(HTML_REG_FORMAT %
              (r, self.format_address(self.reader.Register(r))))
    # TODO(vitalyr): decode eflags.
    if self.reader.arch in [MD_CPU_ARCHITECTURE_ARM, MD_CPU_ARCHITECTURE_ARM64]:
      f.write("<b>cpsr</b>: %s" % bin(self.reader.exception_context.cpsr)[2:])
    else:
      f.write("<b>eflags</b>: %s" %
              bin(self.reader.exception_context.eflags)[2:])
    f.write('</div>')
    return

  def align_down(self, a, size):
    alignment_correction = a % size
    return a - alignment_correction

  def align_up(self, a, size):
    alignment_correction = (size - 1) - ((a + size - 1) % size)
    return a + alignment_correction

  def format_object(self, address):
    heap_object = self.padawan.SenseObject(address)
    return cgi.escape(str(heap_object or ""))

  def output_data(self, f, straddress, datakind):
    try:
      self.output_header(f)
      address = int(straddress, 0)
      if not self.reader.IsValidAddress(address):
        f.write("<h3>Address 0x%x not found in the dump.</h3>" % address)
        return
      region = self.reader.FindRegion(address)
      if datakind == "address":
        self.output_words(f, region[0], region[0] + region[1], address, "Dump")
      elif datakind == "ascii":
        self.output_ascii(f, region[0], region[0] + region[1], address)
      self.output_footer(f)

    except ValueError:
      f.write("<h3>Unrecognized address format \"%s\".</h3>" % straddress)
    return

  def output_words(self, f, start_address, end_address,
                   highlight_address, desc):
    region = self.reader.FindRegion(highlight_address)
    if region is None:
      f.write("<h3>Address 0x%x not found in the dump.</h3>" %
              (highlight_address))
      return
    size = self.heap.PointerSize()
    start_address = self.align_down(start_address, size)
    low = self.align_down(region[0], size)
    high = self.align_up(region[0] + region[1], size)
    if start_address < low:
      start_address = low
    end_address = self.align_up(end_address, size)
    if end_address > high:
      end_address = high

    expand = ""
    if start_address != low or end_address != high:
      expand = ("(<a href=\"data.html?%s&amp;val=0x%x#highlight\">"
                " more..."
                " </a>)" %
                (self.encfilename, highlight_address))

    f.write("<h3>%s 0x%x - 0x%x, "
            "highlighting <a href=\"#highlight\">0x%x</a> %s</h3>" %
            (desc, start_address, end_address, highlight_address, expand))
    f.write('<div class="code">')
    f.write("<table class=codedump>")

    for j in xrange(0, end_address - start_address, size):
      slot = start_address + j
      heap_object = ""
      maybe_address = None
      end_region = region[0] + region[1]
      if slot < region[0] or slot + size > end_region:
        straddress = "0x"
        for i in xrange(end_region, slot + size):
          straddress += "??"
        for i in reversed(
            xrange(max(slot, region[0]), min(slot + size, end_region))):
          straddress += "%02x" % self.reader.ReadU8(i)
        for i in xrange(slot, region[0]):
          straddress += "??"
      else:
        maybe_address = self.reader.ReadUIntPtr(slot)
        straddress = self.format_address(maybe_address)
        if maybe_address:
          heap_object = self.format_object(maybe_address)

      address_fmt = "%s&nbsp;</td>"
      if slot == highlight_address:
        f.write("<tr class=highlight-line>")
        address_fmt = "<a id=highlight></a>%s&nbsp;</td>"
      elif slot < highlight_address and highlight_address < slot + size:
        f.write("<tr class=inexact-highlight-line>")
        address_fmt = "<a id=highlight></a>%s&nbsp;</td>"
      else:
        f.write("<tr>")

      f.write("<td>")
      self.output_comment_box(f, "da-", slot)
      f.write("</td>")
      self.td_from_address(f, slot)
      f.write(address_fmt % self.format_address(slot))
      self.td_from_address(f, maybe_address)
      f.write(":&nbsp;%s&nbsp;</td>" % straddress)
      f.write("<td>")
      if maybe_address != None:
        self.output_comment_box(
            f, "sv-" + self.reader.FormatIntPtr(slot), maybe_address)
      f.write("</td>")
      f.write("<td>%s</td>" % (heap_object or ''))
      f.write("</tr>")
    f.write("</table>")
    f.write("</div>")
    return

  def output_ascii(self, f, start_address, end_address, highlight_address):
    region = self.reader.FindRegion(highlight_address)
    if region is None:
      f.write("<h3>Address %x not found in the dump.</h3>" %
          highlight_address)
      return
    if start_address < region[0]:
      start_address = region[0]
    if end_address > region[0] + region[1]:
      end_address = region[0] + region[1]

    expand = ""
    if start_address != region[0] or end_address != region[0] + region[1]:
      link = ("data.html?%s&amp;val=0x%x&amp;type=ascii#highlight" %
              (self.encfilename, highlight_address))
      expand = "(<a href=\"%s\">more...</a>)" % link

    f.write("<h3>ASCII dump 0x%x - 0x%x, highlighting 0x%x %s</h3>" %
            (start_address, end_address, highlight_address, expand))

    line_width = 64

    f.write('<div class="code">')

    start = self.align_down(start_address, line_width)

    for i in xrange(end_address - start):
      address = start + i
      if address % 64 == 0:
        if address != start:
          f.write("<br>")
        f.write("0x%08x:&nbsp;" % address)
      if address < start_address:
        f.write("&nbsp;")
      else:
        if address == highlight_address:
          f.write("<span class=\"highlight\">")
        code = self.reader.ReadU8(address)
        if code < 127 and code >= 32:
          f.write("&#")
          f.write(str(code))
          f.write(";")
        else:
          f.write("&middot;")
        if address == highlight_address:
          f.write("</span>")
    f.write("</div>")
    return

  def output_disasm(self, f, straddress, strexact):
    try:
      self.output_header(f)
      address = int(straddress, 0)
      if not self.reader.IsValidAddress(address):
        f.write("<h3>Address 0x%x not found in the dump.</h3>" % address)
        return
      region = self.reader.FindRegion(address)
      self.output_disasm_range(
          f, region[0], region[0] + region[1], address, strexact == "on")
      self.output_footer(f)
    except ValueError:
      f.write("<h3>Unrecognized address format \"%s\".</h3>" % straddress)
    return

  def output_disasm_range(
      self, f, start_address, end_address, highlight_address, exact):
    region = self.reader.FindRegion(highlight_address)
    if start_address < region[0]:
      start_address = region[0]
    if end_address > region[0] + region[1]:
      end_address = region[0] + region[1]
    count = end_address - start_address
    lines = self.reader.GetDisasmLines(start_address, count)
    found = False
    if exact:
      for line in lines:
        if line[0] + start_address == highlight_address:
          found = True
          break
      if not found:
        start_address = highlight_address
        count = end_address - start_address
        lines = self.reader.GetDisasmLines(highlight_address, count)
    expand = ""
    if start_address != region[0] or end_address != region[0] + region[1]:
      exactness = ""
      if exact and not found and end_address == region[0] + region[1]:
        exactness = "&amp;exact=off"
      expand = ("(<a href=\"disasm.html?%s%s"
                "&amp;val=0x%x#highlight\">more...</a>)" %
                (self.encfilename, exactness, highlight_address))

    f.write("<h3>Disassembling 0x%x - 0x%x, highlighting 0x%x %s</h3>" %
            (start_address, end_address, highlight_address, expand))
    f.write('<div class="code">')
    f.write("<table class=\"codedump\">");
    for i in xrange(len(lines)):
      line = lines[i]
      next_address = count
      if i + 1 < len(lines):
        next_line = lines[i + 1]
        next_address = next_line[0]
      self.format_disasm_line(
          f, start_address, line, next_address, highlight_address)
    f.write("</table>")
    f.write("</div>")
    return

  def annotate_disasm_addresses(self, line):
    extra = []
    for m in ADDRESS_RE.finditer(line):
      maybe_address = int(m.group(0), 16)
      formatted_address = self.format_address(maybe_address, m.group(0))
      line = line.replace(m.group(0), formatted_address)
      object_info = self.padawan.SenseObject(maybe_address)
      if not object_info:
        continue
      extra.append(cgi.escape(str(object_info)))
    if len(extra) == 0:
      return line
    return ("%s <span class=disasmcomment>;; %s</span>" %
            (line, ", ".join(extra)))

  def format_disasm_line(
      self, f, start, line, next_address, highlight_address):
    line_address = start + line[0]
    address_fmt = "  <td>%s</td>"
    if line_address == highlight_address:
      f.write("<tr class=highlight-line>")
      address_fmt = "  <td><a id=highlight>%s</a></td>"
    elif (line_address < highlight_address and
          highlight_address < next_address + start):
      f.write("<tr class=inexact-highlight-line>")
      address_fmt = "  <td><a id=highlight>%s</a></td>"
    else:
      f.write("<tr>")
    num_bytes = next_address - line[0]
    stack_slot = self.heap.stack_map.get(line_address)
    marker = ""
    if stack_slot:
      marker = "=>"

    code = line[1]

    # Some disassemblers insert spaces between each byte,
    # while some do not.
    if code[2] == " ":
        op_offset = 3 * num_bytes - 1
    else:
        op_offset = 2 * num_bytes

    # Compute the actual call target which the disassembler is too stupid
    # to figure out (it adds the call offset to the disassembly offset rather
    # than the absolute instruction address).
    if self.heap.reader.arch == MD_CPU_ARCHITECTURE_X86:
      if code.startswith("e8"):
        words = code.split()
        if len(words) > 6 and words[5] == "call":
          offset = int(words[4] + words[3] + words[2] + words[1], 16)
          target = (line_address + offset + 5) & 0xFFFFFFFF
          code = code.replace(words[6], "0x%08x" % target)
    # TODO(jkummerow): port this hack to ARM and x64.

    opcodes = code[:op_offset]
    code = self.annotate_disasm_addresses(code[op_offset:])
    f.write("  <td>")
    self.output_comment_box(f, "codel-", line_address)
    f.write("</td>")
    f.write(address_fmt % marker)
    f.write("  ")
    self.td_from_address(f, line_address)
    f.write(self.format_address(line_address))
    f.write(" (+0x%x)</td>" % line[0])
    f.write("<td>:&nbsp;%s&nbsp;</td>" % opcodes)
    f.write("<td>%s</td>" % code)
    f.write("</tr>")

  def output_comment_box(self, f, prefix, address):
    comment = self.comments.get_comment(address)
    value = ""
    if comment:
      value = " value=\"%s\"" % cgi.escape(comment)
    f.write("<input type=text class=ci "
            "id=%s-address-0x%s onchange=c()%s>" %
            (prefix,
             self.reader.FormatIntPtr(address),
             value))

  MAX_FOUND_RESULTS = 100

  def output_find_results(self, f, results):
    f.write("Addresses")
    toomany = len(results) > self.MAX_FOUND_RESULTS
    if toomany:
      f.write("(found %i results, displaying only first %i)" %
              (len(results), self.MAX_FOUND_RESULTS))
    f.write(": ")
    results = sorted(results)
    results = results[:min(len(results), self.MAX_FOUND_RESULTS)]
    for address in results:
      f.write("<span %s>%s</span>" %
              (self.comments.get_style_class_string(address),
               self.format_address(address)))
    if toomany:
      f.write("...")


  def output_page_info(self, f, page_kind, page_address, my_page_address):
    if my_page_address == page_address and page_address != 0:
      f.write("Marked first %s page." % page_kind)
    else:
      f.write("<span id=\"%spage\" style=\"display:none\">" % page_kind)
      f.write("Marked first %s page." % page_kind)
      f.write("</span>\n")
      f.write("<button onclick=\"onpage('%spage', '0x%x')\">" %
              (page_kind, my_page_address))
      f.write("Mark as first %s page</button>" % page_kind)
    return

  def output_search_res(self, f, straddress):
    try:
      self.output_header(f)
      f.write("<h3>Search results for %s</h3>" % straddress)

      address = int(straddress, 0)

      f.write("Comment: ")
      self.output_comment_box(f, "search-", address)
      f.write("<br>")

      page_address = address & ~self.heap.PageAlignmentMask()

      f.write("Page info: ")
      self.output_page_info(f, "old", self.padawan.known_first_old_page, \
                            page_address)
      self.output_page_info(f, "map", self.padawan.known_first_map_page, \
                            page_address)

      if not self.reader.IsValidAddress(address):
        f.write("<h3>The contents at address %s not found in the dump.</h3>" % \
                straddress)
      else:
        # Print as words
        self.output_words(f, address - 8, address + 32, address, "Dump")

        # Print as ASCII
        f.write("<hr>")
        self.output_ascii(f, address, address + 256, address)

        # Print as code
        f.write("<hr>")
        self.output_disasm_range(f, address - 16, address + 16, address, True)

      aligned_res, unaligned_res = self.reader.FindWordList(address)

      if len(aligned_res) > 0:
        f.write("<h3>Occurrences of 0x%x at aligned addresses</h3>" %
                address)
        self.output_find_results(f, aligned_res)

      if len(unaligned_res) > 0:
        f.write("<h3>Occurrences of 0x%x at unaligned addresses</h3>" % \
                address)
        self.output_find_results(f, unaligned_res)

      if len(aligned_res) + len(unaligned_res) == 0:
        f.write("<h3>No occurrences of 0x%x found in the dump</h3>" % address)

      self.output_footer(f)

    except ValueError:
      f.write("<h3>Unrecognized address format \"%s\".</h3>" % straddress)
    return

  def output_disasm_pc(self, f):
    address = self.reader.ExceptionIP()
    if not self.reader.IsValidAddress(address):
      return
    self.output_disasm_range(f, address - 16, address + 16, address, True)


WEB_DUMPS_HEADER = """
<!DOCTYPE html>
<html>
<head>
<meta content="text/html; charset=utf-8" http-equiv="content-type">
<style media="screen" type="text/css">

.dumplist {
  border-collapse : collapse;
  border-spacing : 0px;
  font-family: monospace;
}

.dumpcomments {
  border : 1px solid LightGray;
  width : 32em;
}

</style>

<script type="application/javascript">

var dump_str = "dump-";
var dump_len = dump_str.length;

function dump_comment() {
  var s = event.srcElement.id;
  var index = s.indexOf(dump_str);
  if (index >= 0) {
    send_dump_desc(s.substring(index + dump_len), event.srcElement.value);
  }
}

function send_dump_desc(name, desc) {
  xmlhttp = new XMLHttpRequest();
  name = encodeURIComponent(name)
  desc = encodeURIComponent(desc)
  xmlhttp.open("GET",
      "setdumpdesc?dump=" + name +
      "&description=" + desc, true);
  xmlhttp.send();
}

</script>

<title>Dump list</title>
</head>

<body>
"""

WEB_DUMPS_FOOTER = """
</body>
</html>
"""

DUMP_FILE_RE = re.compile(r"[-_0-9a-zA-Z][-\._0-9a-zA-Z]*\.dmp$")


class InspectionWebServer(BaseHTTPServer.HTTPServer):
  def __init__(self, port_number, switches, minidump_name):
    BaseHTTPServer.HTTPServer.__init__(
        self, ('localhost', port_number), InspectionWebHandler)
    splitpath = os.path.split(minidump_name)
    self.dumppath = splitpath[0]
    self.dumpfilename = splitpath[1]
    self.default_formatter = InspectionWebFormatter(
        switches, minidump_name, self)
    self.formatters = { self.dumpfilename : self.default_formatter }
    self.switches = switches

  def output_dump_desc_field(self, f, name):
    try:
      descfile = open(os.path.join(self.dumppath, name + ".desc"), "r")
      desc = descfile.readline()
      descfile.close()
    except IOError:
      desc = ""
    f.write("<input type=\"text\" class=\"dumpcomments\" "
            "id=\"dump-%s\" onchange=\"dump_comment()\" value=\"%s\">\n" %
            (cgi.escape(name), desc))

  def set_dump_desc(self, name, description):
    if not DUMP_FILE_RE.match(name):
      return False
    fname = os.path.join(self.dumppath, name)
    if not os.path.isfile(fname):
      return False
    fname = fname + ".desc"
    descfile = open(fname, "w")
    descfile.write(description)
    descfile.close()
    return True

  def get_dump_formatter(self, name):
    if name is None:
      return self.default_formatter
    else:
      if not DUMP_FILE_RE.match(name):
        raise WebParameterError("Invalid name '%s'" % name)
      formatter = self.formatters.get(name, None)
      if formatter is None:
        try:
          formatter = InspectionWebFormatter(
              self.switches, os.path.join(self.dumppath, name), self)
          self.formatters[name] = formatter
        except IOError:
          raise WebParameterError("Could not open dump '%s'" % name)
      return formatter

  def output_dumps(self, f):
    f.write(WEB_DUMPS_HEADER)
    f.write("<h3>List of available dumps</h3>")
    f.write("<table class=\"dumplist\">\n")
    f.write("<thead><tr>")
    f.write("<th>Name</th>")
    f.write("<th>File time</th>")
    f.write("<th>Comment</th>")
    f.write("</tr></thead>")
    dumps_by_time = {}
    for fname in os.listdir(self.dumppath):
      if DUMP_FILE_RE.match(fname):
        mtime = os.stat(os.path.join(self.dumppath, fname)).st_mtime
        fnames = dumps_by_time.get(mtime, [])
        fnames.append(fname)
        dumps_by_time[mtime] = fnames

    for mtime in sorted(dumps_by_time, reverse=True):
      fnames = dumps_by_time[mtime]
      for fname in fnames:
        f.write("<tr>\n")
        f.write("<td><a href=\"summary.html?%s\">%s</a></td>\n" % (
            (urllib.urlencode({ 'dump' : fname }), fname)))
        f.write("<td>&nbsp;&nbsp;&nbsp;")
        f.write(datetime.datetime.fromtimestamp(mtime))
        f.write("</td>")
        f.write("<td>&nbsp;&nbsp;&nbsp;")
        self.output_dump_desc_field(f, fname)
        f.write("</td>")
        f.write("</tr>\n")
    f.write("</table>\n")
    f.write(WEB_DUMPS_FOOTER)
    return

class InspectionShell(cmd.Cmd):
  def __init__(self, reader, heap):
    cmd.Cmd.__init__(self)
    self.reader = reader
    self.heap = heap
    self.padawan = InspectionPadawan(reader, heap)
    self.prompt = "(grok) "

    self.dd_start = 0
    self.dd_num = 0x10
    self.u_start = 0
    self.u_num = 0

  def EvalExpression(self, expr):
    # Auto convert hex numbers to a python compatible format
    if expr[:2] == "00":
      expr = "0x"+expr
    result = None
    try:
      # Ugly hack to patch in register values.
      registers = [register
                   for register,value in self.reader.ContextDescriptor().fields]
      registers.sort(key=lambda r: len(r))
      registers.reverse()
      for register in registers:
        expr = expr.replace("$"+register, str(self.reader.Register(register)))
      result = eval(expr)
    except Exception as e:
      print("**** Could not evaluate '%s': %s" % (expr, e))
      raise e
    return result

  def ParseAddressExpr(self, expr):
    address = 0;
    try:
      result = self.EvalExpression(expr)
    except:
      return 0
    try:
      address = int(result)
    except Exception as e:
      print("**** Could not convert '%s' => %s to valid address: %s" % (
          expr, result , e))
    return address

  def do_help(self, cmd=None):
    if len(cmd) == 0:
      print "Available commands"
      print "=" * 79
      prefix = "do_"
      methods = inspect.getmembers(InspectionShell, predicate=inspect.ismethod)
      for name,method in methods:
        if not name.startswith(prefix): continue
        doc = inspect.getdoc(method)
        if not doc: continue
        name = prefix.join(name.split(prefix)[1:])
        description = doc.splitlines()[0]
        print (name + ": ").ljust(16) + description
      print "=" * 79
    else:
      return super(InspectionShell, self).do_help(cmd)

  def do_p(self, cmd):
    """ see print """
    return self.do_print(cmd)

  def do_print(self, cmd):
    """
    Evaluate an arbitrary python command.
    """
    try:
      print(self.EvalExpression(cmd))
    except:
      pass

  def do_da(self, address):
    """ see display_ascii"""
    return self.do_display_ascii(address)

  def do_display_ascii(self, address):
    """
     Print ASCII string starting at specified address.
    """
    address = self.ParseAddressExpr(address)
    string = self.reader.ReadAsciiString(address)
    if string == "":
      print "Not an ASCII string at %s" % self.reader.FormatIntPtr(address)
    else:
      print "%s\n" % string

  def do_dsa(self, address):
    """ see display_stack_ascii"""
    return self.do_display_stack_ascii(address)

  def do_display_stack_ascii(self, address):
    """
    Print ASCII stack error message.
    """
    if self.reader.exception is None:
      print "Minidump has no exception info"
      return
    if len(address) == 0:
      address = None
    else:
      address = self.ParseAddressExpr(address)
    self.padawan.PrintStackTraceMessage(address)

  def do_dd(self, args):
    """
     Interpret memory in the given region [address, address + num * word_size)

     (if available) as a sequence of words. Automatic alignment is not performed.
     If the num is not specified, a default value of 16 words is usif not self.Is
     If no address is given, dd continues printing at the next word.

     Synopsis: dd 0x<address>|$register [0x<num>]
    """
    if len(args) != 0:
      args = args.split(' ')
      self.dd_start = self.ParseAddressExpr(args[0])
      self.dd_num = int(args[1], 16) if len(args) > 1 else 0x10
    else:
      self.dd_start += self.dd_num * self.reader.PointerSize()
    if not self.reader.IsAlignedAddress(self.dd_start):
      print "Warning: Dumping un-aligned memory, is this what you had in mind?"
    end = self.dd_start + self.reader.PointerSize() * self.dd_num
    self.padawan.InterpretMemory(self.dd_start, end)

  def do_do(self, address):
    """ see display_object """
    return self.do_display_object(address)

  def do_display_object(self, address):
    """
     Interpret memory at the given address as a V8 object.

     Automatic alignment makes sure that you can pass tagged as well as
     un-tagged addresses.
    """
    address = self.ParseAddressExpr(address)
    if self.reader.IsAlignedAddress(address):
      address = address + 1
    elif not self.heap.IsTaggedObjectAddress(address):
      print "Address doesn't look like a valid pointer!"
      return
    heap_object = self.padawan.SenseObject(address)
    if heap_object:
      heap_object.Print(Printer())
    else:
      print "Address cannot be interpreted as object!"

  def do_dso(self, args):
    """ see display_stack_objects """
    return self.do_display_stack_objects(args)

  def do_display_stack_objects(self, args):
    """
    Find and Print object pointers in the given range.

    Print all possible object pointers that are on the stack or in the given
    address range.

    Usage: dso [START_ADDR,[END_ADDR]]
    """
    start = self.reader.StackTop()
    end = self.reader.StackBottom()
    if len(args) != 0:
      args = args.split(' ')
      start = self.ParseAddressExpr(args[0])
      end = self.ParseAddressExpr(args[1]) if len(args) > 1 else end
    objects = self.heap.FindObjectPointers(start, end)
    for address in objects:
      heap_object = self.padawan.SenseObject(address)
      info = ""
      if heap_object:
        info = str(heap_object)
      print("%s %s" % (self.padawan.FormatIntPtr(address), info))

  def do_do_desc(self, address):
    """
      Print a descriptor array in a readable format.
    """
    start = self.ParseAddressExpr(address)
    if ((start & 1) == 1): start = start - 1
    DescriptorArray(FixedArray(self.heap, None, start)).Print(Printer())

  def do_do_map(self, address):
    """
      Print a Map in a readable format.
    """
    start = self.ParseAddressExpr(address)
    if ((start & 1) == 1): start = start - 1
    Map(self.heap, None, start).Print(Printer())

  def do_do_trans(self, address):
    """
      Print a transition array in a readable format.
    """
    start = self.ParseAddressExpr(address)
    if ((start & 1) == 1): start = start - 1
    TransitionArray(FixedArray(self.heap, None, start)).Print(Printer())

  def do_dp(self, address):
    """ see display_page """
    return self.do_display_page(address)

  def do_display_page(self, address):
    """
     Prints details about the V8 heap page of the given address.

     Interpret memory at the given address as being on a V8 heap page
     and print information about the page header (if available).
    """
    address = self.ParseAddressExpr(address)
    page_address = address & ~self.heap.PageAlignmentMask()
    if self.reader.IsValidAddress(page_address):
      print "**** Not Implemented"
      return
    else:
      print "Page header is not available!"

  def do_k(self, arguments):
    """
     Teach V8 heap layout information to the inspector.

     This increases the amount of annotations the inspector can produce while
     dumping data. The first page of each heap space is of particular interest
     because it contains known objects that do not move.
    """
    self.padawan.PrintKnowledge()

  def do_ko(self, address):
    """ see known_oldspace """
    return self.do_known_oldspace(address)

  def do_known_oldspace(self, address):
    """
     Teach V8 heap layout information to the inspector.

     Set the first old space page by passing any pointer into that page.
    """
    address = self.ParseAddressExpr(address)
    page_address = address & ~self.heap.PageAlignmentMask()
    self.padawan.known_first_old_page = page_address

  def do_km(self, address):
    """ see known_map """
    return self.do_known_map(address)

  def do_known_map(self, address):
    """
     Teach V8 heap layout information to the inspector.

     Set the first map-space page by passing any pointer into that page.
    """
    address = self.ParseAddressExpr(address)
    page_address = address & ~self.heap.PageAlignmentMask()
    self.padawan.known_first_map_page = page_address

  def do_list(self, smth):
    """
     List all available memory regions.
    """
    def print_region(reader, start, size, location):
      print "  %s - %s (%d bytes)" % (reader.FormatIntPtr(start),
                                      reader.FormatIntPtr(start + size),
                                      size)
    print "Available memory regions:"
    self.reader.ForEachMemoryRegion(print_region)

  def do_lm(self, arg):
    """ see list_modules """
    return self.do_list_modules(arg)

  def do_list_modules(self, arg):
    """
     List details for all loaded modules in the minidump.

     An argument can be passed to limit the output to only those modules that
     contain the argument as a substring (case insensitive match).
    """
    for module in self.reader.module_list.modules:
      if arg:
        name = GetModuleName(self.reader, module).lower()
        if name.find(arg.lower()) >= 0:
          PrintModuleDetails(self.reader, module)
      else:
        PrintModuleDetails(self.reader, module)
    print

  def do_s(self, word):
    """ see search """
    return self.do_search(word)

  def do_search(self, word):
    """
     Search for a given word in available memory regions.

     The given word is expanded to full pointer size and searched at aligned
     as well as un-aligned memory locations. Use 'sa' to search aligned locations
     only.
    """
    try:
      word = self.ParseAddressExpr(word)
    except ValueError:
      print "Malformed word, prefix with '0x' to use hexadecimal format."
      return
    print "Searching for word %d/0x%s:" % (word, self.reader.FormatIntPtr(word))
    self.reader.FindWord(word)

  def do_sh(self, none):
    """
     Search for the V8 Heap object in all available memory regions.

     You might get lucky and find this rare treasure full of invaluable
     information.
    """
    print "**** Not Implemented"

  def do_u(self, args):
    """ see disassemble """
    return self.do_disassemble(args)

  def do_disassemble(self, args):
    """
     Unassemble memory in the region [address, address + size).

     If the size is not specified, a default value of 32 bytes is used.
     Synopsis: u 0x<address> 0x<size>
    """
    if len(args) != 0:
      args = args.split(' ')
      self.u_start = self.ParseAddressExpr(args[0])
      self.u_size = self.ParseAddressExpr(args[1]) if len(args) > 1 else 0x20
      skip = False
    else:
      # Skip the first instruction if we reuse the last address.
      skip = True

    if not self.reader.IsValidAddress(self.u_start):
      print "Address %s is not contained within the minidump!" % (
          self.reader.FormatIntPtr(self.u_start))
      return
    lines = self.reader.GetDisasmLines(self.u_start, self.u_size)
    if len(lines) == 0:
      print "Address %s could not be disassembled!" % (
          self.reader.FormatIntPtr(self.u_start))
      print "    Could not disassemble using %s." % OBJDUMP_BIN
      print "    Pass path to architecture specific objdump via --objdump?"
      return
    for line in lines:
      if skip:
        skip = False
        continue
      print FormatDisasmLine(self.u_start, self.heap, line)
    # Set the next start address = last line
    self.u_start += lines[-1][0]
    print

  def do_EOF(self, none):
    raise KeyboardInterrupt

EIP_PROXIMITY = 64

CONTEXT_FOR_ARCH = {
    MD_CPU_ARCHITECTURE_AMD64:
      ['rax', 'rbx', 'rcx', 'rdx', 'rdi', 'rsi', 'rbp', 'rsp', 'rip',
       'r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15'],
    MD_CPU_ARCHITECTURE_ARM:
      ['r0', 'r1', 'r2', 'r3', 'r4', 'r5', 'r6', 'r7', 'r8', 'r9',
       'r10', 'r11', 'r12', 'sp', 'lr', 'pc'],
    MD_CPU_ARCHITECTURE_ARM64:
      ['r0', 'r1', 'r2', 'r3', 'r4', 'r5', 'r6', 'r7', 'r8', 'r9',
       'r10', 'r11', 'r12', 'r13', 'r14', 'r15', 'r16', 'r17', 'r18', 'r19',
       'r20', 'r21', 'r22', 'r23', 'r24', 'r25', 'r26', 'r27', 'r28',
       'fp', 'lr', 'sp', 'pc'],
    MD_CPU_ARCHITECTURE_X86:
      ['eax', 'ebx', 'ecx', 'edx', 'edi', 'esi', 'ebp', 'esp', 'eip']
}

KNOWN_MODULES = {'chrome.exe', 'chrome.dll'}

def GetVersionString(ms, ls):
  return "%d.%d.%d.%d" % (ms >> 16, ms & 0xffff, ls >> 16, ls & 0xffff)


def GetModuleName(reader, module):
  name = reader.ReadMinidumpString(module.module_name_rva)
  # simplify for path manipulation
  name = name.encode('utf-8')
  return str(os.path.basename(str(name).replace("\\", "/")))


def PrintModuleDetails(reader, module):
  print "%s" % GetModuleName(reader, module)
  file_version = GetVersionString(module.version_info.dwFileVersionMS,
                                  module.version_info.dwFileVersionLS);
  product_version = GetVersionString(module.version_info.dwProductVersionMS,
                                     module.version_info.dwProductVersionLS)
  print "  base: %s" % reader.FormatIntPtr(module.base_of_image)
  print "  end: %s" % reader.FormatIntPtr(module.base_of_image +
                                          module.size_of_image)
  print "  file version: %s" % file_version
  print "  product version: %s" % product_version
  time_date_stamp = datetime.datetime.fromtimestamp(module.time_date_stamp)
  print "  timestamp: %s" % time_date_stamp


def AnalyzeMinidump(options, minidump_name):
  reader = MinidumpReader(options, minidump_name)
  heap = None

  stack_top = reader.ExceptionSP()
  stack_bottom = reader.StackBottom()
  stack_map = {reader.ExceptionIP(): -1}
  for slot in xrange(stack_top, stack_bottom, reader.PointerSize()):
    maybe_address = reader.ReadUIntPtr(slot)
    if not maybe_address in stack_map:
      stack_map[maybe_address] = slot

  heap = V8Heap(reader, stack_map)
  padawan = InspectionPadawan(reader, heap)

  DebugPrint("========================================")
  if reader.exception is None:
    print "Minidump has no exception info"
  else:
    print "Address markers:"
    print "  T = valid tagged pointer in the minidump"
    print "  S = address on the exception stack"
    print "  C = address in loaded C/C++ module"
    print "  * = address in the minidump"
    print ""
    print "Exception info:"
    exception_thread = reader.ExceptionThread()
    print "  thread id: %d" % exception_thread.id
    print "  code:      %08X" % reader.exception.exception.code
    print "  context:"
    context = CONTEXT_FOR_ARCH[reader.arch]
    maxWidth = max(map(lambda s: len(s), context))
    for r in context:
      register_value = reader.Register(r)
      print "    %s: %s" % (r.rjust(maxWidth),
                            heap.FormatIntPtr(register_value))
    # TODO(vitalyr): decode eflags.
    if reader.arch in [MD_CPU_ARCHITECTURE_ARM, MD_CPU_ARCHITECTURE_ARM64]:
      print "    cpsr: %s" % bin(reader.exception_context.cpsr)[2:]
    else:
      print "    eflags: %s" % bin(reader.exception_context.eflags)[2:]

    print
    print "  modules:"
    for module in reader.module_list.modules:
      name = GetModuleName(reader, module)
      if name in KNOWN_MODULES:
        print "    %s at %08X" % (name, module.base_of_image)
        reader.TryLoadSymbolsFor(name, module)
    print

    print "  stack-top:    %s" % heap.FormatIntPtr(reader.StackTop())
    print "  stack-bottom: %s" % heap.FormatIntPtr(reader.StackBottom())
    print ""

    if options.shell:
      padawan.PrintStackTraceMessage(print_message=False)

    print "Disassembly around exception.eip:"
    eip_symbol = reader.FindSymbol(reader.ExceptionIP())
    if eip_symbol is not None:
      print eip_symbol
    disasm_start = reader.ExceptionIP() - EIP_PROXIMITY
    disasm_bytes = 2 * EIP_PROXIMITY
    if (options.full):
      full_range = reader.FindRegion(reader.ExceptionIP())
      if full_range is not None:
        disasm_start = full_range[0]
        disasm_bytes = full_range[1]

    lines = reader.GetDisasmLines(disasm_start, disasm_bytes)

    if not lines:
      print "Could not disassemble using %s." % OBJDUMP_BIN
      print "Pass path to architecture specific objdump via --objdump?"

    for line in lines:
      print FormatDisasmLine(disasm_start, heap, line)
    print

  if heap is None:
    heap = V8Heap(reader, None)

  if options.full:
    FullDump(reader, heap)

  if options.command:
    InspectionShell(reader, heap).onecmd(options.command)

  if options.shell:
    try:
      InspectionShell(reader, heap).cmdloop("type help to get help")
    except KeyboardInterrupt:
      print "Kthxbye."
  elif not options.command:
    if reader.exception is not None:
      print "Annotated stack (from exception.esp to bottom):"
      stack_start = padawan.PrintStackTraceMessage()
      padawan.InterpretMemory(stack_start, stack_bottom)
  reader.Dispose()


if __name__ == "__main__":
  parser = optparse.OptionParser(USAGE)
  parser.add_option("-s", "--shell", dest="shell", action="store_true",
                    help="start an interactive inspector shell")
  parser.add_option("-w", "--web", dest="web", action="store_true",
                    help="start a web server on localhost:%i" % PORT_NUMBER)
  parser.add_option("-c", "--command", dest="command", default="",
                    help="run an interactive inspector shell command and exit")
  parser.add_option("-f", "--full", dest="full", action="store_true",
                    help="dump all information contained in the minidump")
  parser.add_option("--symdir", dest="symdir", default=".",
                    help="directory containing *.pdb.sym file with symbols")
  parser.add_option("--objdump", default="",
                    help="objdump tool to use [default: %s]" % (
                        DEFAULT_OBJDUMP_BIN))
  options, args = parser.parse_args()
  if len(args) != 1:
    parser.print_help()
    sys.exit(1)
  if options.web:
    try:
      server = InspectionWebServer(PORT_NUMBER, options, args[0])
      print 'Started httpserver on port ' , PORT_NUMBER
      webbrowser.open('http://localhost:%i/summary.html' % PORT_NUMBER)
      server.serve_forever()
    except KeyboardInterrupt:
      print '^C received, shutting down the web server'
      server.socket.close()
  else:
    AnalyzeMinidump(options, args[0])
