15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#!/usr/bin/python 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#---------------------------------------------------------------------- 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Be sure to add the python path that points to the LLDB shared library. 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# On MacOSX csh, tcsh: 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# setenv PYTHONPATH /Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Resources/Python 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# On MacOSX sh, bash: 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# export PYTHONPATH=/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Resources/Python 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#---------------------------------------------------------------------- 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import commands 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import optparse 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import os 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import platform 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import re 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import resource 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import sys 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import time 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import types 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#---------------------------------------------------------------------- 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Code that auto imports LLDB 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#---------------------------------------------------------------------- 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)try: 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Just try for LLDB in case PYTHONPATH is already correctly setup 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) import lldb 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)except ImportError: 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lldb_python_dirs = list() 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # lldb is not in the PYTHONPATH, try some defaults for the current platform 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) platform_system = platform.system() 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if platform_system == 'Darwin': 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # On Darwin, try the currently selected Xcode directory 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xcode_dir = commands.getoutput("xcode-select --print-path") 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if xcode_dir: 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lldb_python_dirs.append(os.path.realpath(xcode_dir + '/../SharedFrameworks/LLDB.framework/Resources/Python')) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lldb_python_dirs.append(xcode_dir + '/Library/PrivateFrameworks/LLDB.framework/Resources/Python') 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lldb_python_dirs.append('/System/Library/PrivateFrameworks/LLDB.framework/Resources/Python') 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) success = False 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for lldb_python_dir in lldb_python_dirs: 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if os.path.exists(lldb_python_dir): 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not (sys.path.__contains__(lldb_python_dir)): 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sys.path.append(lldb_python_dir) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) try: 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) import lldb 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) except ImportError: 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pass 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print 'imported lldb from: "%s"' % (lldb_python_dir) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) success = True 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not success: 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print "error: couldn't locate the 'lldb' module, please set PYTHONPATH correctly" 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sys.exit(1) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Timer: 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def __enter__(self): 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.start = time.clock() 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return self 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def __exit__(self, *args): 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.end = time.clock() 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.interval = self.end - self.start 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Action(object): 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Class that encapsulates actions to take when a thread stops for a reason.""" 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def __init__(self, callback = None, callback_owner = None): 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.callback = callback 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.callback_owner = callback_owner 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def ThreadStopped (self, thread): 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert False, "performance.Action.ThreadStopped(self, thread) must be overridden in a subclass" 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PlanCompleteAction (Action): 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def __init__(self, callback = None, callback_owner = None): 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Action.__init__(self, callback, callback_owner) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def ThreadStopped (self, thread): 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if thread.GetStopReason() == lldb.eStopReasonPlanComplete: 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if self.callback: 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if self.callback_owner: 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.callback (self.callback_owner, thread) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.callback (thread) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return True 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return False 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BreakpointAction (Action): 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def __init__(self, callback = None, callback_owner = None, name = None, module = None, file = None, line = None, breakpoint = None): 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Action.__init__(self, callback, callback_owner) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.modules = lldb.SBFileSpecList() 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.files = lldb.SBFileSpecList() 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.breakpoints = list() 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # "module" can be a list or a string 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if breakpoint: 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.breakpoints.append(breakpoint) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if module: 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if isinstance(module, types.ListType): 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for module_path in module: 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.modules.Append(lldb.SBFileSpec(module_path, False)) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) elif isinstance(module, types.StringTypes): 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.modules.Append(lldb.SBFileSpec(module, False)) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if name: 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # "file" can be a list or a string 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if file: 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if isinstance(file, types.ListType): 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.files = lldb.SBFileSpecList() 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for f in file: 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.files.Append(lldb.SBFileSpec(f, False)) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) elif isinstance(file, types.StringTypes): 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.files.Append(lldb.SBFileSpec(file, False)) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.breakpoints.append (self.target.BreakpointCreateByName(name, self.modules, self.files)) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) elif file and line: 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.breakpoints.append (self.target.BreakpointCreateByLocation(file, line)) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def ThreadStopped (self, thread): 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if thread.GetStopReason() == lldb.eStopReasonBreakpoint: 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for bp in self.breakpoints: 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if bp.GetID() == thread.GetStopReasonDataAtIndex(0): 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if self.callback: 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if self.callback_owner: 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.callback (self.callback_owner, thread) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.callback (thread) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return True 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return False 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TestCase: 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Class that aids in running performance tests.""" 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def __init__(self): 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.verbose = False 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.debugger = lldb.SBDebugger.Create() 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.target = None 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.process = None 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.thread = None 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.launch_info = None 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.done = False 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.listener = self.debugger.GetListener() 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.user_actions = list() 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.builtin_actions = list() 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.bp_id_to_dict = dict() 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def Setup(self, args): 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.launch_info = lldb.SBLaunchInfo(args) 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def Run (self, args): 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert False, "performance.TestCase.Run(self, args) must be subclassed" 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def Launch(self): 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if self.target: 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error = lldb.SBError() 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.process = self.target.Launch (self.launch_info, error) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not error.Success(): 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print "error: %s" % error.GetCString() 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if self.process: 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.process.GetBroadcaster().AddListener(self.listener, lldb.SBProcess.eBroadcastBitStateChanged | lldb.SBProcess.eBroadcastBitInterrupt) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return True 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return False 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def WaitForNextProcessEvent (self): 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event = None 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if self.process: 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while event is None: 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) process_event = lldb.SBEvent() 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if self.listener.WaitForEvent (lldb.UINT32_MAX, process_event): 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state = lldb.SBProcess.GetStateFromEvent (process_event) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if self.verbose: 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print "event = %s" % (lldb.SBDebugger.StateAsCString(state)) 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if lldb.SBProcess.GetRestartedFromEvent(process_event): 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if state == lldb.eStateInvalid or state == lldb.eStateDetached or state == lldb.eStateCrashed or state == lldb.eStateUnloaded or state == lldb.eStateExited: 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event = process_event 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.done = True 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) elif state == lldb.eStateConnected or state == lldb.eStateAttaching or state == lldb.eStateLaunching or state == lldb.eStateRunning or state == lldb.eStateStepping or state == lldb.eStateSuspended: 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) elif state == lldb.eStateStopped: 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event = process_event 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) call_test_step = True 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fatal = False 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) selected_thread = False 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for thread in self.process: 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) frame = thread.GetFrameAtIndex(0) 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) select_thread = False 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stop_reason = thread.GetStopReason() 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if self.verbose: 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print "tid = %#x pc = %#x " % (thread.GetThreadID(),frame.GetPC()), 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if stop_reason == lldb.eStopReasonNone: 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if self.verbose: 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print "none" 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) elif stop_reason == lldb.eStopReasonTrace: 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) select_thread = True 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if self.verbose: 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print "trace" 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) elif stop_reason == lldb.eStopReasonPlanComplete: 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) select_thread = True 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if self.verbose: 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print "plan complete" 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) elif stop_reason == lldb.eStopReasonThreadExiting: 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if self.verbose: 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print "thread exiting" 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) elif stop_reason == lldb.eStopReasonExec: 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if self.verbose: 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print "exec" 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) elif stop_reason == lldb.eStopReasonInvalid: 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if self.verbose: 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print "invalid" 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) elif stop_reason == lldb.eStopReasonException: 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) select_thread = True 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if self.verbose: 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print "exception" 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fatal = True 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) elif stop_reason == lldb.eStopReasonBreakpoint: 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) select_thread = True 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bp_id = thread.GetStopReasonDataAtIndex(0) 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bp_loc_id = thread.GetStopReasonDataAtIndex(1) 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if self.verbose: 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print "breakpoint id = %d.%d" % (bp_id, bp_loc_id) 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) elif stop_reason == lldb.eStopReasonWatchpoint: 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) select_thread = True 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if self.verbose: 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print "watchpoint id = %d" % (thread.GetStopReasonDataAtIndex(0)) 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) elif stop_reason == lldb.eStopReasonSignal: 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) select_thread = True 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if self.verbose: 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print "signal %d" % (thread.GetStopReasonDataAtIndex(0)) 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if select_thread and not selected_thread: 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.thread = thread 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) selected_thread = self.process.SetSelectedThread(thread) 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for action in self.user_actions: 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) action.ThreadStopped (thread) 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if fatal: 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # if self.verbose: 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Xcode.RunCommand(self.debugger,"bt all",true) 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sys.exit(1) 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return event 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Measurement: 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) '''A class that encapsulates a measurement''' 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def __init__(self): 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) object.__init__(self) 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def Measure(self): 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert False, "performance.Measurement.Measure() must be subclassed" 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MemoryMeasurement(Measurement): 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) '''A class that can measure memory statistics for a process.''' 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def __init__(self, pid): 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Measurement.__init__(self) 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.pid = pid 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.stats = ["rprvt","rshrd","rsize","vsize","vprvt","kprvt","kshrd","faults","cow","pageins"] 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.command = "top -l 1 -pid %u -stats %s" % (self.pid, ",".join(self.stats)) 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.value = dict() 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def Measure(self): 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output = commands.getoutput(self.command).split("\n")[-1] 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) values = re.split('[-+\s]+', output) 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (idx, stat) in enumerate(values): 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) multiplier = 1 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if stat: 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if stat[-1] == 'K': 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) multiplier = 1024 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stat = stat[:-1] 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) elif stat[-1] == 'M': 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) multiplier = 1024*1024 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stat = stat[:-1] 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) elif stat[-1] == 'G': 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) multiplier = 1024*1024*1024 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) elif stat[-1] == 'T': 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) multiplier = 1024*1024*1024*1024 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stat = stat[:-1] 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.value[self.stats[idx]] = int (stat) * multiplier 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def __str__(self): 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) '''Dump the MemoryMeasurement current value''' 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s = '' 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for key in self.value.keys(): 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if s: 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s += "\n" 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s += "%8s = %s" % (key, self.value[key]) 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return s 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TesterTestCase(TestCase): 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def __init__(self): 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCase.__init__(self) 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.verbose = True 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.num_steps = 5 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def BreakpointHit (self, thread): 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bp_id = thread.GetStopReasonDataAtIndex(0) 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) loc_id = thread.GetStopReasonDataAtIndex(1) 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print "Breakpoint %i.%i hit: %s" % (bp_id, loc_id, thread.process.target.FindBreakpointByID(bp_id)) 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) thread.StepOver() 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def PlanComplete (self, thread): 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if self.num_steps > 0: 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) thread.StepOver() 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.num_steps = self.num_steps - 1 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) thread.process.Kill() 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def Run (self, args): 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.Setup(args) 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) with Timer() as total_time: 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.target = self.debugger.CreateTarget(args[0]) 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if self.target: 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) with Timer() as breakpoint_timer: 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bp = self.target.BreakpointCreateByName("main") 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print('Breakpoint time = %.03f sec.' % breakpoint_timer.interval) 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.user_actions.append (BreakpointAction(breakpoint=bp, callback=TesterTestCase.BreakpointHit, callback_owner=self)) 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.user_actions.append (PlanCompleteAction(callback=TesterTestCase.PlanComplete, callback_owner=self)) 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if self.Launch(): 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while not self.done: 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.WaitForNextProcessEvent() 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print "error: failed to launch process" 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print "error: failed to create target with '%s'" % (args[0]) 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print('Total time = %.03f sec.' % total_time.interval) 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if __name__ == '__main__': 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lldb.SBDebugger.Initialize() 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test = TesterTestCase() 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test.Run (sys.argv[1:]) 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mem = MemoryMeasurement(os.getpid()) 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mem.Measure() 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print str(mem) 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lldb.SBDebugger.Terminate() 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # print "sleeeping for 100 seconds" 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # time.sleep(100) 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)