lldbutil.py revision 311b1d69ef5cde8f70a1528f8c2d3b8e28c3d090
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
98a3b54eb714602c777d57ccc3626440c41dee46aJohnny Chen# ===================================================
108a3b54eb714602c777d57ccc3626440c41dee46aJohnny Chen# Utilities for locating/checking executable programs
118a3b54eb714602c777d57ccc3626440c41dee46aJohnny Chen# ===================================================
12979cb5da1f9aee5d23d8facfb7d5a781406cca28Johnny Chen
130bfa859ea49d27efd89d5f152b8371b39919d92dJohnny Chendef is_exe(fpath):
14efdc26a60c21852787e7bde326163c824d9e0491Johnny Chen    """Returns True if fpath is an executable."""
150bfa859ea49d27efd89d5f152b8371b39919d92dJohnny Chen    return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
160bfa859ea49d27efd89d5f152b8371b39919d92dJohnny Chen
170bfa859ea49d27efd89d5f152b8371b39919d92dJohnny Chendef which(program):
18efdc26a60c21852787e7bde326163c824d9e0491Johnny Chen    """Returns the full path to a program; None otherwise."""
190bfa859ea49d27efd89d5f152b8371b39919d92dJohnny Chen    fpath, fname = os.path.split(program)
200bfa859ea49d27efd89d5f152b8371b39919d92dJohnny Chen    if fpath:
210bfa859ea49d27efd89d5f152b8371b39919d92dJohnny Chen        if is_exe(program):
220bfa859ea49d27efd89d5f152b8371b39919d92dJohnny Chen            return program
230bfa859ea49d27efd89d5f152b8371b39919d92dJohnny Chen    else:
240bfa859ea49d27efd89d5f152b8371b39919d92dJohnny Chen        for path in os.environ["PATH"].split(os.pathsep):
250bfa859ea49d27efd89d5f152b8371b39919d92dJohnny Chen            exe_file = os.path.join(path, program)
260bfa859ea49d27efd89d5f152b8371b39919d92dJohnny Chen            if is_exe(exe_file):
270bfa859ea49d27efd89d5f152b8371b39919d92dJohnny Chen                return exe_file
280bfa859ea49d27efd89d5f152b8371b39919d92dJohnny Chen    return None
290bfa859ea49d27efd89d5f152b8371b39919d92dJohnny Chen
3051ed1b614f2c2b6970f50296d7d41c9de2c30ff4Johnny Chen# ===================================================
3151ed1b614f2c2b6970f50296d7d41c9de2c30ff4Johnny Chen# Disassembly for an SBFunction or an SBSymbol object
3251ed1b614f2c2b6970f50296d7d41c9de2c30ff4Johnny Chen# ===================================================
3351ed1b614f2c2b6970f50296d7d41c9de2c30ff4Johnny Chen
3451ed1b614f2c2b6970f50296d7d41c9de2c30ff4Johnny Chendef disassemble(target, function_or_symbol):
3551ed1b614f2c2b6970f50296d7d41c9de2c30ff4Johnny Chen    """Disassemble the function or symbol given a target.
3651ed1b614f2c2b6970f50296d7d41c9de2c30ff4Johnny Chen
3751ed1b614f2c2b6970f50296d7d41c9de2c30ff4Johnny Chen    It returns the disassembly content in a string object.
3851ed1b614f2c2b6970f50296d7d41c9de2c30ff4Johnny Chen    """
3951ed1b614f2c2b6970f50296d7d41c9de2c30ff4Johnny Chen    buf = StringIO.StringIO()
4051ed1b614f2c2b6970f50296d7d41c9de2c30ff4Johnny Chen    insts = function_or_symbol.GetInstructions(target)
41d643c08c3d80ab16308f395aaa5aa7664d506cd3Johnny Chen    for i in insts:
4251ed1b614f2c2b6970f50296d7d41c9de2c30ff4Johnny Chen        print >> buf, i
4351ed1b614f2c2b6970f50296d7d41c9de2c30ff4Johnny Chen    return buf.getvalue()
4451ed1b614f2c2b6970f50296d7d41c9de2c30ff4Johnny Chen
4551ed1b614f2c2b6970f50296d7d41c9de2c30ff4Johnny Chen
464c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen# ==========================================================
474c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen# Integer (byte size 1, 2, 4, and 8) to bytearray conversion
484c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen# ==========================================================
494c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen
504c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chendef int_to_bytearray(val, bytesize):
514c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen    """Utility function to convert an integer into a bytearray.
524c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen
53d2765fc8b9c9bd4d98dd5d6176b6108b6516e04cJohnny Chen    It returns the bytearray in the little endian format.  It is easy to get the
54d2765fc8b9c9bd4d98dd5d6176b6108b6516e04cJohnny Chen    big endian format, just do ba.reverse() on the returned object.
554c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen    """
56f4c0d1d8854f3ed87ca797628008386fdb9318afJohnny Chen    import struct
574c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen
584c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen    if bytesize == 1:
594c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen        return bytearray([val])
604c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen
614c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen    # Little endian followed by a format character.
624c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen    template = "<%c"
634c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen    if bytesize == 2:
644c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen        fmt = template % 'h'
654c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen    elif bytesize == 4:
664c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen        fmt = template % 'i'
674c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen    elif bytesize == 4:
684c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen        fmt = template % 'q'
694c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen    else:
704c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen        return None
714c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen
72f4c0d1d8854f3ed87ca797628008386fdb9318afJohnny Chen    packed = struct.pack(fmt, val)
734c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen    return bytearray(map(ord, packed))
744c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen
754c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chendef bytearray_to_int(bytes, bytesize):
764c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen    """Utility function to convert a bytearray into an integer.
774c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen
78d2765fc8b9c9bd4d98dd5d6176b6108b6516e04cJohnny Chen    It interprets the bytearray in the little endian format. For a big endian
79d2765fc8b9c9bd4d98dd5d6176b6108b6516e04cJohnny Chen    bytearray, just do ba.reverse() on the object before passing it in.
804c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen    """
81f4c0d1d8854f3ed87ca797628008386fdb9318afJohnny Chen    import struct
824c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen
834c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen    if bytesize == 1:
844c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen        return ba[0]
854c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen
864c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen    # Little endian followed by a format character.
874c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen    template = "<%c"
884c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen    if bytesize == 2:
894c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen        fmt = template % 'h'
904c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen    elif bytesize == 4:
914c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen        fmt = template % 'i'
924c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen    elif bytesize == 4:
934c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen        fmt = template % 'q'
944c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen    else:
954c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen        return None
964c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen
97f4c0d1d8854f3ed87ca797628008386fdb9318afJohnny Chen    unpacked = struct.unpack(fmt, str(bytes))
984c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen    return unpacked[0]
994c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen
1004c70f287ea336c4a0c599431bfc2b5a9a618ab5eJohnny Chen
101bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen# ==============================================================
102bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen# Get the description of an lldb object or None if not available
103bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen# ==============================================================
104bdc36bd05d156143d9f2e568a1aa1b5253bbe1f1Johnny Chendef get_description(obj, option=None):
105bdc36bd05d156143d9f2e568a1aa1b5253bbe1f1Johnny Chen    """Calls lldb_obj.GetDescription() and returns a string, or None.
106bdc36bd05d156143d9f2e568a1aa1b5253bbe1f1Johnny Chen
107bdc36bd05d156143d9f2e568a1aa1b5253bbe1f1Johnny Chen    For SBTarget and SBBreakpointLocation lldb objects, an extra option can be
108bdc36bd05d156143d9f2e568a1aa1b5253bbe1f1Johnny Chen    passed in to describe the detailed level of description desired:
109bdc36bd05d156143d9f2e568a1aa1b5253bbe1f1Johnny Chen        o lldb.eDescriptionLevelBrief
110bdc36bd05d156143d9f2e568a1aa1b5253bbe1f1Johnny Chen        o lldb.eDescriptionLevelFull
111bdc36bd05d156143d9f2e568a1aa1b5253bbe1f1Johnny Chen        o lldb.eDescriptionLevelVerbose
112bdc36bd05d156143d9f2e568a1aa1b5253bbe1f1Johnny Chen    """
113bdc36bd05d156143d9f2e568a1aa1b5253bbe1f1Johnny Chen    method = getattr(obj, 'GetDescription')
114bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen    if not method:
115bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen        return None
116bdc36bd05d156143d9f2e568a1aa1b5253bbe1f1Johnny Chen    if isinstance(obj, lldb.SBTarget) or isinstance(obj, lldb.SBBreakpointLocation):
117bdc36bd05d156143d9f2e568a1aa1b5253bbe1f1Johnny Chen        if option is None:
118bdc36bd05d156143d9f2e568a1aa1b5253bbe1f1Johnny Chen            option = lldb.eDescriptionLevelBrief
119bdc36bd05d156143d9f2e568a1aa1b5253bbe1f1Johnny Chen
120bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen    stream = lldb.SBStream()
121bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen    if option is None:
122bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen        success = method(stream)
123bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen    else:
124bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen        success = method(stream, option)
125bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen    if not success:
126bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen        return None
127bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen    return stream.GetData()
128bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen
129bc1a93e702cae42f87a8cbc58035877cb19e0840Johnny Chen
130168a61a9d1551d407240395942dc9e005c47ba30Johnny Chen# =================================================
131168a61a9d1551d407240395942dc9e005c47ba30Johnny Chen# Convert some enum value to its string counterpart
132168a61a9d1551d407240395942dc9e005c47ba30Johnny Chen# =================================================
133be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen
13447342d57ac5ac0bb2da765374229f94d98cb600aJohnny Chendef state_type_to_str(enum):
135be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    """Returns the stateType string given an enum."""
136be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    if enum == lldb.eStateInvalid:
13759b8477b020651df9b215396864e2e161a007d8cJohnny Chen        return "invalid"
138be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    elif enum == lldb.eStateUnloaded:
13959b8477b020651df9b215396864e2e161a007d8cJohnny Chen        return "unloaded"
14042da4dae5d7dccf98a57399d4689150b928ab545Johnny Chen    elif enum == lldb.eStateConnected:
14142da4dae5d7dccf98a57399d4689150b928ab545Johnny Chen        return "connected"
142be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    elif enum == lldb.eStateAttaching:
14359b8477b020651df9b215396864e2e161a007d8cJohnny Chen        return "attaching"
144be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    elif enum == lldb.eStateLaunching:
14559b8477b020651df9b215396864e2e161a007d8cJohnny Chen        return "launching"
146be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    elif enum == lldb.eStateStopped:
14759b8477b020651df9b215396864e2e161a007d8cJohnny Chen        return "stopped"
148be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    elif enum == lldb.eStateRunning:
14959b8477b020651df9b215396864e2e161a007d8cJohnny Chen        return "running"
150be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    elif enum == lldb.eStateStepping:
15159b8477b020651df9b215396864e2e161a007d8cJohnny Chen        return "stepping"
152be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    elif enum == lldb.eStateCrashed:
15359b8477b020651df9b215396864e2e161a007d8cJohnny Chen        return "crashed"
154be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    elif enum == lldb.eStateDetached:
15559b8477b020651df9b215396864e2e161a007d8cJohnny Chen        return "detached"
156be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    elif enum == lldb.eStateExited:
15759b8477b020651df9b215396864e2e161a007d8cJohnny Chen        return "exited"
158be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    elif enum == lldb.eStateSuspended:
15959b8477b020651df9b215396864e2e161a007d8cJohnny Chen        return "suspended"
160be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    else:
16142da4dae5d7dccf98a57399d4689150b928ab545Johnny Chen        raise Exception("Unknown StateType enum")
162be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen
16347342d57ac5ac0bb2da765374229f94d98cb600aJohnny Chendef stop_reason_to_str(enum):
164be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    """Returns the stopReason string given an enum."""
165be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    if enum == lldb.eStopReasonInvalid:
16659b8477b020651df9b215396864e2e161a007d8cJohnny Chen        return "invalid"
167be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    elif enum == lldb.eStopReasonNone:
16859b8477b020651df9b215396864e2e161a007d8cJohnny Chen        return "none"
169be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    elif enum == lldb.eStopReasonTrace:
17059b8477b020651df9b215396864e2e161a007d8cJohnny Chen        return "trace"
171be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    elif enum == lldb.eStopReasonBreakpoint:
17259b8477b020651df9b215396864e2e161a007d8cJohnny Chen        return "breakpoint"
173be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    elif enum == lldb.eStopReasonWatchpoint:
17459b8477b020651df9b215396864e2e161a007d8cJohnny Chen        return "watchpoint"
175be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    elif enum == lldb.eStopReasonSignal:
17659b8477b020651df9b215396864e2e161a007d8cJohnny Chen        return "signal"
177be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    elif enum == lldb.eStopReasonException:
17859b8477b020651df9b215396864e2e161a007d8cJohnny Chen        return "exception"
179be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    elif enum == lldb.eStopReasonPlanComplete:
18059b8477b020651df9b215396864e2e161a007d8cJohnny Chen        return "plancomplete"
181be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    else:
18242da4dae5d7dccf98a57399d4689150b928ab545Johnny Chen        raise Exception("Unknown StopReason enum")
183be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen
18447342d57ac5ac0bb2da765374229f94d98cb600aJohnny Chendef value_type_to_str(enum):
1852c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen    """Returns the valueType string given an enum."""
1862c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen    if enum == lldb.eValueTypeInvalid:
1872c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen        return "invalid"
1882c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen    elif enum == lldb.eValueTypeVariableGlobal:
1892c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen        return "global_variable"
1902c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen    elif enum == lldb.eValueTypeVariableStatic:
1912c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen        return "static_variable"
1922c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen    elif enum == lldb.eValueTypeVariableArgument:
1932c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen        return "argument_variable"
1942c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen    elif enum == lldb.eValueTypeVariableLocal:
1952c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen        return "local_variable"
1962c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen    elif enum == lldb.eValueTypeRegister:
1972c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen        return "register"
1982c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen    elif enum == lldb.eValueTypeRegisterSet:
1992c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen        return "register_set"
2002c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen    elif enum == lldb.eValueTypeConstResult:
2012c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen        return "constant_result"
2022c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen    else:
20342da4dae5d7dccf98a57399d4689150b928ab545Johnny Chen        raise Exception("Unknown ValueType enum")
2042c8d1596ec40c321d6d39c2b32c33fd662b66c11Johnny Chen
205be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen
206168a61a9d1551d407240395942dc9e005c47ba30Johnny Chen# ==================================================
207168a61a9d1551d407240395942dc9e005c47ba30Johnny Chen# Utility functions related to Threads and Processes
208168a61a9d1551d407240395942dc9e005c47ba30Johnny Chen# ==================================================
209be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen
210e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chendef get_stopped_threads(process, reason):
211e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen    """Returns the thread(s) with the specified stop reason in a list."""
212e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen    threads = []
213d643c08c3d80ab16308f395aaa5aa7664d506cd3Johnny Chen    for t in process:
214e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen        if t.GetStopReason() == reason:
215e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen            threads.append(t)
216e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen    return threads
217e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen
218e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chendef get_stopped_thread(process, reason):
219e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen    """A convenience function which returns the first thread with the given stop
220e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen    reason or None.
221e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen
222e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen    Example usages:
223e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen
224e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen    1. Get the stopped thread due to a breakpoint condition
225e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen
226e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen    ...
227e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen        from lldbutil import get_stopped_thread
228e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen        thread = get_stopped_thread(self.process, lldb.eStopReasonPlanComplete)
229e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen        self.assertTrue(thread != None, "There should be a thread stopped due to breakpoint condition")
230e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen    ...
231e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen
232e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen    2. Get the thread stopped due to a breakpoint
233e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen
234e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen    ...
235e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen        from lldbutil import get_stopped_thread
236e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen        thread = get_stopped_thread(self.process, lldb.eStopReasonBreakpoint)
237e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen        self.assertTrue(thread != None, "There should be a thread stopped due to breakpoint")
238e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen    ...
239e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen
240e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen    """
241e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen    threads = get_stopped_threads(process, reason)
242e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen    if len(threads) == 0:
243e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen        return None
244e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen    return threads[0]
245e428d33b3f09b789f0b5f70f973ebea5785d7feeJohnny Chen
246318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chendef get_threads_stopped_at_breakpoint (process, bkpt):
247318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen    """ For a stopped process returns the thread stopped at the breakpoint passed in bkpt"""
248318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen    stopped_threads = []
249318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen    threads = []
250318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen
251318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen    stopped_threads = get_stopped_threads (process, lldb.eStopReasonBreakpoint)
252318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen
253318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen    if len(stopped_threads) == 0:
254318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen        return threads
255318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen
256318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen    for thread in stopped_threads:
257318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen    # Make sure we've hit our breakpoint...
258318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen        break_id = thread.GetStopReasonDataAtIndex (0)
259318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen        if break_id == bkpt.GetID():
260318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen            threads.append(thread)
261318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen
262318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen    return threads
263318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen
264318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chendef continue_to_breakpoint (process, bkpt):
265318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen    """ Continues the process, if it stops, returns the threads stopped at bkpt; otherwise, returns None"""
266318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen    process.Continue()
267318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen    if process.GetState() != lldb.eStateStopped:
268318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen        return None
269318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen    else:
270318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen        return get_threads_stopped_at_breakpoint (process, bkpt)
271318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen
27269af39d7e7c1988caf027956a6af5f17c55b5534Johnny Chendef get_caller_symbol(thread):
27369af39d7e7c1988caf027956a6af5f17c55b5534Johnny Chen    """
27469af39d7e7c1988caf027956a6af5f17c55b5534Johnny Chen    Returns the symbol name for the call site of the leaf function.
27569af39d7e7c1988caf027956a6af5f17c55b5534Johnny Chen    """
27669af39d7e7c1988caf027956a6af5f17c55b5534Johnny Chen    depth = thread.GetNumFrames()
27769af39d7e7c1988caf027956a6af5f17c55b5534Johnny Chen    if depth <= 1:
27869af39d7e7c1988caf027956a6af5f17c55b5534Johnny Chen        return None
27969af39d7e7c1988caf027956a6af5f17c55b5534Johnny Chen    caller = thread.GetFrameAtIndex(1).GetSymbol()
28069af39d7e7c1988caf027956a6af5f17c55b5534Johnny Chen    if caller:
28169af39d7e7c1988caf027956a6af5f17c55b5534Johnny Chen        return caller.GetName()
28269af39d7e7c1988caf027956a6af5f17c55b5534Johnny Chen    else:
28369af39d7e7c1988caf027956a6af5f17c55b5534Johnny Chen        return None
28469af39d7e7c1988caf027956a6af5f17c55b5534Johnny Chen
28569af39d7e7c1988caf027956a6af5f17c55b5534Johnny Chen
286318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chendef get_function_names(thread):
2871605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    """
2881605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    Returns a sequence of function names from the stack frames of this thread.
2891605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    """
2901605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    def GetFuncName(i):
2911605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen        return thread.GetFrameAtIndex(i).GetFunction().GetName()
2921605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen
2931605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    return map(GetFuncName, range(thread.GetNumFrames()))
2941605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen
2951605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen
296318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chendef get_symbol_names(thread):
297b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen    """
298b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen    Returns a sequence of symbols for this thread.
299b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen    """
300b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen    def GetSymbol(i):
301b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen        return thread.GetFrameAtIndex(i).GetSymbol().GetName()
302b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen
303b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen    return map(GetSymbol, range(thread.GetNumFrames()))
304b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen
305b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen
306318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chendef get_pc_addresses(thread):
307b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen    """
308b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen    Returns a sequence of pc addresses for this thread.
309b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen    """
310b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen    def GetPCAddress(i):
311b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen        return thread.GetFrameAtIndex(i).GetPCAddress()
312b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen
313b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen    return map(GetPCAddress, range(thread.GetNumFrames()))
314b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen
315b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen
316318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chendef get_filenames(thread):
3171605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    """
3181605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    Returns a sequence of file names from the stack frames of this thread.
3191605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    """
3201605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    def GetFilename(i):
3211605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen        return thread.GetFrameAtIndex(i).GetLineEntry().GetFileSpec().GetFilename()
3221605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen
3231605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    return map(GetFilename, range(thread.GetNumFrames()))
3241605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen
3251605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen
326318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chendef get_line_numbers(thread):
3271605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    """
3281605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    Returns a sequence of line numbers from the stack frames of this thread.
3291605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    """
3301605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    def GetLineNumber(i):
3311605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen        return thread.GetFrameAtIndex(i).GetLineEntry().GetLine()
3321605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen
3331605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    return map(GetLineNumber, range(thread.GetNumFrames()))
3341605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen
3351605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen
336318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chendef get_module_names(thread):
3371605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    """
3381605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    Returns a sequence of module names from the stack frames of this thread.
3391605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    """
3401605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    def GetModuleName(i):
3411605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen        return thread.GetFrameAtIndex(i).GetModule().GetFileSpec().GetFilename()
3421605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen
3431605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    return map(GetModuleName, range(thread.GetNumFrames()))
3441605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen
3451605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen
346318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chendef get_stack_frames(thread):
34788866ac481cd5533c18e00233aeced2eb1fce42bJohnny Chen    """
34888866ac481cd5533c18e00233aeced2eb1fce42bJohnny Chen    Returns a sequence of stack frames for this thread.
34988866ac481cd5533c18e00233aeced2eb1fce42bJohnny Chen    """
35088866ac481cd5533c18e00233aeced2eb1fce42bJohnny Chen    def GetStackFrame(i):
35188866ac481cd5533c18e00233aeced2eb1fce42bJohnny Chen        return thread.GetFrameAtIndex(i)
35288866ac481cd5533c18e00233aeced2eb1fce42bJohnny Chen
35388866ac481cd5533c18e00233aeced2eb1fce42bJohnny Chen    return map(GetStackFrame, range(thread.GetNumFrames()))
35488866ac481cd5533c18e00233aeced2eb1fce42bJohnny Chen
35588866ac481cd5533c18e00233aeced2eb1fce42bJohnny Chen
356318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chendef print_stacktrace(thread, string_buffer = False):
3571605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    """Prints a simple stack trace of this thread."""
35830425e9677342cff9995cd4937fdc12354b6b24bJohnny Chen
359ed5f04ef51b18d6bedbc8589fa06544491977b9cJohnny Chen    output = StringIO.StringIO() if string_buffer else sys.stdout
360b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen    target = thread.GetProcess().GetTarget()
361b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen
3621605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    depth = thread.GetNumFrames()
3631605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen
364318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen    mods = get_module_names(thread)
365318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen    funcs = get_function_names(thread)
366318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen    symbols = get_symbol_names(thread)
367318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen    files = get_filenames(thread)
368318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen    lines = get_line_numbers(thread)
369318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chen    addrs = get_pc_addresses(thread)
37030425e9677342cff9995cd4937fdc12354b6b24bJohnny Chen
371ad5fd40cb92070593d248b8f44b9902be0bcb4bfJohnny Chen    if thread.GetStopReason() != lldb.eStopReasonInvalid:
37247342d57ac5ac0bb2da765374229f94d98cb600aJohnny Chen        desc =  "stop reason=" + stop_reason_to_str(thread.GetStopReason())
373ad5fd40cb92070593d248b8f44b9902be0bcb4bfJohnny Chen    else:
374ad5fd40cb92070593d248b8f44b9902be0bcb4bfJohnny Chen        desc = ""
375ad5fd40cb92070593d248b8f44b9902be0bcb4bfJohnny Chen    print >> output, "Stack trace for thread id={0:#x} name={1} queue={2} ".format(
376ad5fd40cb92070593d248b8f44b9902be0bcb4bfJohnny Chen        thread.GetThreadID(), thread.GetName(), thread.GetQueueName()) + desc
3771605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen
378b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen    for i in range(depth):
379b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen        frame = thread.GetFrameAtIndex(i)
380b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen        function = frame.GetFunction()
381b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen
382b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen        load_addr = addrs[i].GetLoadAddress(target)
383b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen        if not function.IsValid():
384b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen            file_addr = addrs[i].GetFileAddress()
385b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen            print >> output, "  frame #{num}: {addr:#016x} {mod}`{symbol} + ????".format(
386b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen                num=i, addr=load_addr, mod=mods[i], symbol=symbols[i])
387b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen        else:
388b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen            print >> output, "  frame #{num}: {addr:#016x} {mod}`{func} at {file}:{line}".format(
389b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen                num=i, addr=load_addr, mod=mods[i], func=funcs[i], file=files[i], line=lines[i])
390b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen
391b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen    if string_buffer:
392ed5f04ef51b18d6bedbc8589fa06544491977b9cJohnny Chen        return output.getvalue()
393b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen
394b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen
395318aaa0b4b593ec3e69c5962bddab10c47066c4fJohnny Chendef print_stacktraces(process, string_buffer = False):
396b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen    """Prints the stack traces of all the threads."""
397b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen
398ed5f04ef51b18d6bedbc8589fa06544491977b9cJohnny Chen    output = StringIO.StringIO() if string_buffer else sys.stdout
399b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen
400b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen    print >> output, "Stack traces for " + repr(process)
4011605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen
402311b1d69ef5cde8f70a1528f8c2d3b8e28c3d090Johnny Chen    for thread in process:
403311b1d69ef5cde8f70a1528f8c2d3b8e28c3d090Johnny Chen        print >> output, print_stacktrace(thread, string_buffer=True)
40430425e9677342cff9995cd4937fdc12354b6b24bJohnny Chen
40530425e9677342cff9995cd4937fdc12354b6b24bJohnny Chen    if string_buffer:
406ed5f04ef51b18d6bedbc8589fa06544491977b9cJohnny Chen        return output.getvalue()
407