lldbutil.py revision 318aaa0b4b593ec3e69c5962bddab10c47066c4f
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 131bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen# ============================================================== 132bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen# Get the description of an lldb object or None if not available 133bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen# ============================================================== 134bdc36bd05d156143d9f2e568a1aa1b5253bbe1f1Johnny Chendef get_description(obj, option=None): 135bdc36bd05d156143d9f2e568a1aa1b5253bbe1f1Johnny Chen """Calls lldb_obj.GetDescription() and returns a string, or None. 136bdc36bd05d156143d9f2e568a1aa1b5253bbe1f1Johnny Chen 137bdc36bd05d156143d9f2e568a1aa1b5253bbe1f1Johnny Chen For SBTarget and SBBreakpointLocation lldb objects, an extra option can be 138bdc36bd05d156143d9f2e568a1aa1b5253bbe1f1Johnny Chen passed in to describe the detailed level of description desired: 139bdc36bd05d156143d9f2e568a1aa1b5253bbe1f1Johnny Chen o lldb.eDescriptionLevelBrief 140bdc36bd05d156143d9f2e568a1aa1b5253bbe1f1Johnny Chen o lldb.eDescriptionLevelFull 141bdc36bd05d156143d9f2e568a1aa1b5253bbe1f1Johnny Chen o lldb.eDescriptionLevelVerbose 142bdc36bd05d156143d9f2e568a1aa1b5253bbe1f1Johnny Chen """ 143bdc36bd05d156143d9f2e568a1aa1b5253bbe1f1Johnny Chen method = getattr(obj, 'GetDescription') 144bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen if not method: 145bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen return None 146bdc36bd05d156143d9f2e568a1aa1b5253bbe1f1Johnny Chen if isinstance(obj, lldb.SBTarget) or isinstance(obj, lldb.SBBreakpointLocation): 147bdc36bd05d156143d9f2e568a1aa1b5253bbe1f1Johnny Chen if option is None: 148bdc36bd05d156143d9f2e568a1aa1b5253bbe1f1Johnny Chen option = lldb.eDescriptionLevelBrief 149bdc36bd05d156143d9f2e568a1aa1b5253bbe1f1Johnny Chen 150bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen stream = lldb.SBStream() 151bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen if option is None: 152bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen success = method(stream) 153bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen else: 154bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen success = method(stream, option) 155bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen if not success: 156bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen return None 157bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen return stream.GetData() 158bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen 159bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen 160168a61a9d1551d407240395942dc9e005c47ba30Johnny Chen# ================================================= 161168a61a9d1551d407240395942dc9e005c47ba30Johnny Chen# Convert some enum value to its string counterpart 162168a61a9d1551d407240395942dc9e005c47ba30Johnny Chen# ================================================= 163be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen 164be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chendef StateTypeString(enum): 165be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen """Returns the stateType string given an enum.""" 166be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen if enum == lldb.eStateInvalid: 16759b8477b020651df9b215396864e2e161a007d8cJohnny Chen return "invalid" 168be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen elif enum == lldb.eStateUnloaded: 16959b8477b020651df9b215396864e2e161a007d8cJohnny Chen return "unloaded" 17042da4dae5d7dccf98a57399d4689150b928ab545Johnny Chen elif enum == lldb.eStateConnected: 17142da4dae5d7dccf98a57399d4689150b928ab545Johnny Chen return "connected" 172be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen elif enum == lldb.eStateAttaching: 17359b8477b020651df9b215396864e2e161a007d8cJohnny Chen return "attaching" 174be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen elif enum == lldb.eStateLaunching: 17559b8477b020651df9b215396864e2e161a007d8cJohnny Chen return "launching" 176be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen elif enum == lldb.eStateStopped: 17759b8477b020651df9b215396864e2e161a007d8cJohnny Chen return "stopped" 178be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen elif enum == lldb.eStateRunning: 17959b8477b020651df9b215396864e2e161a007d8cJohnny Chen return "running" 180be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen elif enum == lldb.eStateStepping: 18159b8477b020651df9b215396864e2e161a007d8cJohnny Chen return "stepping" 182be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen elif enum == lldb.eStateCrashed: 18359b8477b020651df9b215396864e2e161a007d8cJohnny Chen return "crashed" 184be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen elif enum == lldb.eStateDetached: 18559b8477b020651df9b215396864e2e161a007d8cJohnny Chen return "detached" 186be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen elif enum == lldb.eStateExited: 18759b8477b020651df9b215396864e2e161a007d8cJohnny Chen return "exited" 188be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen elif enum == lldb.eStateSuspended: 18959b8477b020651df9b215396864e2e161a007d8cJohnny Chen return "suspended" 190be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen else: 19142da4dae5d7dccf98a57399d4689150b928ab545Johnny Chen raise Exception("Unknown StateType enum") 192be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen 193be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chendef StopReasonString(enum): 194be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen """Returns the stopReason string given an enum.""" 195be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen if enum == lldb.eStopReasonInvalid: 19659b8477b020651df9b215396864e2e161a007d8cJohnny Chen return "invalid" 197be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen elif enum == lldb.eStopReasonNone: 19859b8477b020651df9b215396864e2e161a007d8cJohnny Chen return "none" 199be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen elif enum == lldb.eStopReasonTrace: 20059b8477b020651df9b215396864e2e161a007d8cJohnny Chen return "trace" 201be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen elif enum == lldb.eStopReasonBreakpoint: 20259b8477b020651df9b215396864e2e161a007d8cJohnny Chen return "breakpoint" 203be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen elif enum == lldb.eStopReasonWatchpoint: 20459b8477b020651df9b215396864e2e161a007d8cJohnny Chen return "watchpoint" 205be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen elif enum == lldb.eStopReasonSignal: 20659b8477b020651df9b215396864e2e161a007d8cJohnny Chen return "signal" 207be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen elif enum == lldb.eStopReasonException: 20859b8477b020651df9b215396864e2e161a007d8cJohnny Chen return "exception" 209be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen elif enum == lldb.eStopReasonPlanComplete: 21059b8477b020651df9b215396864e2e161a007d8cJohnny Chen return "plancomplete" 211be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen else: 21242da4dae5d7dccf98a57399d4689150b928ab545Johnny Chen raise Exception("Unknown StopReason enum") 213be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen 2142c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chendef ValueTypeString(enum): 2152c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen """Returns the valueType string given an enum.""" 2162c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen if enum == lldb.eValueTypeInvalid: 2172c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen return "invalid" 2182c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen elif enum == lldb.eValueTypeVariableGlobal: 2192c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen return "global_variable" 2202c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen elif enum == lldb.eValueTypeVariableStatic: 2212c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen return "static_variable" 2222c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen elif enum == lldb.eValueTypeVariableArgument: 2232c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen return "argument_variable" 2242c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen elif enum == lldb.eValueTypeVariableLocal: 2252c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen return "local_variable" 2262c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen elif enum == lldb.eValueTypeRegister: 2272c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen return "register" 2282c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen elif enum == lldb.eValueTypeRegisterSet: 2292c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen return "register_set" 2302c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen elif enum == lldb.eValueTypeConstResult: 2312c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen return "constant_result" 2322c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen else: 23342da4dae5d7dccf98a57399d4689150b928ab545Johnny Chen raise Exception("Unknown ValueType enum") 2342c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen 235be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen 236168a61a9d1551d407240395942dc9e005c47ba30Johnny Chen# ================================================== 237168a61a9d1551d407240395942dc9e005c47ba30Johnny Chen# Utility functions related to Threads and Processes 238168a61a9d1551d407240395942dc9e005c47ba30Johnny Chen# ================================================== 239be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen 240e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chendef get_stopped_threads(process, reason): 241e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen """Returns the thread(s) with the specified stop reason in a list.""" 242e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen threads = [] 243e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen for t in lldb_iter(process, 'GetNumThreads', 'GetThreadAtIndex'): 244e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen if t.GetStopReason() == reason: 245e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen threads.append(t) 246e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen return threads 247e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen 248e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chendef get_stopped_thread(process, reason): 249e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen """A convenience function which returns the first thread with the given stop 250e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen reason or None. 251e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen 252e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen Example usages: 253e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen 254e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen 1. Get the stopped thread due to a breakpoint condition 255e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen 256e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen ... 257e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen from lldbutil import get_stopped_thread 258e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen thread = get_stopped_thread(self.process, lldb.eStopReasonPlanComplete) 259e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen self.assertTrue(thread != None, "There should be a thread stopped due to breakpoint condition") 260e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen ... 261e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen 262e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen 2. Get the thread stopped due to a breakpoint 263e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen 264e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen ... 265e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen from lldbutil import get_stopped_thread 266e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen thread = get_stopped_thread(self.process, lldb.eStopReasonBreakpoint) 267e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen self.assertTrue(thread != None, "There should be a thread stopped due to breakpoint") 268e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen ... 269e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen 270e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen """ 271e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen threads = get_stopped_threads(process, reason) 272e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen if len(threads) == 0: 273e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen return None 274e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen return threads[0] 275e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen 276318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chendef get_threads_stopped_at_breakpoint (process, bkpt): 277318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen """ For a stopped process returns the thread stopped at the breakpoint passed in bkpt""" 278318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen stopped_threads = [] 279318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen threads = [] 280318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen 281318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen stopped_threads = get_stopped_threads (process, lldb.eStopReasonBreakpoint) 282318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen 283318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen if len(stopped_threads) == 0: 284318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen return threads 285318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen 286318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen for thread in stopped_threads: 287318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen # Make sure we've hit our breakpoint... 288318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen break_id = thread.GetStopReasonDataAtIndex (0) 289318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen if break_id == bkpt.GetID(): 290318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen threads.append(thread) 291318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen 292318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen return threads 293318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen 294318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chendef continue_to_breakpoint (process, bkpt): 295318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen """ Continues the process, if it stops, returns the threads stopped at bkpt; otherwise, returns None""" 296318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen process.Continue() 297318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen if process.GetState() != lldb.eStateStopped: 298318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen return None 299318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen else: 300318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen return get_threads_stopped_at_breakpoint (process, bkpt) 301318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen 30269af39d7e7c1988caf027956a6af5f17c55b5534Johnny Chendef get_caller_symbol(thread): 30369af39d7e7c1988caf027956a6af5f17c55b5534Johnny Chen """ 30469af39d7e7c1988caf027956a6af5f17c55b5534Johnny Chen Returns the symbol name for the call site of the leaf function. 30569af39d7e7c1988caf027956a6af5f17c55b5534Johnny Chen """ 30669af39d7e7c1988caf027956a6af5f17c55b5534Johnny Chen depth = thread.GetNumFrames() 30769af39d7e7c1988caf027956a6af5f17c55b5534Johnny Chen if depth <= 1: 30869af39d7e7c1988caf027956a6af5f17c55b5534Johnny Chen return None 30969af39d7e7c1988caf027956a6af5f17c55b5534Johnny Chen caller = thread.GetFrameAtIndex(1).GetSymbol() 31069af39d7e7c1988caf027956a6af5f17c55b5534Johnny Chen if caller: 31169af39d7e7c1988caf027956a6af5f17c55b5534Johnny Chen return caller.GetName() 31269af39d7e7c1988caf027956a6af5f17c55b5534Johnny Chen else: 31369af39d7e7c1988caf027956a6af5f17c55b5534Johnny Chen return None 31469af39d7e7c1988caf027956a6af5f17c55b5534Johnny Chen 31569af39d7e7c1988caf027956a6af5f17c55b5534Johnny Chen 316318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chendef get_function_names(thread): 3171605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen """ 3181605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen Returns a sequence of function names from the stack frames of this thread. 3191605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen """ 3201605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen def GetFuncName(i): 3211605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen return thread.GetFrameAtIndex(i).GetFunction().GetName() 3221605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen 3231605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen return map(GetFuncName, range(thread.GetNumFrames())) 3241605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen 3251605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen 326318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chendef get_symbol_names(thread): 327b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen """ 328b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen Returns a sequence of symbols for this thread. 329b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen """ 330b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen def GetSymbol(i): 331b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen return thread.GetFrameAtIndex(i).GetSymbol().GetName() 332b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen 333b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen return map(GetSymbol, range(thread.GetNumFrames())) 334b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen 335b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen 336318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chendef get_pc_addresses(thread): 337b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen """ 338b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen Returns a sequence of pc addresses for this thread. 339b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen """ 340b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen def GetPCAddress(i): 341b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen return thread.GetFrameAtIndex(i).GetPCAddress() 342b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen 343b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen return map(GetPCAddress, range(thread.GetNumFrames())) 344b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen 345b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen 346318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chendef get_filenames(thread): 3471605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen """ 3481605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen Returns a sequence of file names from the stack frames of this thread. 3491605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen """ 3501605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen def GetFilename(i): 3511605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen return thread.GetFrameAtIndex(i).GetLineEntry().GetFileSpec().GetFilename() 3521605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen 3531605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen return map(GetFilename, range(thread.GetNumFrames())) 3541605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen 3551605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen 356318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chendef get_line_numbers(thread): 3571605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen """ 3581605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen Returns a sequence of line numbers from the stack frames of this thread. 3591605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen """ 3601605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen def GetLineNumber(i): 3611605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen return thread.GetFrameAtIndex(i).GetLineEntry().GetLine() 3621605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen 3631605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen return map(GetLineNumber, range(thread.GetNumFrames())) 3641605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen 3651605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen 366318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chendef get_module_names(thread): 3671605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen """ 3681605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen Returns a sequence of module names from the stack frames of this thread. 3691605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen """ 3701605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen def GetModuleName(i): 3711605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen return thread.GetFrameAtIndex(i).GetModule().GetFileSpec().GetFilename() 3721605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen 3731605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen return map(GetModuleName, range(thread.GetNumFrames())) 3741605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen 3751605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen 376318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chendef get_stack_frames(thread): 37788866ac481cd5533c18e00233aeced2eb1fce42bJohnny Chen """ 37888866ac481cd5533c18e00233aeced2eb1fce42bJohnny Chen Returns a sequence of stack frames for this thread. 37988866ac481cd5533c18e00233aeced2eb1fce42bJohnny Chen """ 38088866ac481cd5533c18e00233aeced2eb1fce42bJohnny Chen def GetStackFrame(i): 38188866ac481cd5533c18e00233aeced2eb1fce42bJohnny Chen return thread.GetFrameAtIndex(i) 38288866ac481cd5533c18e00233aeced2eb1fce42bJohnny Chen 38388866ac481cd5533c18e00233aeced2eb1fce42bJohnny Chen return map(GetStackFrame, range(thread.GetNumFrames())) 38488866ac481cd5533c18e00233aeced2eb1fce42bJohnny Chen 38588866ac481cd5533c18e00233aeced2eb1fce42bJohnny Chen 386318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chendef print_stacktrace(thread, string_buffer = False): 3871605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen """Prints a simple stack trace of this thread.""" 38830425e9677342cff9995cd4937fdc12354b6b24bJohnny Chen 389ed5f04ef51b18d6bedbc8589fa06544491977b9cJohnny Chen output = StringIO.StringIO() if string_buffer else sys.stdout 390b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen target = thread.GetProcess().GetTarget() 391b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen 3921605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen depth = thread.GetNumFrames() 3931605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen 394318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen mods = get_module_names(thread) 395318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen funcs = get_function_names(thread) 396318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen symbols = get_symbol_names(thread) 397318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen files = get_filenames(thread) 398318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen lines = get_line_numbers(thread) 399318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen addrs = get_pc_addresses(thread) 40030425e9677342cff9995cd4937fdc12354b6b24bJohnny Chen 401ad5fd40cb92070593d248b8f44b9902be0bcb4bfJohnny Chen if thread.GetStopReason() != lldb.eStopReasonInvalid: 402ad5fd40cb92070593d248b8f44b9902be0bcb4bfJohnny Chen desc = "stop reason=" + StopReasonString(thread.GetStopReason()) 403ad5fd40cb92070593d248b8f44b9902be0bcb4bfJohnny Chen else: 404ad5fd40cb92070593d248b8f44b9902be0bcb4bfJohnny Chen desc = "" 405ad5fd40cb92070593d248b8f44b9902be0bcb4bfJohnny Chen print >> output, "Stack trace for thread id={0:#x} name={1} queue={2} ".format( 406ad5fd40cb92070593d248b8f44b9902be0bcb4bfJohnny Chen thread.GetThreadID(), thread.GetName(), thread.GetQueueName()) + desc 4071605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen 408b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen for i in range(depth): 409b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen frame = thread.GetFrameAtIndex(i) 410b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen function = frame.GetFunction() 411b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen 412b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen load_addr = addrs[i].GetLoadAddress(target) 413b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen if not function.IsValid(): 414b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen file_addr = addrs[i].GetFileAddress() 415b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen print >> output, " frame #{num}: {addr:#016x} {mod}`{symbol} + ????".format( 416b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen num=i, addr=load_addr, mod=mods[i], symbol=symbols[i]) 417b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen else: 418b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen print >> output, " frame #{num}: {addr:#016x} {mod}`{func} at {file}:{line}".format( 419b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen num=i, addr=load_addr, mod=mods[i], func=funcs[i], file=files[i], line=lines[i]) 420b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen 421b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen if string_buffer: 422ed5f04ef51b18d6bedbc8589fa06544491977b9cJohnny Chen return output.getvalue() 423b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen 424b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen 425318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chendef print_stacktraces(process, string_buffer = False): 426b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen """Prints the stack traces of all the threads.""" 427b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen 428ed5f04ef51b18d6bedbc8589fa06544491977b9cJohnny Chen output = StringIO.StringIO() if string_buffer else sys.stdout 429b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen 430b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen print >> output, "Stack traces for " + repr(process) 4311605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen 432b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen for i in range(process.GetNumThreads()): 433318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen print >> output, print_stacktrace(process.GetThreadAtIndex(i), string_buffer=True) 43430425e9677342cff9995cd4937fdc12354b6b24bJohnny Chen 43530425e9677342cff9995cd4937fdc12354b6b24bJohnny Chen if string_buffer: 436ed5f04ef51b18d6bedbc8589fa06544491977b9cJohnny Chen return output.getvalue() 437