stacktrace.py revision 0529e5d033099cbfc42635f6f6183833b09dff6e
1# Copyright 2014 The Chromium Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5import os
6
7from memory_inspector.core import symbol
8
9
10class Stacktrace(object):
11  """Models a stack-trace, which is a sequence of stack |Frame|s."""
12
13  def __init__(self):
14    self.frames = []
15
16  def Add(self, frame):
17    assert(isinstance(frame, Frame))
18    self.frames += [frame]
19
20  @property
21  def depth(self):
22    return len(self.frames)
23
24  def __getitem__(self, index):
25    return self.frames[index]
26
27  def __str__(self):
28    return ', '.join([str(x) for x in self.frames])
29
30
31class Frame(object):
32  """Models a stack frame in a |Stacktrace|. It might be symbolized or not."""
33
34  def __init__(self, address):
35    """
36    Args:
37        address: the absolute (virtual) address of the stack frame in the
38                 original process virtual address space.
39    """
40    assert(isinstance(address, int))
41    self.address = address
42    self.symbol = None
43    self.exec_file_rel_path = None
44
45    # Offset is the displacement inside the executable file, calculated as:
46    # self.address - mapping_address_of_the_so + mapping_offset_of_the_exec.
47    self.offset = None
48
49  def SetExecFileInfo(self, exec_file_rel_path, offset):
50    """Sets the base file + offset information required for symbolization.
51
52    Args:
53        exec_file_rel_path: the path of the mapped executable (binary or lib)
54            relative to the target device (e.g., /system/lib/libc.so).
55        offset: the offset in the executable.
56    """
57    assert(isinstance(offset, int))
58    self.exec_file_rel_path = exec_file_rel_path
59    self.offset = offset
60
61  def SetSymbolInfo(self, sym):
62    """Sets the symbolization information."""
63    assert(isinstance(sym, symbol.Symbol))
64    assert(not self.symbol)
65    self.symbol = sym
66
67  @property
68  def exec_file_name(self):
69    """Returns the file name (stripped of the path) of the executable."""
70    return os.path.basename(self.exec_file_rel_path)
71
72  @property
73  def raw_address(self):
74    if self.exec_file_rel_path:
75      return '%s +0x%x' % (self.exec_file_name, self.offset)
76    else:
77      return '0x%x' % self.address
78
79  def __str__(self):
80    if self.symbol:
81      return str(self.symbol)
82    elif self.exec_file_rel_path:
83      return self.raw_address