[tools] Add support for new stack error messages and js stack traces

Change-Id: I809b10935c92a129bd633c98759ba9d800aaa91c
Reviewed-on: https://chromium-review.googlesource.com/934503
Reviewed-by: Peter Marshall <petermarshall@chromium.org>
Commit-Queue: Camillo Bruni <cbruni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#51587}
This commit is contained in:
Camillo Bruni 2018-02-23 14:28:34 +01:00 committed by Commit Bot
parent ea97a8fb32
commit 78cba2ae00

View File

@ -185,6 +185,10 @@ MAGIC_MARKER_PAIRS = (
(0xbbbbbbbb, 0xbbbbbbbb), (0xbbbbbbbb, 0xbbbbbbbb),
(0xfefefefe, 0xfefefeff), (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 # Set of structures and constants that describe the layout of minidump
# files. Based on MSDN and Google Breakpad. # files. Based on MSDN and Google Breakpad.
@ -2105,11 +2109,9 @@ class InspectionPadawan(object):
""" """
# Only look at the first 1k words on the stack # Only look at the first 1k words on the stack
ptr_size = self.reader.PointerSize() ptr_size = self.reader.PointerSize()
if start is None: if start is None: start = self.reader.ExceptionSP()
start = self.reader.ExceptionSP()
if not self.reader.IsValidAddress(start): return start if not self.reader.IsValidAddress(start): return start
end = start + ptr_size * 1024 * 4 end = start + ptr_size * 1024 * 4
message_start = 0
magic1 = None magic1 = None
for slot in xrange(start, end, ptr_size): for slot in xrange(start, end, ptr_size):
if not self.reader.IsValidAddress(slot + ptr_size): break if not self.reader.IsValidAddress(slot + ptr_size): break
@ -2117,10 +2119,64 @@ class InspectionPadawan(object):
magic2 = self.reader.ReadUIntPtr(slot + ptr_size) magic2 = self.reader.ReadUIntPtr(slot + ptr_size)
pair = (magic1 & 0xFFFFFFFF, magic2 & 0xFFFFFFFF) pair = (magic1 & 0xFFFFFFFF, magic2 & 0xFFFFFFFF)
if pair in MAGIC_MARKER_PAIRS: if pair in MAGIC_MARKER_PAIRS:
message_slot = slot + ptr_size * 4 return self.TryExtractOldStyleStackTrace(slot, start, end,
message_start = self.reader.ReadUIntPtr(message_slot) print_message)
break if pair[0] == STACK_TRACE_MARKER:
if message_start == 0: 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):
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 On Mac we don't always get proper magic markers, so just try printing
the first long ascii string found on the stack. the first long ascii string found on the stack.
@ -2130,6 +2186,7 @@ class InspectionPadawan(object):
message_start, message = self.FindFirstAsciiString(start, end, 128) message_start, message = self.FindFirstAsciiString(start, end, 128)
if message_start is None: return start if message_start is None: return start
else: else:
message_start = self.reader.ReadUIntPtr(message_slot + ptr_size * 4)
message = self.reader.ReadAsciiString(message_start) message = self.reader.ReadAsciiString(message_start)
stack_start = message_start + len(message) + 1 stack_start = message_start + len(message) + 1
# Make sure the address is word aligned # Make sure the address is word aligned
@ -2149,10 +2206,15 @@ class InspectionPadawan(object):
print " message start: %s" % self.heap.FormatIntPtr(message_start) print " message start: %s" % self.heap.FormatIntPtr(message_start)
print " stack_start: %s" % self.heap.FormatIntPtr(stack_start ) print " stack_start: %s" % self.heap.FormatIntPtr(stack_start )
print "" print ""
self.FormatStackTrace(message, print_message)
return stack_start
def FormatStackTrace(self, message, print_message):
if not print_message: if not print_message:
print " Use `dsa` to print the message with annotated addresses." print " Use `dsa` to print the message with annotated addresses."
print "" print ""
return stack_start return
ptr_size = self.reader.PointerSize()
# Annotate all addresses in the dumped message # Annotate all addresses in the dumped message
prog = re.compile("[0-9a-fA-F]{%s}" % ptr_size*2) prog = re.compile("[0-9a-fA-F]{%s}" % ptr_size*2)
addresses = list(set(prog.findall(message))) addresses = list(set(prog.findall(message)))
@ -2166,7 +2228,7 @@ class InspectionPadawan(object):
print message print message
print "="*80 print "="*80
print "" print ""
return stack_start
def TryInferFramePointer(self, slot, address): def TryInferFramePointer(self, slot, address):
""" Assume we have a framepointer if we find 4 consecutive links """ """ Assume we have a framepointer if we find 4 consecutive links """