stacktrace.py revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
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  def __str__(self):
73    if self.symbol:
74      return str(self.symbol)
75    elif self.exec_file_rel_path:
76      return '%s +0x%x' % (self.exec_file_name, self.offset)
77    else:
78      return '0x%x' % self.address
79