15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# Copyright 2014 The Chromium Authors. All rights reserved. 25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be 35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# found in the LICENSE file. 45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciimport posixpath 65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)from memory_inspector.core import symbol 85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class Stacktrace(object): 115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """Models a stack-trace, which is a sequence of stack |Frame|s.""" 125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def __init__(self): 14a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) self.frames = [] 155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def Add(self, frame): 175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) assert(isinstance(frame, Frame)) 18a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) self.frames += [frame] 195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) @property 215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def depth(self): 22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return len(self.frames) 235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def __getitem__(self, index): 25a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return self.frames[index] 265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def __str__(self): 28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return ', '.join([str(x) for x in self.frames]) 295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class Frame(object): 325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """Models a stack frame in a |Stacktrace|. It might be symbolized or not.""" 335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def __init__(self, address): 355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """ 365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Args: 375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) address: the absolute (virtual) address of the stack frame in the 385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) original process virtual address space. 395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """ 401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci assert(isinstance(address, (long, int))) 415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self.address = address 425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self.symbol = None 435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self.exec_file_rel_path = None 445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # Offset is the displacement inside the executable file, calculated as: 465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # self.address - mapping_address_of_the_so + mapping_offset_of_the_exec. 475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self.offset = None 485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def SetExecFileInfo(self, exec_file_rel_path, offset): 505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """Sets the base file + offset information required for symbolization. 515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Args: 535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) exec_file_rel_path: the path of the mapped executable (binary or lib) 545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) relative to the target device (e.g., /system/lib/libc.so). 555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) offset: the offset in the executable. 565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """ 571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci assert(isinstance(offset, (long, int))) 585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self.exec_file_rel_path = exec_file_rel_path 595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self.offset = offset 605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def SetSymbolInfo(self, sym): 625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """Sets the symbolization information.""" 635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) assert(isinstance(sym, symbol.Symbol)) 645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) assert(not self.symbol) 655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self.symbol = sym 665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) @property 685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def exec_file_name(self): 695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """Returns the file name (stripped of the path) of the executable.""" 701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if not self.exec_file_rel_path: 711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return None 721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return posixpath.basename(self.exec_file_rel_path.replace('\\', '/')) 735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch @property 750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch def raw_address(self): 760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if self.exec_file_rel_path: 770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return '%s +0x%x' % (self.exec_file_name, self.offset) 780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch else: 790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return '0x%x' % self.address 800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def __str__(self): 825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if self.symbol: 835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return str(self.symbol) 845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) elif self.exec_file_rel_path: 850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return self.raw_address