lldbutil.py revision bdc36bd05d156143d9f2e568a1aa1b5253bbe1f1
11605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen""" 2b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny ChenThis LLDB module contains miscellaneous utilities. 31605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen""" 41605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen 51605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chenimport lldb 60bfa859ea49d27efd89d5f152b8371b39919d92dJohnny Chenimport os, sys 7ed5f04ef51b18d6bedbc8589fa06544491977b9cJohnny Chenimport StringIO 81605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen 90bfa859ea49d27efd89d5f152b8371b39919d92dJohnny Chendef is_exe(fpath): 100bfa859ea49d27efd89d5f152b8371b39919d92dJohnny Chen return os.path.isfile(fpath) and os.access(fpath, os.X_OK) 110bfa859ea49d27efd89d5f152b8371b39919d92dJohnny Chen 120bfa859ea49d27efd89d5f152b8371b39919d92dJohnny Chendef which(program): 130b4dfac85ae7fc774fb7dc8b820daa0a89ad8281Johnny Chen """Find the full path to a program, or return None.""" 140bfa859ea49d27efd89d5f152b8371b39919d92dJohnny Chen fpath, fname = os.path.split(program) 150bfa859ea49d27efd89d5f152b8371b39919d92dJohnny Chen if fpath: 160bfa859ea49d27efd89d5f152b8371b39919d92dJohnny Chen if is_exe(program): 170bfa859ea49d27efd89d5f152b8371b39919d92dJohnny Chen return program 180bfa859ea49d27efd89d5f152b8371b39919d92dJohnny Chen else: 190bfa859ea49d27efd89d5f152b8371b39919d92dJohnny Chen for path in os.environ["PATH"].split(os.pathsep): 200bfa859ea49d27efd89d5f152b8371b39919d92dJohnny Chen exe_file = os.path.join(path, program) 210bfa859ea49d27efd89d5f152b8371b39919d92dJohnny Chen if is_exe(exe_file): 220bfa859ea49d27efd89d5f152b8371b39919d92dJohnny Chen return exe_file 230bfa859ea49d27efd89d5f152b8371b39919d92dJohnny Chen return None 240bfa859ea49d27efd89d5f152b8371b39919d92dJohnny Chen 2577356a0e9bec77c6ed7eb23151bcd8de27fef902Johnny Chen# =========================================== 2677356a0e9bec77c6ed7eb23151bcd8de27fef902Johnny Chen# Iterator for lldb aggregate data structures 2777356a0e9bec77c6ed7eb23151bcd8de27fef902Johnny Chen# =========================================== 2877356a0e9bec77c6ed7eb23151bcd8de27fef902Johnny Chen 2977356a0e9bec77c6ed7eb23151bcd8de27fef902Johnny Chendef lldb_iter(obj, getsize, getelem): 3077356a0e9bec77c6ed7eb23151bcd8de27fef902Johnny Chen """A generator adaptor for lldb aggregate data structures. 3177356a0e9bec77c6ed7eb23151bcd8de27fef902Johnny Chen 3277356a0e9bec77c6ed7eb23151bcd8de27fef902Johnny Chen API clients pass in an aggregate object or a container of it, the name of 3377356a0e9bec77c6ed7eb23151bcd8de27fef902Johnny Chen the method to get the size of the aggregate, and the name of the method to 3477356a0e9bec77c6ed7eb23151bcd8de27fef902Johnny Chen get the element by index. 3577356a0e9bec77c6ed7eb23151bcd8de27fef902Johnny Chen 3677356a0e9bec77c6ed7eb23151bcd8de27fef902Johnny Chen Example usages: 3777356a0e9bec77c6ed7eb23151bcd8de27fef902Johnny Chen 3877356a0e9bec77c6ed7eb23151bcd8de27fef902Johnny Chen 1. Pass an aggregate as the first argument: 3977356a0e9bec77c6ed7eb23151bcd8de27fef902Johnny Chen 4077356a0e9bec77c6ed7eb23151bcd8de27fef902Johnny Chen def disassemble_instructions (insts): 4177356a0e9bec77c6ed7eb23151bcd8de27fef902Johnny Chen from lldbutil import lldb_iter 4277356a0e9bec77c6ed7eb23151bcd8de27fef902Johnny Chen for i in lldb_iter(insts, 'GetSize', 'GetInstructionAtIndex'): 4377356a0e9bec77c6ed7eb23151bcd8de27fef902Johnny Chen print i 4477356a0e9bec77c6ed7eb23151bcd8de27fef902Johnny Chen 4577356a0e9bec77c6ed7eb23151bcd8de27fef902Johnny Chen 2. Pass a container of aggregate which provides APIs to get to the size and 4677356a0e9bec77c6ed7eb23151bcd8de27fef902Johnny Chen the element of the aggregate: 4777356a0e9bec77c6ed7eb23151bcd8de27fef902Johnny Chen 4877356a0e9bec77c6ed7eb23151bcd8de27fef902Johnny Chen # Module is a container of symbol table 4977356a0e9bec77c6ed7eb23151bcd8de27fef902Johnny Chen module = target.FindModule(filespec) 5077356a0e9bec77c6ed7eb23151bcd8de27fef902Johnny Chen for symbol in lldb_iter(module, 'GetNumSymbols', 'GetSymbolAtIndex'): 5177356a0e9bec77c6ed7eb23151bcd8de27fef902Johnny Chen name = symbol.GetName() 5277356a0e9bec77c6ed7eb23151bcd8de27fef902Johnny Chen ... 5377356a0e9bec77c6ed7eb23151bcd8de27fef902Johnny Chen """ 5477356a0e9bec77c6ed7eb23151bcd8de27fef902Johnny Chen size = getattr(obj, getsize) 5577356a0e9bec77c6ed7eb23151bcd8de27fef902Johnny Chen elem = getattr(obj, getelem) 5677356a0e9bec77c6ed7eb23151bcd8de27fef902Johnny Chen for i in range(size()): 5777356a0e9bec77c6ed7eb23151bcd8de27fef902Johnny Chen yield elem(i) 5877356a0e9bec77c6ed7eb23151bcd8de27fef902Johnny Chen 5977356a0e9bec77c6ed7eb23151bcd8de27fef902Johnny Chen 6051ed1b614f2c2b6970f50296d7d41c9de2c30ff4Johnny Chen# =================================================== 6151ed1b614f2c2b6970f50296d7d41c9de2c30ff4Johnny Chen# Disassembly for an SBFunction or an SBSymbol object 6251ed1b614f2c2b6970f50296d7d41c9de2c30ff4Johnny Chen# =================================================== 6351ed1b614f2c2b6970f50296d7d41c9de2c30ff4Johnny Chen 6451ed1b614f2c2b6970f50296d7d41c9de2c30ff4Johnny Chendef disassemble(target, function_or_symbol): 6551ed1b614f2c2b6970f50296d7d41c9de2c30ff4Johnny Chen """Disassemble the function or symbol given a target. 6651ed1b614f2c2b6970f50296d7d41c9de2c30ff4Johnny Chen 6751ed1b614f2c2b6970f50296d7d41c9de2c30ff4Johnny Chen It returns the disassembly content in a string object. 6851ed1b614f2c2b6970f50296d7d41c9de2c30ff4Johnny Chen """ 6951ed1b614f2c2b6970f50296d7d41c9de2c30ff4Johnny Chen buf = StringIO.StringIO() 7051ed1b614f2c2b6970f50296d7d41c9de2c30ff4Johnny Chen insts = function_or_symbol.GetInstructions(target) 7151ed1b614f2c2b6970f50296d7d41c9de2c30ff4Johnny Chen for i in lldb_iter(insts, 'GetSize', 'GetInstructionAtIndex'): 7251ed1b614f2c2b6970f50296d7d41c9de2c30ff4Johnny Chen print >> buf, i 7351ed1b614f2c2b6970f50296d7d41c9de2c30ff4Johnny Chen return buf.getvalue() 7451ed1b614f2c2b6970f50296d7d41c9de2c30ff4Johnny Chen 7551ed1b614f2c2b6970f50296d7d41c9de2c30ff4Johnny Chen 764c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen# ========================================================== 774c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen# Integer (byte size 1, 2, 4, and 8) to bytearray conversion 784c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen# ========================================================== 794c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen 804c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chendef int_to_bytearray(val, bytesize): 814c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen """Utility function to convert an integer into a bytearray. 824c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen 83d2765fc8b9c9bd4d98dd5d6176b6108b6516e04cJohnny Chen It returns the bytearray in the little endian format. It is easy to get the 84d2765fc8b9c9bd4d98dd5d6176b6108b6516e04cJohnny Chen big endian format, just do ba.reverse() on the returned object. 854c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen """ 86f4c0d1d8854f3ed87ca797628008386fdb9318afJohnny Chen import struct 874c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen 884c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen if bytesize == 1: 894c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen return bytearray([val]) 904c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen 914c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen # Little endian followed by a format character. 924c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen template = "<%c" 934c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen if bytesize == 2: 944c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen fmt = template % 'h' 954c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen elif bytesize == 4: 964c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen fmt = template % 'i' 974c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen elif bytesize == 4: 984c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen fmt = template % 'q' 994c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen else: 1004c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen return None 1014c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen 102f4c0d1d8854f3ed87ca797628008386fdb9318afJohnny Chen packed = struct.pack(fmt, val) 1034c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen return bytearray(map(ord, packed)) 1044c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen 1054c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chendef bytearray_to_int(bytes, bytesize): 1064c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen """Utility function to convert a bytearray into an integer. 1074c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen 108d2765fc8b9c9bd4d98dd5d6176b6108b6516e04cJohnny Chen It interprets the bytearray in the little endian format. For a big endian 109d2765fc8b9c9bd4d98dd5d6176b6108b6516e04cJohnny Chen bytearray, just do ba.reverse() on the object before passing it in. 1104c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen """ 111f4c0d1d8854f3ed87ca797628008386fdb9318afJohnny Chen import struct 1124c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen 1134c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen if bytesize == 1: 1144c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen return ba[0] 1154c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen 1164c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen # Little endian followed by a format character. 1174c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen template = "<%c" 1184c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen if bytesize == 2: 1194c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen fmt = template % 'h' 1204c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen elif bytesize == 4: 1214c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen fmt = template % 'i' 1224c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen elif bytesize == 4: 1234c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen fmt = template % 'q' 1244c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen else: 1254c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen return None 1264c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen 127f4c0d1d8854f3ed87ca797628008386fdb9318afJohnny Chen unpacked = struct.unpack(fmt, str(bytes)) 1284c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen return unpacked[0] 1294c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen 1304c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen 13177356a0e9bec77c6ed7eb23151bcd8de27fef902Johnny Chen# =========================================================== 13277356a0e9bec77c6ed7eb23151bcd8de27fef902Johnny Chen# Returns the list of stopped thread(s) given an lldb process 13377356a0e9bec77c6ed7eb23151bcd8de27fef902Johnny Chen# =========================================================== 13484a6d6f10f3010accf9b717b2995f9acb6bee60cJohnny Chen 13577356a0e9bec77c6ed7eb23151bcd8de27fef902Johnny Chendef get_stopped_threads(process, reason): 13677356a0e9bec77c6ed7eb23151bcd8de27fef902Johnny Chen """Returns the thread(s) with the specified stop reason in a list.""" 13777356a0e9bec77c6ed7eb23151bcd8de27fef902Johnny Chen threads = [] 13877356a0e9bec77c6ed7eb23151bcd8de27fef902Johnny Chen for t in lldb_iter(process, 'GetNumThreads', 'GetThreadAtIndex'): 13977356a0e9bec77c6ed7eb23151bcd8de27fef902Johnny Chen if t.GetStopReason() == reason: 14077356a0e9bec77c6ed7eb23151bcd8de27fef902Johnny Chen threads.append(t) 14177356a0e9bec77c6ed7eb23151bcd8de27fef902Johnny Chen return threads 142deaf884abce0117add8ed0e83491c10eeb8bf220Johnny Chen 14377356a0e9bec77c6ed7eb23151bcd8de27fef902Johnny Chendef get_stopped_thread(process, reason): 14477356a0e9bec77c6ed7eb23151bcd8de27fef902Johnny Chen """A convenience function which returns the first thread with the given stop 14577356a0e9bec77c6ed7eb23151bcd8de27fef902Johnny Chen reason or None. 146164bf887534ab18c939dc46525efb3db9de2613dJohnny Chen 147deaf884abce0117add8ed0e83491c10eeb8bf220Johnny Chen Example usages: 148164bf887534ab18c939dc46525efb3db9de2613dJohnny Chen 14977356a0e9bec77c6ed7eb23151bcd8de27fef902Johnny Chen 1. Get the stopped thread due to a breakpoint condition 150164bf887534ab18c939dc46525efb3db9de2613dJohnny Chen 15177356a0e9bec77c6ed7eb23151bcd8de27fef902Johnny Chen ... 15277356a0e9bec77c6ed7eb23151bcd8de27fef902Johnny Chen from lldbutil import get_stopped_thread 15377356a0e9bec77c6ed7eb23151bcd8de27fef902Johnny Chen thread = get_stopped_thread(self.process, lldb.eStopReasonPlanComplete) 15477356a0e9bec77c6ed7eb23151bcd8de27fef902Johnny Chen self.assertTrue(thread != None, "There should be a thread stopped due to breakpoint condition") 15577356a0e9bec77c6ed7eb23151bcd8de27fef902Johnny Chen ... 156deaf884abce0117add8ed0e83491c10eeb8bf220Johnny Chen 15777356a0e9bec77c6ed7eb23151bcd8de27fef902Johnny Chen 2. Get the thread stopped due to a breakpoint 158deaf884abce0117add8ed0e83491c10eeb8bf220Johnny Chen 15977356a0e9bec77c6ed7eb23151bcd8de27fef902Johnny Chen ... 16077356a0e9bec77c6ed7eb23151bcd8de27fef902Johnny Chen from lldbutil import get_stopped_thread 16177356a0e9bec77c6ed7eb23151bcd8de27fef902Johnny Chen thread = get_stopped_thread(self.process, lldb.eStopReasonBreakpoint) 16277356a0e9bec77c6ed7eb23151bcd8de27fef902Johnny Chen self.assertTrue(thread != None, "There should be a thread stopped due to breakpoint") 16377356a0e9bec77c6ed7eb23151bcd8de27fef902Johnny Chen ... 164164bf887534ab18c939dc46525efb3db9de2613dJohnny Chen 16577356a0e9bec77c6ed7eb23151bcd8de27fef902Johnny Chen """ 16677356a0e9bec77c6ed7eb23151bcd8de27fef902Johnny Chen threads = get_stopped_threads(process, reason) 16777356a0e9bec77c6ed7eb23151bcd8de27fef902Johnny Chen if len(threads) == 0: 16877356a0e9bec77c6ed7eb23151bcd8de27fef902Johnny Chen return None 16977356a0e9bec77c6ed7eb23151bcd8de27fef902Johnny Chen return threads[0] 170164bf887534ab18c939dc46525efb3db9de2613dJohnny Chen 171bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen# ============================================================== 172bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen# Get the description of an lldb object or None if not available 173bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen# ============================================================== 174bdc36bd05d156143d9f2e568a1aa1b5253bbe1f1Johnny Chendef get_description(obj, option=None): 175bdc36bd05d156143d9f2e568a1aa1b5253bbe1f1Johnny Chen """Calls lldb_obj.GetDescription() and returns a string, or None. 176bdc36bd05d156143d9f2e568a1aa1b5253bbe1f1Johnny Chen 177bdc36bd05d156143d9f2e568a1aa1b5253bbe1f1Johnny Chen For SBTarget and SBBreakpointLocation lldb objects, an extra option can be 178bdc36bd05d156143d9f2e568a1aa1b5253bbe1f1Johnny Chen passed in to describe the detailed level of description desired: 179bdc36bd05d156143d9f2e568a1aa1b5253bbe1f1Johnny Chen o lldb.eDescriptionLevelBrief 180bdc36bd05d156143d9f2e568a1aa1b5253bbe1f1Johnny Chen o lldb.eDescriptionLevelFull 181bdc36bd05d156143d9f2e568a1aa1b5253bbe1f1Johnny Chen o lldb.eDescriptionLevelVerbose 182bdc36bd05d156143d9f2e568a1aa1b5253bbe1f1Johnny Chen """ 183bdc36bd05d156143d9f2e568a1aa1b5253bbe1f1Johnny Chen method = getattr(obj, 'GetDescription') 184bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen if not method: 185bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen return None 186bdc36bd05d156143d9f2e568a1aa1b5253bbe1f1Johnny Chen if isinstance(obj, lldb.SBTarget) or isinstance(obj, lldb.SBBreakpointLocation): 187bdc36bd05d156143d9f2e568a1aa1b5253bbe1f1Johnny Chen if option is None: 188bdc36bd05d156143d9f2e568a1aa1b5253bbe1f1Johnny Chen option = lldb.eDescriptionLevelBrief 189bdc36bd05d156143d9f2e568a1aa1b5253bbe1f1Johnny Chen 190bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen stream = lldb.SBStream() 191bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen if option is None: 192bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen success = method(stream) 193bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen else: 194bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen success = method(stream, option) 195bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen if not success: 196bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen return None 197bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen return stream.GetData() 198bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen 199bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen 200168a61a9d1551d407240395942dc9e005c47ba30Johnny Chen# ================================================= 201168a61a9d1551d407240395942dc9e005c47ba30Johnny Chen# Convert some enum value to its string counterpart 202168a61a9d1551d407240395942dc9e005c47ba30Johnny Chen# ================================================= 203be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen 204be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chendef StateTypeString(enum): 205be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen """Returns the stateType string given an enum.""" 206be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen if enum == lldb.eStateInvalid: 20759b8477b020651df9b215396864e2e161a007d8cJohnny Chen return "invalid" 208be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen elif enum == lldb.eStateUnloaded: 20959b8477b020651df9b215396864e2e161a007d8cJohnny Chen return "unloaded" 21042da4dae5d7dccf98a57399d4689150b928ab545Johnny Chen elif enum == lldb.eStateConnected: 21142da4dae5d7dccf98a57399d4689150b928ab545Johnny Chen return "connected" 212be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen elif enum == lldb.eStateAttaching: 21359b8477b020651df9b215396864e2e161a007d8cJohnny Chen return "attaching" 214be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen elif enum == lldb.eStateLaunching: 21559b8477b020651df9b215396864e2e161a007d8cJohnny Chen return "launching" 216be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen elif enum == lldb.eStateStopped: 21759b8477b020651df9b215396864e2e161a007d8cJohnny Chen return "stopped" 218be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen elif enum == lldb.eStateRunning: 21959b8477b020651df9b215396864e2e161a007d8cJohnny Chen return "running" 220be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen elif enum == lldb.eStateStepping: 22159b8477b020651df9b215396864e2e161a007d8cJohnny Chen return "stepping" 222be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen elif enum == lldb.eStateCrashed: 22359b8477b020651df9b215396864e2e161a007d8cJohnny Chen return "crashed" 224be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen elif enum == lldb.eStateDetached: 22559b8477b020651df9b215396864e2e161a007d8cJohnny Chen return "detached" 226be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen elif enum == lldb.eStateExited: 22759b8477b020651df9b215396864e2e161a007d8cJohnny Chen return "exited" 228be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen elif enum == lldb.eStateSuspended: 22959b8477b020651df9b215396864e2e161a007d8cJohnny Chen return "suspended" 230be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen else: 23142da4dae5d7dccf98a57399d4689150b928ab545Johnny Chen raise Exception("Unknown StateType enum") 232be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen 233be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chendef StopReasonString(enum): 234be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen """Returns the stopReason string given an enum.""" 235be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen if enum == lldb.eStopReasonInvalid: 23659b8477b020651df9b215396864e2e161a007d8cJohnny Chen return "invalid" 237be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen elif enum == lldb.eStopReasonNone: 23859b8477b020651df9b215396864e2e161a007d8cJohnny Chen return "none" 239be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen elif enum == lldb.eStopReasonTrace: 24059b8477b020651df9b215396864e2e161a007d8cJohnny Chen return "trace" 241be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen elif enum == lldb.eStopReasonBreakpoint: 24259b8477b020651df9b215396864e2e161a007d8cJohnny Chen return "breakpoint" 243be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen elif enum == lldb.eStopReasonWatchpoint: 24459b8477b020651df9b215396864e2e161a007d8cJohnny Chen return "watchpoint" 245be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen elif enum == lldb.eStopReasonSignal: 24659b8477b020651df9b215396864e2e161a007d8cJohnny Chen return "signal" 247be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen elif enum == lldb.eStopReasonException: 24859b8477b020651df9b215396864e2e161a007d8cJohnny Chen return "exception" 249be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen elif enum == lldb.eStopReasonPlanComplete: 25059b8477b020651df9b215396864e2e161a007d8cJohnny Chen return "plancomplete" 251be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen else: 25242da4dae5d7dccf98a57399d4689150b928ab545Johnny Chen raise Exception("Unknown StopReason enum") 253be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen 2542c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chendef ValueTypeString(enum): 2552c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen """Returns the valueType string given an enum.""" 2562c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen if enum == lldb.eValueTypeInvalid: 2572c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen return "invalid" 2582c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen elif enum == lldb.eValueTypeVariableGlobal: 2592c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen return "global_variable" 2602c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen elif enum == lldb.eValueTypeVariableStatic: 2612c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen return "static_variable" 2622c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen elif enum == lldb.eValueTypeVariableArgument: 2632c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen return "argument_variable" 2642c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen elif enum == lldb.eValueTypeVariableLocal: 2652c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen return "local_variable" 2662c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen elif enum == lldb.eValueTypeRegister: 2672c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen return "register" 2682c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen elif enum == lldb.eValueTypeRegisterSet: 2692c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen return "register_set" 2702c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen elif enum == lldb.eValueTypeConstResult: 2712c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen return "constant_result" 2722c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen else: 27342da4dae5d7dccf98a57399d4689150b928ab545Johnny Chen raise Exception("Unknown ValueType enum") 2742c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen 275be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen 276168a61a9d1551d407240395942dc9e005c47ba30Johnny Chen# ================================================== 277168a61a9d1551d407240395942dc9e005c47ba30Johnny Chen# Utility functions related to Threads and Processes 278168a61a9d1551d407240395942dc9e005c47ba30Johnny Chen# ================================================== 279be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen 28069af39d7e7c1988caf027956a6af5f17c55b5534Johnny Chendef get_caller_symbol(thread): 28169af39d7e7c1988caf027956a6af5f17c55b5534Johnny Chen """ 28269af39d7e7c1988caf027956a6af5f17c55b5534Johnny Chen Returns the symbol name for the call site of the leaf function. 28369af39d7e7c1988caf027956a6af5f17c55b5534Johnny Chen """ 28469af39d7e7c1988caf027956a6af5f17c55b5534Johnny Chen depth = thread.GetNumFrames() 28569af39d7e7c1988caf027956a6af5f17c55b5534Johnny Chen if depth <= 1: 28669af39d7e7c1988caf027956a6af5f17c55b5534Johnny Chen return None 28769af39d7e7c1988caf027956a6af5f17c55b5534Johnny Chen caller = thread.GetFrameAtIndex(1).GetSymbol() 28869af39d7e7c1988caf027956a6af5f17c55b5534Johnny Chen if caller: 28969af39d7e7c1988caf027956a6af5f17c55b5534Johnny Chen return caller.GetName() 29069af39d7e7c1988caf027956a6af5f17c55b5534Johnny Chen else: 29169af39d7e7c1988caf027956a6af5f17c55b5534Johnny Chen return None 29269af39d7e7c1988caf027956a6af5f17c55b5534Johnny Chen 29369af39d7e7c1988caf027956a6af5f17c55b5534Johnny Chen 2941605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chendef GetFunctionNames(thread): 2951605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen """ 2961605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen Returns a sequence of function names from the stack frames of this thread. 2971605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen """ 2981605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen def GetFuncName(i): 2991605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen return thread.GetFrameAtIndex(i).GetFunction().GetName() 3001605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen 3011605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen return map(GetFuncName, range(thread.GetNumFrames())) 3021605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen 3031605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen 304b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chendef GetSymbolNames(thread): 305b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen """ 306b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen Returns a sequence of symbols for this thread. 307b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen """ 308b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen def GetSymbol(i): 309b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen return thread.GetFrameAtIndex(i).GetSymbol().GetName() 310b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen 311b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen return map(GetSymbol, range(thread.GetNumFrames())) 312b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen 313b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen 314b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chendef GetPCAddresses(thread): 315b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen """ 316b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen Returns a sequence of pc addresses for this thread. 317b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen """ 318b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen def GetPCAddress(i): 319b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen return thread.GetFrameAtIndex(i).GetPCAddress() 320b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen 321b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen return map(GetPCAddress, range(thread.GetNumFrames())) 322b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen 323b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen 3241605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chendef GetFilenames(thread): 3251605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen """ 3261605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen Returns a sequence of file names from the stack frames of this thread. 3271605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen """ 3281605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen def GetFilename(i): 3291605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen return thread.GetFrameAtIndex(i).GetLineEntry().GetFileSpec().GetFilename() 3301605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen 3311605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen return map(GetFilename, range(thread.GetNumFrames())) 3321605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen 3331605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen 3341605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chendef GetLineNumbers(thread): 3351605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen """ 3361605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen Returns a sequence of line numbers from the stack frames of this thread. 3371605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen """ 3381605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen def GetLineNumber(i): 3391605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen return thread.GetFrameAtIndex(i).GetLineEntry().GetLine() 3401605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen 3411605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen return map(GetLineNumber, range(thread.GetNumFrames())) 3421605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen 3431605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen 3441605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chendef GetModuleNames(thread): 3451605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen """ 3461605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen Returns a sequence of module names from the stack frames of this thread. 3471605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen """ 3481605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen def GetModuleName(i): 3491605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen return thread.GetFrameAtIndex(i).GetModule().GetFileSpec().GetFilename() 3501605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen 3511605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen return map(GetModuleName, range(thread.GetNumFrames())) 3521605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen 3531605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen 35488866ac481cd5533c18e00233aeced2eb1fce42bJohnny Chendef GetStackFrames(thread): 35588866ac481cd5533c18e00233aeced2eb1fce42bJohnny Chen """ 35688866ac481cd5533c18e00233aeced2eb1fce42bJohnny Chen Returns a sequence of stack frames for this thread. 35788866ac481cd5533c18e00233aeced2eb1fce42bJohnny Chen """ 35888866ac481cd5533c18e00233aeced2eb1fce42bJohnny Chen def GetStackFrame(i): 35988866ac481cd5533c18e00233aeced2eb1fce42bJohnny Chen return thread.GetFrameAtIndex(i) 36088866ac481cd5533c18e00233aeced2eb1fce42bJohnny Chen 36188866ac481cd5533c18e00233aeced2eb1fce42bJohnny Chen return map(GetStackFrame, range(thread.GetNumFrames())) 36288866ac481cd5533c18e00233aeced2eb1fce42bJohnny Chen 36388866ac481cd5533c18e00233aeced2eb1fce42bJohnny Chen 36430425e9677342cff9995cd4937fdc12354b6b24bJohnny Chendef PrintStackTrace(thread, string_buffer = False): 3651605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen """Prints a simple stack trace of this thread.""" 36630425e9677342cff9995cd4937fdc12354b6b24bJohnny Chen 367ed5f04ef51b18d6bedbc8589fa06544491977b9cJohnny Chen output = StringIO.StringIO() if string_buffer else sys.stdout 368b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen target = thread.GetProcess().GetTarget() 369b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen 3701605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen depth = thread.GetNumFrames() 3711605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen 3721605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen mods = GetModuleNames(thread) 3731605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen funcs = GetFunctionNames(thread) 374b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen symbols = GetSymbolNames(thread) 3751605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen files = GetFilenames(thread) 3761605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen lines = GetLineNumbers(thread) 377b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen addrs = GetPCAddresses(thread) 37830425e9677342cff9995cd4937fdc12354b6b24bJohnny Chen 379ad5fd40cb92070593d248b8f44b9902be0bcb4bfJohnny Chen if thread.GetStopReason() != lldb.eStopReasonInvalid: 380ad5fd40cb92070593d248b8f44b9902be0bcb4bfJohnny Chen desc = "stop reason=" + StopReasonString(thread.GetStopReason()) 381ad5fd40cb92070593d248b8f44b9902be0bcb4bfJohnny Chen else: 382ad5fd40cb92070593d248b8f44b9902be0bcb4bfJohnny Chen desc = "" 383ad5fd40cb92070593d248b8f44b9902be0bcb4bfJohnny Chen print >> output, "Stack trace for thread id={0:#x} name={1} queue={2} ".format( 384ad5fd40cb92070593d248b8f44b9902be0bcb4bfJohnny Chen thread.GetThreadID(), thread.GetName(), thread.GetQueueName()) + desc 3851605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen 386b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen for i in range(depth): 387b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen frame = thread.GetFrameAtIndex(i) 388b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen function = frame.GetFunction() 389b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen 390b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen load_addr = addrs[i].GetLoadAddress(target) 391b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen if not function.IsValid(): 392b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen file_addr = addrs[i].GetFileAddress() 393b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen print >> output, " frame #{num}: {addr:#016x} {mod}`{symbol} + ????".format( 394b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen num=i, addr=load_addr, mod=mods[i], symbol=symbols[i]) 395b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen else: 396b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen print >> output, " frame #{num}: {addr:#016x} {mod}`{func} at {file}:{line}".format( 397b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen num=i, addr=load_addr, mod=mods[i], func=funcs[i], file=files[i], line=lines[i]) 398b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen 399b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen if string_buffer: 400ed5f04ef51b18d6bedbc8589fa06544491977b9cJohnny Chen return output.getvalue() 401b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen 402b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen 403b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chendef PrintStackTraces(process, string_buffer = False): 404b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen """Prints the stack traces of all the threads.""" 405b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen 406ed5f04ef51b18d6bedbc8589fa06544491977b9cJohnny Chen output = StringIO.StringIO() if string_buffer else sys.stdout 407b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen 408b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen print >> output, "Stack traces for " + repr(process) 4091605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen 410b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen for i in range(process.GetNumThreads()): 411b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen print >> output, PrintStackTrace(process.GetThreadAtIndex(i), string_buffer=True) 41230425e9677342cff9995cd4937fdc12354b6b24bJohnny Chen 41330425e9677342cff9995cd4937fdc12354b6b24bJohnny Chen if string_buffer: 414ed5f04ef51b18d6bedbc8589fa06544491977b9cJohnny Chen return output.getvalue() 415e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham 416e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Inghamdef GetThreadsStoppedAtBreakpoint (process, bkpt): 41737ac00bdbf6c1cfb4a21b50fec8b0e4ba9735cfaJohnny Chen """ For a stopped process returns the thread stopped at the breakpoint passed in bkpt""" 418e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham stopped_threads = [] 419e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham threads = [] 420e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham 421e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham stopped_threads = get_stopped_threads (process, lldb.eStopReasonBreakpoint) 422e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham 423e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham if len(stopped_threads) == 0: 424e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham return threads 425e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham 426e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham for thread in stopped_threads: 427e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham # Make sure we've hit our breakpoint... 428e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham break_id = thread.GetStopReasonDataAtIndex (0) 429e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham if break_id == bkpt.GetID(): 430e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham threads.append(thread) 431e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham 432e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham return threads 433e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham 434e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Inghamdef ContinueToBreakpoint (process, bkpt): 43537ac00bdbf6c1cfb4a21b50fec8b0e4ba9735cfaJohnny Chen """ Continues the process, if it stops, returns the threads stopped at bkpt; otherwise, returns None""" 436e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham process.Continue() 437e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham if process.GetState() != lldb.eStateStopped: 438e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham return None 439e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham else: 440e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham return GetThreadsStoppedAtBreakpoint (process, bkpt) 441e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham 442