lldbutil.py revision 084fd8945b922818e069adfb72ac39936466e221
11605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen"""
2b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny ChenThis LLDB module contains miscellaneous utilities.
330e4850a3f4687cab5b2465125072d5658786efaJohnny ChenSome of the test suite takes advantage of the utility functions defined here.
430e4850a3f4687cab5b2465125072d5658786efaJohnny ChenThey can also be useful for general purpose lldb scripting.
51605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen"""
61605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen
71605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chenimport lldb
80bfa859ea49d27efd89d5f152b8371b39919d92dJohnny Chenimport os, sys
9ed5f04ef51b18d6bedbc8589fa06544491977b9cJohnny Chenimport StringIO
101605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen
118a3b54eb714602c777d57ccc3626440c41dee46aJohnny Chen# ===================================================
128a3b54eb714602c777d57ccc3626440c41dee46aJohnny Chen# Utilities for locating/checking executable programs
138a3b54eb714602c777d57ccc3626440c41dee46aJohnny Chen# ===================================================
14979cb5da1f9aee5d23d8facfb7d5a781406cca28Johnny Chen
150bfa859ea49d27efd89d5f152b8371b39919d92dJohnny Chendef is_exe(fpath):
16efdc26a60c21852787e7bde326163c824d9e0491Johnny Chen    """Returns True if fpath is an executable."""
170bfa859ea49d27efd89d5f152b8371b39919d92dJohnny Chen    return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
180bfa859ea49d27efd89d5f152b8371b39919d92dJohnny Chen
190bfa859ea49d27efd89d5f152b8371b39919d92dJohnny Chendef which(program):
20efdc26a60c21852787e7bde326163c824d9e0491Johnny Chen    """Returns the full path to a program; None otherwise."""
210bfa859ea49d27efd89d5f152b8371b39919d92dJohnny Chen    fpath, fname = os.path.split(program)
220bfa859ea49d27efd89d5f152b8371b39919d92dJohnny Chen    if fpath:
230bfa859ea49d27efd89d5f152b8371b39919d92dJohnny Chen        if is_exe(program):
240bfa859ea49d27efd89d5f152b8371b39919d92dJohnny Chen            return program
250bfa859ea49d27efd89d5f152b8371b39919d92dJohnny Chen    else:
260bfa859ea49d27efd89d5f152b8371b39919d92dJohnny Chen        for path in os.environ["PATH"].split(os.pathsep):
270bfa859ea49d27efd89d5f152b8371b39919d92dJohnny Chen            exe_file = os.path.join(path, program)
280bfa859ea49d27efd89d5f152b8371b39919d92dJohnny Chen            if is_exe(exe_file):
290bfa859ea49d27efd89d5f152b8371b39919d92dJohnny Chen                return exe_file
300bfa859ea49d27efd89d5f152b8371b39919d92dJohnny Chen    return None
310bfa859ea49d27efd89d5f152b8371b39919d92dJohnny Chen
3251ed1b614f2c2b6970f50296d7d41c9de2c30ff4Johnny Chen# ===================================================
3351ed1b614f2c2b6970f50296d7d41c9de2c30ff4Johnny Chen# Disassembly for an SBFunction or an SBSymbol object
3451ed1b614f2c2b6970f50296d7d41c9de2c30ff4Johnny Chen# ===================================================
3551ed1b614f2c2b6970f50296d7d41c9de2c30ff4Johnny Chen
3651ed1b614f2c2b6970f50296d7d41c9de2c30ff4Johnny Chendef disassemble(target, function_or_symbol):
3751ed1b614f2c2b6970f50296d7d41c9de2c30ff4Johnny Chen    """Disassemble the function or symbol given a target.
3851ed1b614f2c2b6970f50296d7d41c9de2c30ff4Johnny Chen
3951ed1b614f2c2b6970f50296d7d41c9de2c30ff4Johnny Chen    It returns the disassembly content in a string object.
4051ed1b614f2c2b6970f50296d7d41c9de2c30ff4Johnny Chen    """
4151ed1b614f2c2b6970f50296d7d41c9de2c30ff4Johnny Chen    buf = StringIO.StringIO()
4251ed1b614f2c2b6970f50296d7d41c9de2c30ff4Johnny Chen    insts = function_or_symbol.GetInstructions(target)
43d643c08c3d80ab16308f395aaa5aa7664d506cd3Johnny Chen    for i in insts:
4451ed1b614f2c2b6970f50296d7d41c9de2c30ff4Johnny Chen        print >> buf, i
4551ed1b614f2c2b6970f50296d7d41c9de2c30ff4Johnny Chen    return buf.getvalue()
4651ed1b614f2c2b6970f50296d7d41c9de2c30ff4Johnny Chen
4751ed1b614f2c2b6970f50296d7d41c9de2c30ff4Johnny Chen
484c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen# ==========================================================
494c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen# Integer (byte size 1, 2, 4, and 8) to bytearray conversion
504c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen# ==========================================================
514c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen
524c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chendef int_to_bytearray(val, bytesize):
534c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen    """Utility function to convert an integer into a bytearray.
544c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen
55d2765fc8b9c9bd4d98dd5d6176b6108b6516e04cJohnny Chen    It returns the bytearray in the little endian format.  It is easy to get the
56d2765fc8b9c9bd4d98dd5d6176b6108b6516e04cJohnny Chen    big endian format, just do ba.reverse() on the returned object.
574c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen    """
58f4c0d1d8854f3ed87ca797628008386fdb9318afJohnny Chen    import struct
594c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen
604c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen    if bytesize == 1:
614c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen        return bytearray([val])
624c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen
634c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen    # Little endian followed by a format character.
644c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen    template = "<%c"
654c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen    if bytesize == 2:
664c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen        fmt = template % 'h'
674c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen    elif bytesize == 4:
684c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen        fmt = template % 'i'
694c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen    elif bytesize == 4:
704c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen        fmt = template % 'q'
714c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen    else:
724c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen        return None
734c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen
74f4c0d1d8854f3ed87ca797628008386fdb9318afJohnny Chen    packed = struct.pack(fmt, val)
754c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen    return bytearray(map(ord, packed))
764c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen
774c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chendef bytearray_to_int(bytes, bytesize):
784c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen    """Utility function to convert a bytearray into an integer.
794c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen
80d2765fc8b9c9bd4d98dd5d6176b6108b6516e04cJohnny Chen    It interprets the bytearray in the little endian format. For a big endian
81d2765fc8b9c9bd4d98dd5d6176b6108b6516e04cJohnny Chen    bytearray, just do ba.reverse() on the object before passing it in.
824c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen    """
83f4c0d1d8854f3ed87ca797628008386fdb9318afJohnny Chen    import struct
844c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen
854c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen    if bytesize == 1:
864c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen        return ba[0]
874c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen
884c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen    # Little endian followed by a format character.
894c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen    template = "<%c"
904c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen    if bytesize == 2:
914c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen        fmt = template % 'h'
924c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen    elif bytesize == 4:
934c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen        fmt = template % 'i'
944c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen    elif bytesize == 4:
954c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen        fmt = template % 'q'
964c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen    else:
974c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen        return None
984c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen
99f4c0d1d8854f3ed87ca797628008386fdb9318afJohnny Chen    unpacked = struct.unpack(fmt, str(bytes))
1004c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen    return unpacked[0]
1014c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen
1024c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen
103bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen# ==============================================================
104bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen# Get the description of an lldb object or None if not available
105bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen# ==============================================================
106bdc36bd05d156143d9f2e568a1aa1b5253bbe1f1Johnny Chendef get_description(obj, option=None):
107bdc36bd05d156143d9f2e568a1aa1b5253bbe1f1Johnny Chen    """Calls lldb_obj.GetDescription() and returns a string, or None.
108bdc36bd05d156143d9f2e568a1aa1b5253bbe1f1Johnny Chen
109bdc36bd05d156143d9f2e568a1aa1b5253bbe1f1Johnny Chen    For SBTarget and SBBreakpointLocation lldb objects, an extra option can be
110bdc36bd05d156143d9f2e568a1aa1b5253bbe1f1Johnny Chen    passed in to describe the detailed level of description desired:
111bdc36bd05d156143d9f2e568a1aa1b5253bbe1f1Johnny Chen        o lldb.eDescriptionLevelBrief
112bdc36bd05d156143d9f2e568a1aa1b5253bbe1f1Johnny Chen        o lldb.eDescriptionLevelFull
113bdc36bd05d156143d9f2e568a1aa1b5253bbe1f1Johnny Chen        o lldb.eDescriptionLevelVerbose
114bdc36bd05d156143d9f2e568a1aa1b5253bbe1f1Johnny Chen    """
115bdc36bd05d156143d9f2e568a1aa1b5253bbe1f1Johnny Chen    method = getattr(obj, 'GetDescription')
116bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen    if not method:
117bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen        return None
118bdc36bd05d156143d9f2e568a1aa1b5253bbe1f1Johnny Chen    if isinstance(obj, lldb.SBTarget) or isinstance(obj, lldb.SBBreakpointLocation):
119bdc36bd05d156143d9f2e568a1aa1b5253bbe1f1Johnny Chen        if option is None:
120bdc36bd05d156143d9f2e568a1aa1b5253bbe1f1Johnny Chen            option = lldb.eDescriptionLevelBrief
121bdc36bd05d156143d9f2e568a1aa1b5253bbe1f1Johnny Chen
122bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen    stream = lldb.SBStream()
123bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen    if option is None:
124bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen        success = method(stream)
125bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen    else:
126bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen        success = method(stream, option)
127bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen    if not success:
128bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen        return None
129bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen    return stream.GetData()
130bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen
131bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen
132168a61a9d1551d407240395942dc9e005c47ba30Johnny Chen# =================================================
133168a61a9d1551d407240395942dc9e005c47ba30Johnny Chen# Convert some enum value to its string counterpart
134168a61a9d1551d407240395942dc9e005c47ba30Johnny Chen# =================================================
135be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen
13647342d57ac5ac0bb2da765374229f94d98cb600aJohnny Chendef state_type_to_str(enum):
137be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    """Returns the stateType string given an enum."""
138be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    if enum == lldb.eStateInvalid:
13959b8477b020651df9b215396864e2e161a007d8cJohnny Chen        return "invalid"
140be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    elif enum == lldb.eStateUnloaded:
14159b8477b020651df9b215396864e2e161a007d8cJohnny Chen        return "unloaded"
14242da4dae5d7dccf98a57399d4689150b928ab545Johnny Chen    elif enum == lldb.eStateConnected:
14342da4dae5d7dccf98a57399d4689150b928ab545Johnny Chen        return "connected"
144be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    elif enum == lldb.eStateAttaching:
14559b8477b020651df9b215396864e2e161a007d8cJohnny Chen        return "attaching"
146be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    elif enum == lldb.eStateLaunching:
14759b8477b020651df9b215396864e2e161a007d8cJohnny Chen        return "launching"
148be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    elif enum == lldb.eStateStopped:
14959b8477b020651df9b215396864e2e161a007d8cJohnny Chen        return "stopped"
150be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    elif enum == lldb.eStateRunning:
15159b8477b020651df9b215396864e2e161a007d8cJohnny Chen        return "running"
152be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    elif enum == lldb.eStateStepping:
15359b8477b020651df9b215396864e2e161a007d8cJohnny Chen        return "stepping"
154be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    elif enum == lldb.eStateCrashed:
15559b8477b020651df9b215396864e2e161a007d8cJohnny Chen        return "crashed"
156be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    elif enum == lldb.eStateDetached:
15759b8477b020651df9b215396864e2e161a007d8cJohnny Chen        return "detached"
158be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    elif enum == lldb.eStateExited:
15959b8477b020651df9b215396864e2e161a007d8cJohnny Chen        return "exited"
160be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    elif enum == lldb.eStateSuspended:
16159b8477b020651df9b215396864e2e161a007d8cJohnny Chen        return "suspended"
162be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    else:
16342da4dae5d7dccf98a57399d4689150b928ab545Johnny Chen        raise Exception("Unknown StateType enum")
164be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen
16547342d57ac5ac0bb2da765374229f94d98cb600aJohnny Chendef stop_reason_to_str(enum):
166be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    """Returns the stopReason string given an enum."""
167be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    if enum == lldb.eStopReasonInvalid:
16859b8477b020651df9b215396864e2e161a007d8cJohnny Chen        return "invalid"
169be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    elif enum == lldb.eStopReasonNone:
17059b8477b020651df9b215396864e2e161a007d8cJohnny Chen        return "none"
171be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    elif enum == lldb.eStopReasonTrace:
17259b8477b020651df9b215396864e2e161a007d8cJohnny Chen        return "trace"
173be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    elif enum == lldb.eStopReasonBreakpoint:
17459b8477b020651df9b215396864e2e161a007d8cJohnny Chen        return "breakpoint"
175be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    elif enum == lldb.eStopReasonWatchpoint:
17659b8477b020651df9b215396864e2e161a007d8cJohnny Chen        return "watchpoint"
177be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    elif enum == lldb.eStopReasonSignal:
17859b8477b020651df9b215396864e2e161a007d8cJohnny Chen        return "signal"
179be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    elif enum == lldb.eStopReasonException:
18059b8477b020651df9b215396864e2e161a007d8cJohnny Chen        return "exception"
181be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    elif enum == lldb.eStopReasonPlanComplete:
18259b8477b020651df9b215396864e2e161a007d8cJohnny Chen        return "plancomplete"
183be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    else:
18442da4dae5d7dccf98a57399d4689150b928ab545Johnny Chen        raise Exception("Unknown StopReason enum")
185be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen
18647342d57ac5ac0bb2da765374229f94d98cb600aJohnny Chendef value_type_to_str(enum):
1872c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen    """Returns the valueType string given an enum."""
1882c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen    if enum == lldb.eValueTypeInvalid:
1892c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen        return "invalid"
1902c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen    elif enum == lldb.eValueTypeVariableGlobal:
1912c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen        return "global_variable"
1922c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen    elif enum == lldb.eValueTypeVariableStatic:
1932c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen        return "static_variable"
1942c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen    elif enum == lldb.eValueTypeVariableArgument:
1952c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen        return "argument_variable"
1962c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen    elif enum == lldb.eValueTypeVariableLocal:
1972c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen        return "local_variable"
1982c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen    elif enum == lldb.eValueTypeRegister:
1992c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen        return "register"
2002c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen    elif enum == lldb.eValueTypeRegisterSet:
2012c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen        return "register_set"
2022c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen    elif enum == lldb.eValueTypeConstResult:
2032c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen        return "constant_result"
2042c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen    else:
20542da4dae5d7dccf98a57399d4689150b928ab545Johnny Chen        raise Exception("Unknown ValueType enum")
2062c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen
207be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen
208168a61a9d1551d407240395942dc9e005c47ba30Johnny Chen# ==================================================
209168a61a9d1551d407240395942dc9e005c47ba30Johnny Chen# Utility functions related to Threads and Processes
210168a61a9d1551d407240395942dc9e005c47ba30Johnny Chen# ==================================================
211be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen
212e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chendef get_stopped_threads(process, reason):
2135aba3f5e7964f9cdea53ab5f20487201f031d856Johnny Chen    """Returns the thread(s) with the specified stop reason in a list.
2145aba3f5e7964f9cdea53ab5f20487201f031d856Johnny Chen
2155aba3f5e7964f9cdea53ab5f20487201f031d856Johnny Chen    The list can be empty if no such thread exists.
2165aba3f5e7964f9cdea53ab5f20487201f031d856Johnny Chen    """
217e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen    threads = []
218d643c08c3d80ab16308f395aaa5aa7664d506cd3Johnny Chen    for t in process:
219e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen        if t.GetStopReason() == reason:
220e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen            threads.append(t)
221e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen    return threads
222e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen
223e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chendef get_stopped_thread(process, reason):
224e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen    """A convenience function which returns the first thread with the given stop
225e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen    reason or None.
226e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen
227e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen    Example usages:
228e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen
229e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen    1. Get the stopped thread due to a breakpoint condition
230e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen
231e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen    ...
232e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen        from lldbutil import get_stopped_thread
2333d8ae4681b81b42a404ad77a231c6f743040e644Johnny Chen        thread = get_stopped_thread(process, lldb.eStopReasonPlanComplete)
234e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen        self.assertTrue(thread != None, "There should be a thread stopped due to breakpoint condition")
235e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen    ...
236e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen
237e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen    2. Get the thread stopped due to a breakpoint
238e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen
239e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen    ...
240e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen        from lldbutil import get_stopped_thread
2413d8ae4681b81b42a404ad77a231c6f743040e644Johnny Chen        thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint)
242e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen        self.assertTrue(thread != None, "There should be a thread stopped due to breakpoint")
243e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen    ...
244e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen
245e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen    """
246e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen    threads = get_stopped_threads(process, reason)
247e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen    if len(threads) == 0:
248e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen        return None
249e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen    return threads[0]
250e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen
251318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chendef get_threads_stopped_at_breakpoint (process, bkpt):
252318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen    """ For a stopped process returns the thread stopped at the breakpoint passed in bkpt"""
253318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen    stopped_threads = []
254318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen    threads = []
255318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen
256318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen    stopped_threads = get_stopped_threads (process, lldb.eStopReasonBreakpoint)
257318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen
258318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen    if len(stopped_threads) == 0:
259318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen        return threads
260318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen
261318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen    for thread in stopped_threads:
262318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen    # Make sure we've hit our breakpoint...
263318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen        break_id = thread.GetStopReasonDataAtIndex (0)
264318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen        if break_id == bkpt.GetID():
265318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen            threads.append(thread)
266318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen
267318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen    return threads
268318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen
269318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chendef continue_to_breakpoint (process, bkpt):
270318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen    """ Continues the process, if it stops, returns the threads stopped at bkpt; otherwise, returns None"""
271318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen    process.Continue()
272318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen    if process.GetState() != lldb.eStateStopped:
273318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen        return None
274318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen    else:
275318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen        return get_threads_stopped_at_breakpoint (process, bkpt)
276318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen
27769af39d7e7c1988caf027956a6af5f17c55b5534Johnny Chendef get_caller_symbol(thread):
27869af39d7e7c1988caf027956a6af5f17c55b5534Johnny Chen    """
27969af39d7e7c1988caf027956a6af5f17c55b5534Johnny Chen    Returns the symbol name for the call site of the leaf function.
28069af39d7e7c1988caf027956a6af5f17c55b5534Johnny Chen    """
28169af39d7e7c1988caf027956a6af5f17c55b5534Johnny Chen    depth = thread.GetNumFrames()
28269af39d7e7c1988caf027956a6af5f17c55b5534Johnny Chen    if depth <= 1:
28369af39d7e7c1988caf027956a6af5f17c55b5534Johnny Chen        return None
28469af39d7e7c1988caf027956a6af5f17c55b5534Johnny Chen    caller = thread.GetFrameAtIndex(1).GetSymbol()
28569af39d7e7c1988caf027956a6af5f17c55b5534Johnny Chen    if caller:
28669af39d7e7c1988caf027956a6af5f17c55b5534Johnny Chen        return caller.GetName()
28769af39d7e7c1988caf027956a6af5f17c55b5534Johnny Chen    else:
28869af39d7e7c1988caf027956a6af5f17c55b5534Johnny Chen        return None
28969af39d7e7c1988caf027956a6af5f17c55b5534Johnny Chen
29069af39d7e7c1988caf027956a6af5f17c55b5534Johnny Chen
291318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chendef get_function_names(thread):
2921605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    """
2931605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    Returns a sequence of function names from the stack frames of this thread.
2941605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    """
2951605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    def GetFuncName(i):
29664abe46fa4d3b030ae525b40afe1bffccda166aaJohnny Chen        return thread.GetFrameAtIndex(i).GetFunctionName()
2971605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen
2981605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    return map(GetFuncName, range(thread.GetNumFrames()))
2991605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen
3001605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen
301318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chendef get_symbol_names(thread):
302b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen    """
303b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen    Returns a sequence of symbols for this thread.
304b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen    """
305b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen    def GetSymbol(i):
306b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen        return thread.GetFrameAtIndex(i).GetSymbol().GetName()
307b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen
308b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen    return map(GetSymbol, range(thread.GetNumFrames()))
309b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen
310b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen
311318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chendef get_pc_addresses(thread):
312b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen    """
313b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen    Returns a sequence of pc addresses for this thread.
314b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen    """
315b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen    def GetPCAddress(i):
316b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen        return thread.GetFrameAtIndex(i).GetPCAddress()
317b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen
318b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen    return map(GetPCAddress, range(thread.GetNumFrames()))
319b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen
320b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen
321318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chendef get_filenames(thread):
3221605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    """
3231605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    Returns a sequence of file names from the stack frames of this thread.
3241605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    """
3251605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    def GetFilename(i):
3261605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen        return thread.GetFrameAtIndex(i).GetLineEntry().GetFileSpec().GetFilename()
3271605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen
3281605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    return map(GetFilename, range(thread.GetNumFrames()))
3291605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen
3301605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen
331318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chendef get_line_numbers(thread):
3321605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    """
3331605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    Returns a sequence of line numbers from the stack frames of this thread.
3341605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    """
3351605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    def GetLineNumber(i):
3361605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen        return thread.GetFrameAtIndex(i).GetLineEntry().GetLine()
3371605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen
3381605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    return map(GetLineNumber, range(thread.GetNumFrames()))
3391605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen
3401605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen
341318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chendef get_module_names(thread):
3421605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    """
3431605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    Returns a sequence of module names from the stack frames of this thread.
3441605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    """
3451605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    def GetModuleName(i):
3461605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen        return thread.GetFrameAtIndex(i).GetModule().GetFileSpec().GetFilename()
3471605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen
3481605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    return map(GetModuleName, range(thread.GetNumFrames()))
3491605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen
3501605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen
351318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chendef get_stack_frames(thread):
35288866ac481cd5533c18e00233aeced2eb1fce42bJohnny Chen    """
35388866ac481cd5533c18e00233aeced2eb1fce42bJohnny Chen    Returns a sequence of stack frames for this thread.
35488866ac481cd5533c18e00233aeced2eb1fce42bJohnny Chen    """
35588866ac481cd5533c18e00233aeced2eb1fce42bJohnny Chen    def GetStackFrame(i):
35688866ac481cd5533c18e00233aeced2eb1fce42bJohnny Chen        return thread.GetFrameAtIndex(i)
35788866ac481cd5533c18e00233aeced2eb1fce42bJohnny Chen
35888866ac481cd5533c18e00233aeced2eb1fce42bJohnny Chen    return map(GetStackFrame, range(thread.GetNumFrames()))
35988866ac481cd5533c18e00233aeced2eb1fce42bJohnny Chen
36088866ac481cd5533c18e00233aeced2eb1fce42bJohnny Chen
361318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chendef print_stacktrace(thread, string_buffer = False):
3621605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    """Prints a simple stack trace of this thread."""
36330425e9677342cff9995cd4937fdc12354b6b24bJohnny Chen
364ed5f04ef51b18d6bedbc8589fa06544491977b9cJohnny Chen    output = StringIO.StringIO() if string_buffer else sys.stdout
365b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen    target = thread.GetProcess().GetTarget()
366b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen
3671605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    depth = thread.GetNumFrames()
3681605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen
369318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen    mods = get_module_names(thread)
370318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen    funcs = get_function_names(thread)
371318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen    symbols = get_symbol_names(thread)
372318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen    files = get_filenames(thread)
373318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen    lines = get_line_numbers(thread)
374318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen    addrs = get_pc_addresses(thread)
37530425e9677342cff9995cd4937fdc12354b6b24bJohnny Chen
376ad5fd40cb92070593d248b8f44b9902be0bcb4bfJohnny Chen    if thread.GetStopReason() != lldb.eStopReasonInvalid:
37747342d57ac5ac0bb2da765374229f94d98cb600aJohnny Chen        desc =  "stop reason=" + stop_reason_to_str(thread.GetStopReason())
378ad5fd40cb92070593d248b8f44b9902be0bcb4bfJohnny Chen    else:
379ad5fd40cb92070593d248b8f44b9902be0bcb4bfJohnny Chen        desc = ""
380ad5fd40cb92070593d248b8f44b9902be0bcb4bfJohnny Chen    print >> output, "Stack trace for thread id={0:#x} name={1} queue={2} ".format(
381ad5fd40cb92070593d248b8f44b9902be0bcb4bfJohnny Chen        thread.GetThreadID(), thread.GetName(), thread.GetQueueName()) + desc
3821605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen
383b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen    for i in range(depth):
384b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen        frame = thread.GetFrameAtIndex(i)
385b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen        function = frame.GetFunction()
386b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen
387b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen        load_addr = addrs[i].GetLoadAddress(target)
388960ce1206dbe268c7f3142fcf279e6392a852024Johnny Chen        if not function:
389b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen            file_addr = addrs[i].GetFileAddress()
39049f3d81ab49270d85d1637797572a3bc38cce1d9Johnny Chen            start_addr = frame.GetSymbol().GetStartAddress().GetFileAddress()
39149f3d81ab49270d85d1637797572a3bc38cce1d9Johnny Chen            symbol_offset = file_addr - start_addr
39249f3d81ab49270d85d1637797572a3bc38cce1d9Johnny Chen            print >> output, "  frame #{num}: {addr:#016x} {mod}`{symbol} + {offset}".format(
39349f3d81ab49270d85d1637797572a3bc38cce1d9Johnny Chen                num=i, addr=load_addr, mod=mods[i], symbol=symbols[i], offset=symbol_offset)
394b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen        else:
39549f3d81ab49270d85d1637797572a3bc38cce1d9Johnny Chen            print >> output, "  frame #{num}: {addr:#016x} {mod}`{func} at {file}:{line} {args}".format(
39664abe46fa4d3b030ae525b40afe1bffccda166aaJohnny Chen                num=i, addr=load_addr, mod=mods[i],
39764abe46fa4d3b030ae525b40afe1bffccda166aaJohnny Chen                func='%s [inlined]' % funcs[i] if frame.IsInlined() else funcs[i],
3987d4c7fecd679c157804577313203c5212cb59a5eJohnny Chen                file=files[i], line=lines[i],
3997d4c7fecd679c157804577313203c5212cb59a5eJohnny Chen                args=get_args_as_string(frame, showFuncName=False) if not frame.IsInlined() else '()')
400b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen
401b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen    if string_buffer:
402ed5f04ef51b18d6bedbc8589fa06544491977b9cJohnny Chen        return output.getvalue()
403b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen
404b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen
405318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chendef print_stacktraces(process, string_buffer = False):
406b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen    """Prints the stack traces of all the threads."""
407b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen
408ed5f04ef51b18d6bedbc8589fa06544491977b9cJohnny Chen    output = StringIO.StringIO() if string_buffer else sys.stdout
409b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen
410b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen    print >> output, "Stack traces for " + repr(process)
4111605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen
412311b1d69ef5cde8f70a1528f8c2d3b8e28c3d090Johnny Chen    for thread in process:
413311b1d69ef5cde8f70a1528f8c2d3b8e28c3d090Johnny Chen        print >> output, print_stacktrace(thread, string_buffer=True)
41430425e9677342cff9995cd4937fdc12354b6b24bJohnny Chen
41530425e9677342cff9995cd4937fdc12354b6b24bJohnny Chen    if string_buffer:
416ed5f04ef51b18d6bedbc8589fa06544491977b9cJohnny Chen        return output.getvalue()
417185e2c103c2af449262046495b3f8d1640794543Johnny Chen
418185e2c103c2af449262046495b3f8d1640794543Johnny Chen# ===================================
419185e2c103c2af449262046495b3f8d1640794543Johnny Chen# Utility functions related to Frames
420185e2c103c2af449262046495b3f8d1640794543Johnny Chen# ===================================
421185e2c103c2af449262046495b3f8d1640794543Johnny Chen
422abb3b2d796da9e081cd545b710d23c514489f895Johnny Chendef get_parent_frame(frame):
423abb3b2d796da9e081cd545b710d23c514489f895Johnny Chen    """
424abb3b2d796da9e081cd545b710d23c514489f895Johnny Chen    Returns the parent frame of the input frame object; None if not available.
425abb3b2d796da9e081cd545b710d23c514489f895Johnny Chen    """
426abb3b2d796da9e081cd545b710d23c514489f895Johnny Chen    thread = frame.GetThread()
427abb3b2d796da9e081cd545b710d23c514489f895Johnny Chen    parent_found = False
428abb3b2d796da9e081cd545b710d23c514489f895Johnny Chen    for f in thread:
429abb3b2d796da9e081cd545b710d23c514489f895Johnny Chen        if parent_found:
430abb3b2d796da9e081cd545b710d23c514489f895Johnny Chen            return f
431abb3b2d796da9e081cd545b710d23c514489f895Johnny Chen        if f.GetFrameID() == frame.GetFrameID():
432abb3b2d796da9e081cd545b710d23c514489f895Johnny Chen            parent_found = True
433abb3b2d796da9e081cd545b710d23c514489f895Johnny Chen
434abb3b2d796da9e081cd545b710d23c514489f895Johnny Chen    # If we reach here, no parent has been found, return None.
435abb3b2d796da9e081cd545b710d23c514489f895Johnny Chen    return None
436abb3b2d796da9e081cd545b710d23c514489f895Johnny Chen
43749f3d81ab49270d85d1637797572a3bc38cce1d9Johnny Chendef get_args_as_string(frame, showFuncName=True):
438abb3b2d796da9e081cd545b710d23c514489f895Johnny Chen    """
439abb3b2d796da9e081cd545b710d23c514489f895Johnny Chen    Returns the args of the input frame object as a string.
440abb3b2d796da9e081cd545b710d23c514489f895Johnny Chen    """
441abb3b2d796da9e081cd545b710d23c514489f895Johnny Chen    # arguments     => True
442abb3b2d796da9e081cd545b710d23c514489f895Johnny Chen    # locals        => False
443abb3b2d796da9e081cd545b710d23c514489f895Johnny Chen    # statics       => False
444abb3b2d796da9e081cd545b710d23c514489f895Johnny Chen    # in_scope_only => True
445abb3b2d796da9e081cd545b710d23c514489f895Johnny Chen    vars = frame.GetVariables(True, False, False, True) # type of SBValueList
446abb3b2d796da9e081cd545b710d23c514489f895Johnny Chen    args = [] # list of strings
447abb3b2d796da9e081cd545b710d23c514489f895Johnny Chen    for var in vars:
448abb3b2d796da9e081cd545b710d23c514489f895Johnny Chen        args.append("(%s)%s=%s" % (var.GetTypeName(),
449abb3b2d796da9e081cd545b710d23c514489f895Johnny Chen                                   var.GetName(),
450abb3b2d796da9e081cd545b710d23c514489f895Johnny Chen                                   var.GetValue(frame)))
451960ce1206dbe268c7f3142fcf279e6392a852024Johnny Chen    if frame.GetFunction():
452bbc18b63544b1d81b5ea9d58c7e0672b07dd369bJohnny Chen        name = frame.GetFunction().GetName()
453960ce1206dbe268c7f3142fcf279e6392a852024Johnny Chen    elif frame.GetSymbol():
454bbc18b63544b1d81b5ea9d58c7e0672b07dd369bJohnny Chen        name = frame.GetSymbol().GetName()
455bbc18b63544b1d81b5ea9d58c7e0672b07dd369bJohnny Chen    else:
456bbc18b63544b1d81b5ea9d58c7e0672b07dd369bJohnny Chen        name = ""
45749f3d81ab49270d85d1637797572a3bc38cce1d9Johnny Chen    if showFuncName:
45849f3d81ab49270d85d1637797572a3bc38cce1d9Johnny Chen        return "%s(%s)" % (name, ", ".join(args))
45949f3d81ab49270d85d1637797572a3bc38cce1d9Johnny Chen    else:
46049f3d81ab49270d85d1637797572a3bc38cce1d9Johnny Chen        return "(%s)" % (", ".join(args))
46149f3d81ab49270d85d1637797572a3bc38cce1d9Johnny Chen
462185e2c103c2af449262046495b3f8d1640794543Johnny Chendef print_registers(frame, string_buffer = False):
463b299877fa8e5e94f9f86da47583bc2d3b85a41f5Johnny Chen    """Prints all the register sets of the frame."""
464185e2c103c2af449262046495b3f8d1640794543Johnny Chen
465185e2c103c2af449262046495b3f8d1640794543Johnny Chen    output = StringIO.StringIO() if string_buffer else sys.stdout
466185e2c103c2af449262046495b3f8d1640794543Johnny Chen
467185e2c103c2af449262046495b3f8d1640794543Johnny Chen    print >> output, "Register sets for " + repr(frame)
468185e2c103c2af449262046495b3f8d1640794543Johnny Chen
469728255bc323e93a36644a4cdf225192c34c8472cJohnny Chen    registerSet = frame.GetRegisters() # Return type of SBValueList.
470728255bc323e93a36644a4cdf225192c34c8472cJohnny Chen    print >> output, "Frame registers (size of register set = %d):" % registerSet.GetSize()
471728255bc323e93a36644a4cdf225192c34c8472cJohnny Chen    for value in registerSet:
472185e2c103c2af449262046495b3f8d1640794543Johnny Chen        #print >> output, value
473185e2c103c2af449262046495b3f8d1640794543Johnny Chen        print >> output, "%s (number of children = %d):" % (value.GetName(), value.GetNumChildren())
474185e2c103c2af449262046495b3f8d1640794543Johnny Chen        for child in value:
475185e2c103c2af449262046495b3f8d1640794543Johnny Chen            print >> output, "Name: %s, Value: %s" % (child.GetName(), child.GetValue(frame))
476185e2c103c2af449262046495b3f8d1640794543Johnny Chen
477185e2c103c2af449262046495b3f8d1640794543Johnny Chen    if string_buffer:
478185e2c103c2af449262046495b3f8d1640794543Johnny Chen        return output.getvalue()
479728255bc323e93a36644a4cdf225192c34c8472cJohnny Chen
480728255bc323e93a36644a4cdf225192c34c8472cJohnny Chendef get_registers(frame, kind):
481728255bc323e93a36644a4cdf225192c34c8472cJohnny Chen    """Returns the registers given the frame and the kind of registers desired.
482728255bc323e93a36644a4cdf225192c34c8472cJohnny Chen
483728255bc323e93a36644a4cdf225192c34c8472cJohnny Chen    Returns None if there's no such kind.
484728255bc323e93a36644a4cdf225192c34c8472cJohnny Chen    """
485728255bc323e93a36644a4cdf225192c34c8472cJohnny Chen    registerSet = frame.GetRegisters() # Return type of SBValueList.
486728255bc323e93a36644a4cdf225192c34c8472cJohnny Chen    for value in registerSet:
487728255bc323e93a36644a4cdf225192c34c8472cJohnny Chen        if kind.lower() in value.GetName().lower():
488728255bc323e93a36644a4cdf225192c34c8472cJohnny Chen            return value
489728255bc323e93a36644a4cdf225192c34c8472cJohnny Chen
490728255bc323e93a36644a4cdf225192c34c8472cJohnny Chen    return None
491728255bc323e93a36644a4cdf225192c34c8472cJohnny Chen
492728255bc323e93a36644a4cdf225192c34c8472cJohnny Chendef get_GPRs(frame):
493728255bc323e93a36644a4cdf225192c34c8472cJohnny Chen    """Returns the general purpose registers of the frame as an SBValue.
494728255bc323e93a36644a4cdf225192c34c8472cJohnny Chen
495fd1175c5d3152beb6fdee4b3b2ba3461b1ae1e0cJohnny Chen    The returned SBValue object is iterable.  An example:
496fd1175c5d3152beb6fdee4b3b2ba3461b1ae1e0cJohnny Chen        ...
497fd1175c5d3152beb6fdee4b3b2ba3461b1ae1e0cJohnny Chen        from lldbutil import get_GPRs
498fd1175c5d3152beb6fdee4b3b2ba3461b1ae1e0cJohnny Chen        regs = get_GPRs(frame)
499fd1175c5d3152beb6fdee4b3b2ba3461b1ae1e0cJohnny Chen        for reg in regs:
500fd1175c5d3152beb6fdee4b3b2ba3461b1ae1e0cJohnny Chen            print "%s => %s" % (reg.GetName(), reg.GetValue())
501fd1175c5d3152beb6fdee4b3b2ba3461b1ae1e0cJohnny Chen        ...
502728255bc323e93a36644a4cdf225192c34c8472cJohnny Chen    """
503728255bc323e93a36644a4cdf225192c34c8472cJohnny Chen    return get_registers(frame, "general purpose")
504728255bc323e93a36644a4cdf225192c34c8472cJohnny Chen
505728255bc323e93a36644a4cdf225192c34c8472cJohnny Chendef get_FPRs(frame):
506728255bc323e93a36644a4cdf225192c34c8472cJohnny Chen    """Returns the floating point registers of the frame as an SBValue.
507728255bc323e93a36644a4cdf225192c34c8472cJohnny Chen
508fd1175c5d3152beb6fdee4b3b2ba3461b1ae1e0cJohnny Chen    The returned SBValue object is iterable.  An example:
509fd1175c5d3152beb6fdee4b3b2ba3461b1ae1e0cJohnny Chen        ...
510fd1175c5d3152beb6fdee4b3b2ba3461b1ae1e0cJohnny Chen        from lldbutil import get_FPRs
511fd1175c5d3152beb6fdee4b3b2ba3461b1ae1e0cJohnny Chen        regs = get_FPRs(frame)
512fd1175c5d3152beb6fdee4b3b2ba3461b1ae1e0cJohnny Chen        for reg in regs:
513fd1175c5d3152beb6fdee4b3b2ba3461b1ae1e0cJohnny Chen            print "%s => %s" % (reg.GetName(), reg.GetValue())
514fd1175c5d3152beb6fdee4b3b2ba3461b1ae1e0cJohnny Chen        ...
515728255bc323e93a36644a4cdf225192c34c8472cJohnny Chen    """
516728255bc323e93a36644a4cdf225192c34c8472cJohnny Chen    return get_registers(frame, "floating point")
517728255bc323e93a36644a4cdf225192c34c8472cJohnny Chen
518728255bc323e93a36644a4cdf225192c34c8472cJohnny Chendef get_ESRs(frame):
519728255bc323e93a36644a4cdf225192c34c8472cJohnny Chen    """Returns the exception state registers of the frame as an SBValue.
520728255bc323e93a36644a4cdf225192c34c8472cJohnny Chen
521fd1175c5d3152beb6fdee4b3b2ba3461b1ae1e0cJohnny Chen    The returned SBValue object is iterable.  An example:
522fd1175c5d3152beb6fdee4b3b2ba3461b1ae1e0cJohnny Chen        ...
523fd1175c5d3152beb6fdee4b3b2ba3461b1ae1e0cJohnny Chen        from lldbutil import get_ESRs
524fd1175c5d3152beb6fdee4b3b2ba3461b1ae1e0cJohnny Chen        regs = get_ESRs(frame)
525fd1175c5d3152beb6fdee4b3b2ba3461b1ae1e0cJohnny Chen        for reg in regs:
526fd1175c5d3152beb6fdee4b3b2ba3461b1ae1e0cJohnny Chen            print "%s => %s" % (reg.GetName(), reg.GetValue())
527fd1175c5d3152beb6fdee4b3b2ba3461b1ae1e0cJohnny Chen        ...
528728255bc323e93a36644a4cdf225192c34c8472cJohnny Chen    """
529728255bc323e93a36644a4cdf225192c34c8472cJohnny Chen    return get_registers(frame, "exception state")
530084fd8945b922818e069adfb72ac39936466e221Johnny Chen
531084fd8945b922818e069adfb72ac39936466e221Johnny Chen# ===============================
532084fd8945b922818e069adfb72ac39936466e221Johnny Chen# Utility functions for SBValue's
533084fd8945b922818e069adfb72ac39936466e221Johnny Chen# ===============================
534084fd8945b922818e069adfb72ac39936466e221Johnny Chen
535084fd8945b922818e069adfb72ac39936466e221Johnny Chenclass BasicFormatter(object):
536084fd8945b922818e069adfb72ac39936466e221Johnny Chen    def format(self, value, buffer=None, indent=0):
537084fd8945b922818e069adfb72ac39936466e221Johnny Chen        if not buffer:
538084fd8945b922818e069adfb72ac39936466e221Johnny Chen            output = StringIO.StringIO()
539084fd8945b922818e069adfb72ac39936466e221Johnny Chen        else:
540084fd8945b922818e069adfb72ac39936466e221Johnny Chen            output = buffer
541084fd8945b922818e069adfb72ac39936466e221Johnny Chen        sum = value.GetSummary()
542084fd8945b922818e069adfb72ac39936466e221Johnny Chen        if value.GetNumChildren() > 0 and sum == None:
543084fd8945b922818e069adfb72ac39936466e221Johnny Chen            sum = "%s (location)" % value.GetLocation()
544084fd8945b922818e069adfb72ac39936466e221Johnny Chen        print >> output, "{indentation}({type}) {name} = {summary}".format(
545084fd8945b922818e069adfb72ac39936466e221Johnny Chen            indentation = ' ' * indent,
546084fd8945b922818e069adfb72ac39936466e221Johnny Chen            type = value.GetTypeName(),
547084fd8945b922818e069adfb72ac39936466e221Johnny Chen            name = value.GetName(),
548084fd8945b922818e069adfb72ac39936466e221Johnny Chen            summary = sum)
549084fd8945b922818e069adfb72ac39936466e221Johnny Chen        return output.getvalue()
550084fd8945b922818e069adfb72ac39936466e221Johnny Chen
551084fd8945b922818e069adfb72ac39936466e221Johnny Chenclass ChildVisitingFormatter(BasicFormatter):
552084fd8945b922818e069adfb72ac39936466e221Johnny Chen    def __init__(self, indent=2):
553084fd8945b922818e069adfb72ac39936466e221Johnny Chen        """Default indentation of 2 SPC's."""
554084fd8945b922818e069adfb72ac39936466e221Johnny Chen        self.indentation = indent
555084fd8945b922818e069adfb72ac39936466e221Johnny Chen    def format(self, value, buffer=None):
556084fd8945b922818e069adfb72ac39936466e221Johnny Chen        if not buffer:
557084fd8945b922818e069adfb72ac39936466e221Johnny Chen            output = StringIO.StringIO()
558084fd8945b922818e069adfb72ac39936466e221Johnny Chen        else:
559084fd8945b922818e069adfb72ac39936466e221Johnny Chen            output = buffer
560084fd8945b922818e069adfb72ac39936466e221Johnny Chen
561084fd8945b922818e069adfb72ac39936466e221Johnny Chen        BasicFormatter.format(self, value, buffer=output)
562084fd8945b922818e069adfb72ac39936466e221Johnny Chen        for child in value:
563084fd8945b922818e069adfb72ac39936466e221Johnny Chen            BasicFormatter.format(self, child, buffer=output, indent=self.indentation)
564084fd8945b922818e069adfb72ac39936466e221Johnny Chen
565084fd8945b922818e069adfb72ac39936466e221Johnny Chen        return output.getvalue()
566