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