17dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#!/usr/bin/env python
27dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#
37dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch# Copyright (C) 2013 The Android Open Source Project
47dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#
57dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch# Licensed under the Apache License, Version 2.0 (the "License");
67dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch# you may not use this file except in compliance with the License.
77dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch# You may obtain a copy of the License at
87dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#
97dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#      http://www.apache.org/licenses/LICENSE-2.0
107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#
117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch# Unless required by applicable law or agreed to in writing, software
127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch# distributed under the License is distributed on an "AS IS" BASIS,
137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch# See the License for the specific language governing permissions and
157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch# limitations under the License.
167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch"""stack symbolizes native crash dumps."""
187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochimport re
207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochimport symbol
227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochdef PrintTraceLines(trace_lines):
247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  """Print back trace."""
257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  maxlen = max(map(lambda tl: len(tl[1]), trace_lines))
267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  print
277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  print "Stack Trace:"
287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  print "  RELADDR   " + "FUNCTION".ljust(maxlen) + "  FILE:LINE"
297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  for tl in trace_lines:
307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    (addr, symbol_with_offset, location) = tl
317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    print "  %8s  %s  %s" % (addr, symbol_with_offset.ljust(maxlen), location)
327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  return
337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochdef PrintValueLines(value_lines):
367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  """Print stack data values."""
377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  maxlen = max(map(lambda tl: len(tl[2]), value_lines))
387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  print
397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  print "Stack Data:"
407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  print "  ADDR      VALUE     " + "FUNCTION".ljust(maxlen) + "  FILE:LINE"
417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  for vl in value_lines:
427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    (addr, value, symbol_with_offset, location) = vl
437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    print "  %8s  %8s  %s  %s" % (addr, value, symbol_with_offset.ljust(maxlen), location)
447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  return
457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
467dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochUNKNOWN = "<unknown>"
477dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochHEAP = "[heap]"
487dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochSTACK = "[stack]"
497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochdef PrintOutput(trace_lines, value_lines, more_info):
527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if trace_lines:
537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    PrintTraceLines(trace_lines)
547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if value_lines:
557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    # TODO(cjhopman): it seems that symbol.SymbolInformation always fails to
567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    # find information for addresses in value_lines in chrome libraries, and so
577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    # value_lines have little value to us and merely clutter the output.
587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    # Since information is sometimes contained in these lines (from system
597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    # libraries), don't completely disable them.
607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    if more_info:
617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      PrintValueLines(value_lines)
627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochdef PrintDivider():
647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  print
657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  print "-----------------------------------------------------\n"
667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochdef ConvertTrace(lines, more_info):
687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  """Convert strings containing native crash to a stack."""
697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  process_info_line = re.compile("(pid: [0-9]+, tid: [0-9]+.*)")
707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  signal_line = re.compile("(signal [0-9]+ \(.*\).*)")
717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  register_line = re.compile("(([ ]*[0-9a-z]{2} [0-9a-f]{8}){4})")
727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  thread_line = re.compile("(.*)(\-\-\- ){15}\-\-\-")
737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  dalvik_jni_thread_line = re.compile("(\".*\" prio=[0-9]+ tid=[0-9]+ NATIVE.*)")
747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  dalvik_native_thread_line = re.compile("(\".*\" sysTid=[0-9]+ nice=[0-9]+.*)")
75010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
76010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  width = "{8}"
77010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if symbol.ARCH == "arm64" or symbol.ARCH == "x86_64":
78010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    width = "{16}"
79010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
80010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  # Matches LOG(FATAL) lines, like the following example:
81010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  #   [FATAL:source_file.cc(33)] Check failed: !instances_.empty()
82010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  log_fatal_line = re.compile("(\[FATAL\:.*\].*)$")
83010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  # Note that both trace and value line matching allow for variable amounts of
857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  # whitespace (e.g. \t). This is because the we want to allow for the stack
867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  # tool to operate on AndroidFeedback provided system logs. AndroidFeedback
877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  # strips out double spaces that are found in tombsone files and logcat output.
887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  #
897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  # Examples of matched trace lines include lines from tombstone files like:
907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  #   #00  pc 001cf42e  /data/data/com.my.project/lib/libmyproject.so
917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  #   #00  pc 001cf42e  /data/data/com.my.project/lib/libmyproject.so (symbol)
927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  # Or lines from AndroidFeedback crash report system logs like:
937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  #   03-25 00:51:05.520 I/DEBUG ( 65): #00 pc 001cf42e /data/data/com.my.project/lib/libmyproject.so
947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  # Please note the spacing differences.
95010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  trace_line = re.compile("(.*)\#(?P<frame>[0-9]+)[ \t]+(..)[ \t]+(0x)?(?P<address>[0-9a-f]{0,16})[ \t]+(?P<lib>[^\r\n \t]*)(?P<symbol_present> \((?P<symbol_name>.*)\))?")  # pylint: disable-msg=C6310
96010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
97010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  # Matches lines emitted by src/base/debug/stack_trace_android.cc, like:
98010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  #   #00 0x7324d92d /data/app-lib/org.chromium.native_test-1/libbase.cr.so+0x0006992d
99010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  # This pattern includes the unused named capture groups <symbol_present> and
100010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  # <symbol_name> so that it can interoperate with the |trace_line| regex.
101010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  debug_trace_line = re.compile(
102010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      '(.*)(?P<frame>\#[0-9]+ 0x[0-9a-f]' + width + ') '
103010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      '(?P<lib>[^+]+)\+0x(?P<address>[0-9a-f]' + width + ')'
104010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      '(?P<symbol_present>)(?P<symbol_name>)')
105010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
1067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  # Examples of matched value lines include:
1077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  #   bea4170c  8018e4e9  /data/data/com.my.project/lib/libmyproject.so
1087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  #   bea4170c  8018e4e9  /data/data/com.my.project/lib/libmyproject.so (symbol)
1097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  #   03-25 00:51:05.530 I/DEBUG ( 65): bea4170c 8018e4e9 /data/data/com.my.project/lib/libmyproject.so
1107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  # Again, note the spacing differences.
111010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  value_line = re.compile("(.*)([0-9a-f]" + width + ")[ \t]+([0-9a-f]" + width + ")[ \t]+([^\r\n \t]*)( \((.*)\))?")
1127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  # Lines from 'code around' sections of the output will be matched before
1137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  # value lines because otheriwse the 'code around' sections will be confused as
1147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  # value lines.
1157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  #
1167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  # Examples include:
1177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  #   801cf40c ffffc4cc 00b2f2c5 00b2f1c7 00c1e1a8
1187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  #   03-25 00:51:05.530 I/DEBUG ( 65): 801cf40c ffffc4cc 00b2f2c5 00b2f1c7 00c1e1a8
119010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  code_line = re.compile("(.*)[ \t]*[a-f0-9]" + width +
120010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                         "[ \t]*[a-f0-9]" + width +
121010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                         "[ \t]*[a-f0-9]" + width +
122010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                         "[ \t]*[a-f0-9]" + width +
123010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                         "[ \t]*[a-f0-9]" + width +
124010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                         "[ \t]*[ \r\n]")  # pylint: disable-msg=C6310
1257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  trace_lines = []
1277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  value_lines = []
1287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  last_frame = -1
1297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  # It is faster to get symbol information with a single call rather than with
1317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  # separate calls for each line. Since symbol.SymbolInformation caches results,
1327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  # we can extract all the addresses that we will want symbol information for
1337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  # from the log and call symbol.SymbolInformation so that the results are
1347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  # cached in the following lookups.
1357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  code_addresses = {}
1367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  for ln in lines:
1377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    line = unicode(ln, errors='ignore')
1387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    lib, address = None, None
1397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
140010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    match = trace_line.match(line) or debug_trace_line.match(line)
1417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    if match:
1427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      address, lib = match.group('address', 'lib')
1437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    match = value_line.match(line)
1457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    if match and not code_line.match(line):
1467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      (_0, _1, address, lib, _2, _3) = match.groups()
1477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    if lib:
1497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      code_addresses.setdefault(lib, set()).add(address)
1507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  for lib in code_addresses:
1527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    symbol.SymbolInformationForSet(
1537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        symbol.TranslateLibPath(lib), code_addresses[lib], more_info)
1547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  for ln in lines:
1567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    # AndroidFeedback adds zero width spaces into its crash reports. These
1577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    # should be removed or the regular expresssions will fail to match.
1587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    line = unicode(ln, errors='ignore')
1597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    process_header = process_info_line.search(line)
1607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    signal_header = signal_line.search(line)
1617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    register_header = register_line.search(line)
1627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    thread_header = thread_line.search(line)
1637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    dalvik_jni_thread_header = dalvik_jni_thread_line.search(line)
1647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    dalvik_native_thread_header = dalvik_native_thread_line.search(line)
165010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    log_fatal_header = log_fatal_line.search(line)
166010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    if (process_header or signal_header or register_header or thread_header or
167010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        dalvik_jni_thread_header or dalvik_native_thread_header or
168010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        log_fatal_header) :
1697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      if trace_lines or value_lines:
1707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        PrintOutput(trace_lines, value_lines, more_info)
1717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        PrintDivider()
1727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        trace_lines = []
1737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        value_lines = []
1747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        last_frame = -1
1757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      if process_header:
1767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        print process_header.group(1)
1777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      if signal_header:
1787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        print signal_header.group(1)
1797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      if register_header:
1807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        print register_header.group(1)
1817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      if thread_header:
1827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        print thread_header.group(1)
1837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      if dalvik_jni_thread_header:
1847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        print dalvik_jni_thread_header.group(1)
1857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      if dalvik_native_thread_header:
1867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        print dalvik_native_thread_header.group(1)
187010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      if log_fatal_header:
188010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        print log_fatal_header.group(1)
1897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      continue
190010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
191010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    match = trace_line.match(line) or debug_trace_line.match(line)
192010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    if match:
1937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      frame, code_addr, area, symbol_present, symbol_name = match.group(
1947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          'frame', 'address', 'lib', 'symbol_present', 'symbol_name')
1957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      if frame <= last_frame and (trace_lines or value_lines):
1977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        PrintOutput(trace_lines, value_lines, more_info)
1987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        PrintDivider()
1997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        trace_lines = []
2007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        value_lines = []
2017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      last_frame = frame
2027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      if area == UNKNOWN or area == HEAP or area == STACK:
2047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        trace_lines.append((code_addr, "", area))
2057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      else:
2067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        # If a calls b which further calls c and c is inlined to b, we want to
2077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        # display "a -> b -> c" in the stack trace instead of just "a -> c"
2087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        info = symbol.SymbolInformation(area, code_addr, more_info)
2097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        nest_count = len(info) - 1
2107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        for (source_symbol, source_location, object_symbol_with_offset) in info:
2117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          if not source_symbol:
2127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            if symbol_present:
2137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch              source_symbol = symbol.CallCppFilt(symbol_name)
2147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            else:
2157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch              source_symbol = UNKNOWN
2167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          if not source_location:
2177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            source_location = area
2187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          if nest_count > 0:
2197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            nest_count = nest_count - 1
2207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            trace_lines.append(("v------>", source_symbol, source_location))
2217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          else:
2227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            if not object_symbol_with_offset:
2237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch              object_symbol_with_offset = source_symbol
2247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            trace_lines.append((code_addr,
2257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                object_symbol_with_offset,
2267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                source_location))
2277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    if code_line.match(line):
2287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      # Code lines should be ignored. If this were exluded the 'code around'
2297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      # sections would trigger value_line matches.
2307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      continue;
231010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    match = value_line.match(line)
232010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    if match:
2337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      (unused_, addr, value, area, symbol_present, symbol_name) = match.groups()
2347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      if area == UNKNOWN or area == HEAP or area == STACK or not area:
2357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        value_lines.append((addr, value, "", area))
2367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      else:
2377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        info = symbol.SymbolInformation(area, value, more_info)
2387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        (source_symbol, source_location, object_symbol_with_offset) = info.pop()
2397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        if not source_symbol:
2407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          if symbol_present:
2417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            source_symbol = symbol.CallCppFilt(symbol_name)
2427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          else:
2437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            source_symbol = UNKNOWN
2447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        if not source_location:
2457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          source_location = area
2467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        if not object_symbol_with_offset:
2477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          object_symbol_with_offset = source_symbol
2487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        value_lines.append((addr,
2497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                            value,
2507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                            object_symbol_with_offset,
2517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                            source_location))
2527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  PrintOutput(trace_lines, value_lines, more_info)
254