summaryrefslogtreecommitdiff
path: root/chromium/v8/tools/grokdump.py
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/v8/tools/grokdump.py')
-rwxr-xr-xchromium/v8/tools/grokdump.py297
1 files changed, 185 insertions, 112 deletions
diff --git a/chromium/v8/tools/grokdump.py b/chromium/v8/tools/grokdump.py
index 368580f0c3a..1d73b43aced 100755
--- a/chromium/v8/tools/grokdump.py
+++ b/chromium/v8/tools/grokdump.py
@@ -168,7 +168,7 @@ def FullDump(reader, heap):
print("%s - %s" % (reader.FormatIntPtr(start),
reader.FormatIntPtr(start + size)))
print(start + size + 1);
- for i in range(0, size, reader.PointerSize()):
+ for i in range(0, size, reader.MachinePointerSize()):
slot = start + i
maybe_address = reader.ReadUIntPtr(slot)
heap_object = heap.FindObject(maybe_address)
@@ -710,7 +710,7 @@ class MinidumpReader(object):
def _FindObjdump(self, options):
if options.objdump:
- objdump_bin = options.objdump
+ objdump_bin = options.objdump
else:
objdump_bin = self._FindThirdPartyObjdump()
if not objdump_bin or not os.path.exists(objdump_bin):
@@ -722,29 +722,29 @@ class MinidumpReader(object):
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]
+ # 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:
@@ -765,7 +765,7 @@ class MinidumpReader(object):
return self.FindLocation(address) is not None
def IsAlignedAddress(self, address):
- return (address % self.PointerSize()) == 0
+ return (address % self.MachinePointerSize()) == 0
def IsExceptionStackAddress(self, address):
if not self.IsAlignedAddress(address): return False
@@ -804,11 +804,29 @@ class MinidumpReader(object):
return (self.arch == MD_CPU_ARCHITECTURE_ARM64 or
self.arch == MD_CPU_ARCHITECTURE_AMD64)
+ def IsPointerCompressed(self):
+ # Assume all 64-bit builds are pointer compressed.
+ return self.Is64()
+
+ def Is32BitTagged(self):
+ return not self.Is64() or self.IsPointerCompressed()
+
+ def ReadTagged(self, address):
+ if self.Is32BitTagged():
+ return self.ReadU32(address)
+ return self.ReadU64(address)
+
def ReadUIntPtr(self, address):
if self.Is64():
return self.ReadU64(address)
return self.ReadU32(address)
+ def ReadSized(self, address, size):
+ if size == 8:
+ return self.ReadU64(address)
+ assert (size == 4)
+ return self.ReadU32(address)
+
def ReadBytes(self, address, size):
location = self.FindLocation(address)
return self.minidump[location:location + size]
@@ -819,8 +837,10 @@ class MinidumpReader(object):
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())]
+ ascii_content = [
+ c if c >= '\x20' and c < '\x7f' else '.'
+ for c in self.ReadBytes(address, self.MachinePointerSize())
+ ]
return ''.join(ascii_content)
def ReadAsciiString(self, address):
@@ -908,7 +928,7 @@ class MinidumpReader(object):
def FindWord(self, word, alignment=0):
def search_inside_region(reader, start, size, location):
location = (location + alignment) & ~alignment
- for i in range(size - self.PointerSize()):
+ for i in range(size - self.MachinePointerSize()):
loc = location + i
if reader._ReadWord(loc) == word:
slot = start + (loc - location)
@@ -920,7 +940,7 @@ class MinidumpReader(object):
aligned_res = []
unaligned_res = []
def search_inside_region(reader, start, size, location):
- for i in range(size - self.PointerSize()):
+ for i in range(size - self.MachinePointerSize()):
loc = location + i
if reader._ReadWord(loc) == word:
slot = start + (loc - location)
@@ -1023,11 +1043,21 @@ class MinidumpReader(object):
return "%016x" % value
return "%08x" % value
- def PointerSize(self):
+ def FormatTagged(self, value):
+ if self.Is64() and not self.IsPointerCompressed():
+ return "%016x" % value
+ return "%08x" % value
+
+ def MachinePointerSize(self):
if self.Is64():
return 8
return 4
+ def TaggedPointerSize(self):
+ if self.IsPointerCompressed():
+ return 4
+ return self.MachinePointerSize()
+
def Register(self, name):
return self.exception_context.__getattribute__(name)
@@ -1173,11 +1203,11 @@ class HeapObject(object):
instance_type)
def ObjectField(self, offset):
- field_value = self.heap.reader.ReadUIntPtr(self.address + offset)
+ field_value = self.heap.reader.ReadTagged(self.address + offset)
return self.heap.FindObjectOrSmi(field_value)
def SmiField(self, offset):
- field_value = self.heap.reader.ReadUIntPtr(self.address + offset)
+ field_value = self.heap.reader.ReadTagged(self.address + offset)
if self.heap.IsSmi(field_value):
return self.heap.SmiUntag(field_value)
return None
@@ -1189,7 +1219,7 @@ class Map(HeapObject):
# Instance Sizes
def InstanceSizesOffset(self):
- return self.heap.PointerSize()
+ return self.heap.TaggedPointerSize()
def InstanceSizeOffset(self):
return self.InstanceSizesOffset()
@@ -1224,28 +1254,29 @@ class Map(HeapObject):
return self.InstanceAttributesOffset() + self.heap.IntSize()
def PrototypeOffset(self):
- return self.BitField3Offset() + self.heap.PointerSize()
+ return self.BitField3Offset() + self.heap.TaggedPointerSize()
def ConstructorOrBackPointerOffset(self):
- return self.PrototypeOffset() + self.heap.PointerSize()
+ return self.PrototypeOffset() + self.heap.TaggedPointerSize()
def TransitionsOrPrototypeInfoOffset(self):
- return self.ConstructorOrBackPointerOffset() + self.heap.PointerSize()
+ return self.ConstructorOrBackPointerOffset() + self.heap.TaggedPointerSize()
def DescriptorsOffset(self):
- return self.TransitionsOrPrototypeInfoOffset() + self.heap.PointerSize()
+ return (self.TransitionsOrPrototypeInfoOffset() +
+ self.heap.TaggedPointerSize())
def CodeCacheOffset(self):
- return self.DescriptorsOffset() + self.heap.PointerSize()
+ return self.DescriptorsOffset() + self.heap.TaggedPointerSize()
def DependentCodeOffset(self):
- return self.CodeCacheOffset() + self.heap.PointerSize()
+ return self.CodeCacheOffset() + self.heap.TaggedPointerSize()
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 ReadSlot(self, offset):
+ return self.heap.reader.ReadTagged(self.address + offset)
def Print(self, p):
p.Print("Map(%08x)" % (self.address))
@@ -1264,7 +1295,7 @@ class Map(HeapObject):
p.Print(" - kind: %s" % (self.Decode(3, 5, bitfield2)))
- bitfield3 = self.ReadWord(self.BitField3Offset())
+ bitfield3 = self.ReadSlot(self.BitField3Offset())
p.Print(
" - EnumLength: %d NumberOfOwnDescriptors: %d OwnsDescriptors: %s" % (
@@ -1299,7 +1330,7 @@ class Map(HeapObject):
class String(HeapObject):
def LengthOffset(self):
# First word after the map is the hash, the second is the length.
- return self.heap.PointerSize() * 2
+ return self.heap.TaggedPointerSize() * 2
def __init__(self, heap, map, address):
HeapObject.__init__(self, heap, map, address)
@@ -1317,7 +1348,7 @@ class String(HeapObject):
class SeqString(String):
def CharsOffset(self):
- return self.heap.PointerSize() * 3
+ return self.heap.TaggedPointerSize() * 3
def __init__(self, heap, map, address):
String.__init__(self, heap, map, address)
@@ -1360,10 +1391,10 @@ class ExternalString(String):
class ConsString(String):
def LeftOffset(self):
- return self.heap.PointerSize() * 3
+ return self.heap.TaggedPointerSize() * 3
def RightOffset(self):
- return self.heap.PointerSize() * 4
+ return self.heap.TaggedPointerSize() * 4
def __init__(self, heap, map, address):
String.__init__(self, heap, map, address)
@@ -1390,13 +1421,13 @@ class Oddball(HeapObject):
]
def ToStringOffset(self):
- return self.heap.PointerSize()
+ return self.heap.TaggedPointerSize()
def ToNumberOffset(self):
- return self.ToStringOffset() + self.heap.PointerSize()
+ return self.ToStringOffset() + self.heap.TaggedPointerSize()
def KindOffset(self):
- return self.ToNumberOffset() + self.heap.PointerSize()
+ return self.ToNumberOffset() + self.heap.TaggedPointerSize()
def __init__(self, heap, map, address):
HeapObject.__init__(self, heap, map, address)
@@ -1418,13 +1449,13 @@ class Oddball(HeapObject):
class FixedArray(HeapObject):
def LengthOffset(self):
- return self.heap.PointerSize()
+ return self.heap.TaggedPointerSize()
def ElementsOffset(self):
- return self.heap.PointerSize() * 2
+ return self.heap.TaggedPointerSize() * 2
def MemberOffset(self, i):
- return self.ElementsOffset() + self.heap.PointerSize() * i
+ return self.ElementsOffset() + self.heap.TaggedPointerSize() * i
def Get(self, i):
return self.ObjectField(self.MemberOffset(i))
@@ -1561,10 +1592,10 @@ class TransitionArray(object):
class JSFunction(HeapObject):
def CodeEntryOffset(self):
- return 3 * self.heap.PointerSize()
+ return 3 * self.heap.TaggedPointerSize()
def SharedOffset(self):
- return 5 * self.heap.PointerSize()
+ return 5 * self.heap.TaggedPointerSize()
def __init__(self, heap, map, address):
HeapObject.__init__(self, heap, map, address)
@@ -1611,19 +1642,19 @@ class JSFunction(HeapObject):
class SharedFunctionInfo(HeapObject):
def CodeOffset(self):
- return 2 * self.heap.PointerSize()
+ return 2 * self.heap.TaggedPointerSize()
def ScriptOffset(self):
- return 7 * self.heap.PointerSize()
+ return 7 * self.heap.TaggedPointerSize()
def InferredNameOffset(self):
- return 9 * self.heap.PointerSize()
+ return 9 * self.heap.TaggedPointerSize()
def EndPositionOffset(self):
- return 12 * self.heap.PointerSize() + 4 * self.heap.IntSize()
+ return 12 * self.heap.TaggedPointerSize() + 4 * self.heap.IntSize()
def StartPositionAndTypeOffset(self):
- return 12 * self.heap.PointerSize() + 5 * self.heap.IntSize()
+ return 12 * self.heap.TaggedPointerSize() + 5 * self.heap.IntSize()
def __init__(self, heap, map, address):
HeapObject.__init__(self, heap, map, address)
@@ -1631,7 +1662,7 @@ class SharedFunctionInfo(HeapObject):
self.code = self.ObjectField(self.CodeOffset())
self.script = self.ObjectField(self.ScriptOffset())
self.inferred_name = self.ObjectField(self.InferredNameOffset())
- if heap.PointerSize() == 8:
+ if heap.TaggedPointerSize() == 8:
start_position_and_type = \
heap.reader.ReadU32(self.StartPositionAndTypeOffset())
self.start_position = start_position_and_type >> 2
@@ -1653,10 +1684,10 @@ class SharedFunctionInfo(HeapObject):
class Script(HeapObject):
def SourceOffset(self):
- return self.heap.PointerSize()
+ return self.heap.TaggedPointerSize()
def NameOffset(self):
- return self.SourceOffset() + self.heap.PointerSize()
+ return self.SourceOffset() + self.heap.TaggedPointerSize()
def __init__(self, heap, map, address):
HeapObject.__init__(self, heap, map, address)
@@ -1666,10 +1697,10 @@ class Script(HeapObject):
class CodeCache(HeapObject):
def DefaultCacheOffset(self):
- return self.heap.PointerSize()
+ return self.heap.TaggedPointerSize()
def NormalTypeCacheOffset(self):
- return self.DefaultCacheOffset() + self.heap.PointerSize()
+ return self.DefaultCacheOffset() + self.heap.TaggedPointerSize()
def __init__(self, heap, map, address):
HeapObject.__init__(self, heap, map, address)
@@ -1689,12 +1720,12 @@ class Code(HeapObject):
CODE_ALIGNMENT_MASK = (1 << 5) - 1
def InstructionSizeOffset(self):
- return self.heap.PointerSize()
+ return self.heap.TaggedPointerSize()
@staticmethod
def HeaderSize(heap):
- return (heap.PointerSize() + heap.IntSize() + \
- 4 * heap.PointerSize() + 3 * heap.IntSize() + \
+ return (heap.TaggedPointerSize() + heap.IntSize() + \
+ 4 * heap.TaggedPointerSize() + 3 * heap.IntSize() + \
Code.CODE_ALIGNMENT_MASK) & ~Code.CODE_ALIGNMENT_MASK
def __init__(self, heap, map, address):
@@ -1763,7 +1794,7 @@ class V8Heap(object):
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)
+ map_tagged_address = self.reader.ReadTagged(address)
if tagged_address == map_tagged_address:
# Meta map?
meta_map = Map(self, None, address)
@@ -1796,11 +1827,17 @@ class V8Heap(object):
def IntSize(self):
return 4
- def PointerSize(self):
- return self.reader.PointerSize()
+ def MachinePointerSize(self):
+ return self.reader.MachinePointerSize()
+
+ def TaggedPointerSize(self):
+ return self.reader.TaggedPointerSize()
+
+ def IsPointerCompressed(self):
+ return self.reader.IsPointerCompressed()
def ObjectAlignmentMask(self):
- return self.PointerSize() - 1
+ return self.TaggedPointerSize() - 1
def IsTaggedObjectAddress(self, address):
return (address & self.ObjectAlignmentMask()) == 1
@@ -1829,13 +1866,14 @@ class V8Heap(object):
return (address & self.ObjectAlignmentMask()) == 1
def IsSmi(self, tagged_address):
- if self.reader.Is64():
+ if self.reader.Is64() and not self.reader.IsPointerCompressed():
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
+ if self.reader.Is64() and not self.reader.IsPointerCompressed():
+ return tagged_address >> 32
+ return (tagged_address >> 1) & 0xFFFFFFFF
def AddressTypeMarker(self, address):
if not self.reader.IsValidAddress(address): return " "
@@ -1858,7 +1896,7 @@ class V8Heap(object):
if self.IsTaggedObjectAddress(address):
address -= 1
if not self.reader.IsValidAlignedAddress(address): return None
- offset = (address - slot) / self.PointerSize()
+ offset = (address - slot) / self.MachinePointerSize()
lower_limit = -32
upper_limit = 128
@@ -1873,12 +1911,12 @@ class V8Heap(object):
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()):
+ for slot in range(start, start + size, self.reader.TaggedPointerSize()):
if not self.reader.IsValidAddress(slot): break
# Collect only tagged pointers (object) to tagged pointers (map)
- tagged_address = self.reader.ReadUIntPtr(slot)
+ tagged_address = self.reader.ReadTagged(slot)
if not self.IsValidTaggedObjectAddress(tagged_address): continue
- map_address = self.reader.ReadUIntPtr(tagged_address - 1)
+ map_address = self.reader.ReadTagged(tagged_address - 1)
if not self.IsTaggedMapAddress(map_address): continue
objects.add(tagged_address)
@@ -1951,10 +1989,12 @@ class InspectionInfo(object):
exception_thread.stack.memory.data_size
frame_pointer = self.reader.ExceptionFP()
self.styles[frame_pointer] = "frame"
- for slot in range(stack_top, stack_bottom, self.reader.PointerSize()):
+ for slot in range(stack_top, stack_bottom,
+ self.reader.MachinePointerSize()):
# stack address
self.styles[slot] = "sa"
- for slot in range(stack_top, stack_bottom, self.reader.PointerSize()):
+ for slot in range(stack_top, stack_bottom,
+ self.reader.MachinePointerSize()):
maybe_address = self.reader.ReadUIntPtr(slot)
# stack value
self.styles[maybe_address] = "sv"
@@ -2026,7 +2066,7 @@ class InspectionPadawan(object):
# 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()
+ next_slot = slot + self.reader.MachinePointerSize()
if not self.reader.IsValidAddress(next_slot): return False
next_address = self.reader.ReadUIntPtr(next_slot)
return self.reader.IsExceptionStackAddress(next_address)
@@ -2058,7 +2098,7 @@ class InspectionPadawan(object):
if found_obj: return found_obj
address = tagged_address - 1
if self.reader.IsValidAddress(address):
- map_tagged_address = self.reader.ReadUIntPtr(address)
+ map_tagged_address = self.reader.ReadTagged(address)
map = self.SenseMap(map_tagged_address)
if map is None: return None
instance_type_name = INSTANCE_TYPES.get(map.instance_type)
@@ -2118,7 +2158,7 @@ class InspectionPadawan(object):
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()
+ ptr_size = self.reader.MachinePointerSize()
if start is None: start = self.reader.ExceptionSP()
if not self.reader.IsValidAddress(start): return start
end = start + ptr_size * 1024 * 4
@@ -2140,7 +2180,7 @@ class InspectionPadawan(object):
print_message)
def TryExtractStackTrace(self, slot, start, end, print_message):
- ptr_size = self.reader.PointerSize()
+ ptr_size = self.reader.MachinePointerSize()
assert self.reader.ReadUIntPtr(slot) & 0xFFFFFFFF == STACK_TRACE_MARKER
end_marker = STACK_TRACE_MARKER + 1;
header_size = 10
@@ -2163,7 +2203,7 @@ class InspectionPadawan(object):
return stack_start
def FindPtr(self, expected_value, start, end):
- ptr_size = self.reader.PointerSize()
+ ptr_size = self.reader.MachinePointerSize()
for slot in range(start, end, ptr_size):
if not self.reader.IsValidAddress(slot): return None
value = self.reader.ReadUIntPtr(slot)
@@ -2171,7 +2211,7 @@ class InspectionPadawan(object):
return None
def TryExtractErrorMessage(self, slot, start, end, print_message):
- ptr_size = self.reader.PointerSize()
+ ptr_size = self.reader.MachinePointerSize()
end_marker = ERROR_MESSAGE_MARKER + 1;
header_size = 1
end_search = start + 1024 + (header_size * ptr_size);
@@ -2186,7 +2226,7 @@ class InspectionPadawan(object):
def TryExtractOldStyleStackTrace(self, message_slot, start, end,
print_message):
- ptr_size = self.reader.PointerSize()
+ ptr_size = self.reader.MachinePointerSize()
if message_slot == 0:
"""
On Mac we don't always get proper magic markers, so just try printing
@@ -2225,7 +2265,7 @@ class InspectionPadawan(object):
print(" Use `dsa` to print the message with annotated addresses.")
print("")
return
- ptr_size = self.reader.PointerSize()
+ ptr_size = self.reader.MachinePointerSize()
# Annotate all addresses in the dumped message
prog = re.compile("[0-9a-fA-F]{%s}" % ptr_size*2)
addresses = list(set(prog.findall(message)))
@@ -2252,7 +2292,7 @@ class InspectionPadawan(object):
def TryInferContext(self, address):
if self.context: return
- ptr_size = self.reader.PointerSize()
+ ptr_size = self.reader.MachinePointerSize()
possible_context = dict()
count = 0
while self.reader.IsExceptionStackAddress(address):
@@ -2287,7 +2327,7 @@ class InspectionPadawan(object):
in_oom_dump_area = False
is_stack = self.reader.IsExceptionStackAddress(start)
free_space_end = 0
- ptr_size = self.reader.PointerSize()
+ ptr_size = self.reader.TaggedPointerSize()
for slot in range(start, end, ptr_size):
if not self.reader.IsValidAddress(slot):
@@ -2309,7 +2349,7 @@ class InspectionPadawan(object):
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)
+ length = self.reader.ReadTagged(slot + ptr_size)
if self.heap.IsSmi(length):
length = self.heap.SmiUntag(length)
free_space_end = slot + length - ptr_size
@@ -2711,7 +2751,8 @@ class InspectionWebFormatter(object):
stack_bottom = exception_thread.stack.start + \
exception_thread.stack.memory.data_size
stack_map = {self.reader.ExceptionIP(): -1}
- for slot in range(stack_top, stack_bottom, self.reader.PointerSize()):
+ for slot in range(stack_top, stack_bottom,
+ self.reader.MachinePointerSize()):
maybe_address = self.reader.ReadUIntPtr(slot)
if not maybe_address in stack_map:
stack_map[maybe_address] = slot
@@ -2757,6 +2798,18 @@ class InspectionWebFormatter(object):
return ("<a %s href=s?%s&amp;val=%s>%s</a>" %
(style_class, self.encfilename, straddress, straddress))
+ def format_onheap_address(self, size, maybeaddress, uncompressed):
+ if maybeaddress is None:
+ return "not in dump"
+ else:
+ straddress = "0x" + self.reader.FormatTagged(maybeaddress)
+ struncompressed = "0x" + self.reader.FormatIntPtr(uncompressed)
+ 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, struncompressed, straddress))
+
def output_header(self, f):
f.write(WEB_HEADER %
{ "query_dump" : self.encfilename,
@@ -2779,7 +2832,8 @@ class InspectionWebFormatter(object):
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")
+ self.output_words(f, stack_top - 16, stack_bottom, stack_top, "Stack",
+ self.heap.MachinePointerSize())
f.write('</div>')
self.output_footer(f)
@@ -2900,7 +2954,11 @@ class InspectionWebFormatter(object):
return
region = self.reader.FindRegion(address)
if datakind == "address":
- self.output_words(f, region[0], region[0] + region[1], address, "Dump")
+ self.output_words(f, region[0], region[0] + region[1], address, "Dump",
+ self.heap.MachinePointerSize())
+ if datakind == "tagged":
+ self.output_words(f, region[0], region[0] + region[1], address,
+ "Tagged Dump", self.heap.TaggedPointerSize())
elif datakind == "ascii":
self.output_ascii(f, region[0], region[0] + region[1], address)
self.output_footer(f)
@@ -2909,14 +2967,13 @@ class InspectionWebFormatter(object):
f.write("<h3>Unrecognized address format \"%s\".</h3>" % straddress)
return
- def output_words(self, f, start_address, end_address,
- highlight_address, desc):
+ def output_words(self, f, start_address, end_address, highlight_address, desc,
+ size):
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)
@@ -2943,6 +3000,7 @@ class InspectionWebFormatter(object):
slot = start_address + j
heap_object = ""
maybe_address = None
+ maybe_uncompressed_address = None
end_region = region[0] + region[1]
if slot < region[0] or slot + size > end_region:
straddress = "0x"
@@ -2954,10 +3012,20 @@ class InspectionWebFormatter(object):
for i in range(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)
+ maybe_address = self.reader.ReadSized(slot, size)
+ if size == self.reader.MachinePointerSize():
+ maybe_uncompressed_address = maybe_address
+ else:
+ maybe_uncompressed_address = (slot & (0xFFFFFF << 32)) | (
+ maybe_address & 0xFFFFFF)
+
+ if size == self.reader.TaggedPointerSize():
+ straddress = self.format_onheap_address(size, maybe_address,
+ maybe_uncompressed_address)
+ if maybe_address:
+ heap_object = self.format_object(maybe_address)
+ else:
+ straddress = self.format_address(maybe_address)
address_fmt = "%s&nbsp;</td>"
if slot == highlight_address:
@@ -2974,12 +3042,12 @@ class InspectionWebFormatter(object):
f.write("</td>")
self.td_from_address(f, slot)
f.write(address_fmt % self.format_address(slot))
- self.td_from_address(f, maybe_address)
+ self.td_from_address(f, maybe_uncompressed_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)
+ if maybe_uncompressed_address != None:
+ self.output_comment_box(f, "sv-" + self.reader.FormatIntPtr(slot),
+ maybe_uncompressed_address)
f.write("</td>")
f.write("<td>%s</td>" % (heap_object or ''))
f.write("</tr>")
@@ -3134,9 +3202,9 @@ class InspectionWebFormatter(object):
# Some disassemblers insert spaces between each byte,
# while some do not.
if code[2] == " ":
- op_offset = 3 * num_bytes - 1
+ op_offset = 3 * num_bytes - 1
else:
- op_offset = 2 * num_bytes
+ 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
@@ -3230,7 +3298,12 @@ class InspectionWebFormatter(object):
straddress)
else:
# Print as words
- self.output_words(f, address - 8, address + 32, address, "Dump")
+ self.output_words(f, address - 8, address + 32, address, "Dump",
+ self.heap.MachinePointerSize())
+
+ if self.heap.IsPointerCompressed():
+ self.output_words(f, address - 8, address + 32, address,
+ "Tagged Dump", self.heap.TaggedPointerSize())
# Print as ASCII
f.write("<hr>")
@@ -3534,10 +3607,10 @@ class InspectionShell(cmd.Cmd):
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()
+ self.dd_start += self.dd_num * self.reader.MachinePointerSize()
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
+ end = self.dd_start + self.reader.MachinePointerSize() * self.dd_num
self.padawan.InterpretMemory(self.dd_start, end)
def do_do(self, address):
@@ -3828,7 +3901,7 @@ def AnalyzeMinidump(options, minidump_name):
stack_top = reader.ExceptionSP()
stack_bottom = reader.StackBottom()
stack_map = {reader.ExceptionIP(): -1}
- for slot in range(stack_top, stack_bottom, reader.PointerSize()):
+ for slot in range(stack_top, stack_bottom, reader.MachinePointerSize()):
maybe_address = reader.ReadUIntPtr(slot)
if not maybe_address in stack_map:
stack_map[maybe_address] = slot