stacktrace.py revision 1320f92c476a1ad9d19dba2a48c72b75566198e9
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 posixpath 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, (long, 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, (long, 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 if not self.exec_file_rel_path: 71 return None 72 return posixpath.basename(self.exec_file_rel_path.replace('\\', '/')) 73 74 @property 75 def raw_address(self): 76 if self.exec_file_rel_path: 77 return '%s +0x%x' % (self.exec_file_name, self.offset) 78 else: 79 return '0x%x' % self.address 80 81 def __str__(self): 82 if self.symbol: 83 return str(self.symbol) 84 elif self.exec_file_rel_path: 85 return self.raw_address