lldbutil.py revision ad5fd40cb92070593d248b8f44b9902be0bcb4bf
11605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen"""
2b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny ChenThis LLDB module contains miscellaneous utilities.
31605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen"""
41605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen
51605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chenimport lldb
630425e9677342cff9995cd4937fdc12354b6b24bJohnny Chenimport sys
7ed5f04ef51b18d6bedbc8589fa06544491977b9cJohnny Chenimport StringIO
81605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen
9168a61a9d1551d407240395942dc9e005c47ba30Johnny Chen# ===========================================
10168a61a9d1551d407240395942dc9e005c47ba30Johnny Chen# Iterator for lldb aggregate data structures
11168a61a9d1551d407240395942dc9e005c47ba30Johnny Chen# ===========================================
1284a6d6f10f3010accf9b717b2995f9acb6bee60cJohnny Chen
134d72c746131d8ae86217dfb35edc2e4417330b7bJohnny Chendef lldb_iter(obj, getsize, getelem):
14164bf887534ab18c939dc46525efb3db9de2613dJohnny Chen    """
15164bf887534ab18c939dc46525efb3db9de2613dJohnny Chen    A generator adaptor for lldb aggregate data structures.
16164bf887534ab18c939dc46525efb3db9de2613dJohnny Chen
174d72c746131d8ae86217dfb35edc2e4417330b7bJohnny Chen    API clients pass in the aggregate object, the name of the method to get the
184d72c746131d8ae86217dfb35edc2e4417330b7bJohnny Chen    size of the object, and the name of the method to get the element given an
194d72c746131d8ae86217dfb35edc2e4417330b7bJohnny Chen    index.
20164bf887534ab18c939dc46525efb3db9de2613dJohnny Chen
21164bf887534ab18c939dc46525efb3db9de2613dJohnny Chen    Example usage:
22164bf887534ab18c939dc46525efb3db9de2613dJohnny Chen
23164bf887534ab18c939dc46525efb3db9de2613dJohnny Chen    def disassemble_instructions (insts):
244d72c746131d8ae86217dfb35edc2e4417330b7bJohnny Chen        from lldbutil import lldb_iter
254d72c746131d8ae86217dfb35edc2e4417330b7bJohnny Chen        for i in lldb_iter(insts, 'GetSize', 'GetInstructionAtIndex'):
26164bf887534ab18c939dc46525efb3db9de2613dJohnny Chen            print i
27164bf887534ab18c939dc46525efb3db9de2613dJohnny Chen    """
284d72c746131d8ae86217dfb35edc2e4417330b7bJohnny Chen    size = getattr(obj, getsize)
294d72c746131d8ae86217dfb35edc2e4417330b7bJohnny Chen    elem = getattr(obj, getelem)
304d72c746131d8ae86217dfb35edc2e4417330b7bJohnny Chen    for i in range(size()):
314d72c746131d8ae86217dfb35edc2e4417330b7bJohnny Chen        yield elem(i)
32164bf887534ab18c939dc46525efb3db9de2613dJohnny Chen
33164bf887534ab18c939dc46525efb3db9de2613dJohnny Chen
34168a61a9d1551d407240395942dc9e005c47ba30Johnny Chen# =================================================
35168a61a9d1551d407240395942dc9e005c47ba30Johnny Chen# Convert some enum value to its string counterpart
36168a61a9d1551d407240395942dc9e005c47ba30Johnny Chen# =================================================
37be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen
38be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chendef StateTypeString(enum):
39be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    """Returns the stateType string given an enum."""
40be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    if enum == lldb.eStateInvalid:
4159b8477b020651df9b215396864e2e161a007d8cJohnny Chen        return "invalid"
42be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    elif enum == lldb.eStateUnloaded:
4359b8477b020651df9b215396864e2e161a007d8cJohnny Chen        return "unloaded"
44be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    elif enum == lldb.eStateAttaching:
4559b8477b020651df9b215396864e2e161a007d8cJohnny Chen        return "attaching"
46be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    elif enum == lldb.eStateLaunching:
4759b8477b020651df9b215396864e2e161a007d8cJohnny Chen        return "launching"
48be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    elif enum == lldb.eStateStopped:
4959b8477b020651df9b215396864e2e161a007d8cJohnny Chen        return "stopped"
50be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    elif enum == lldb.eStateRunning:
5159b8477b020651df9b215396864e2e161a007d8cJohnny Chen        return "running"
52be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    elif enum == lldb.eStateStepping:
5359b8477b020651df9b215396864e2e161a007d8cJohnny Chen        return "stepping"
54be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    elif enum == lldb.eStateCrashed:
5559b8477b020651df9b215396864e2e161a007d8cJohnny Chen        return "crashed"
56be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    elif enum == lldb.eStateDetached:
5759b8477b020651df9b215396864e2e161a007d8cJohnny Chen        return "detached"
58be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    elif enum == lldb.eStateExited:
5959b8477b020651df9b215396864e2e161a007d8cJohnny Chen        return "exited"
60be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    elif enum == lldb.eStateSuspended:
6159b8477b020651df9b215396864e2e161a007d8cJohnny Chen        return "suspended"
62be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    else:
63be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen        raise Exception("Unknown stopReason enum")
64be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen
65be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chendef StopReasonString(enum):
66be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    """Returns the stopReason string given an enum."""
67be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    if enum == lldb.eStopReasonInvalid:
6859b8477b020651df9b215396864e2e161a007d8cJohnny Chen        return "invalid"
69be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    elif enum == lldb.eStopReasonNone:
7059b8477b020651df9b215396864e2e161a007d8cJohnny Chen        return "none"
71be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    elif enum == lldb.eStopReasonTrace:
7259b8477b020651df9b215396864e2e161a007d8cJohnny Chen        return "trace"
73be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    elif enum == lldb.eStopReasonBreakpoint:
7459b8477b020651df9b215396864e2e161a007d8cJohnny Chen        return "breakpoint"
75be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    elif enum == lldb.eStopReasonWatchpoint:
7659b8477b020651df9b215396864e2e161a007d8cJohnny Chen        return "watchpoint"
77be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    elif enum == lldb.eStopReasonSignal:
7859b8477b020651df9b215396864e2e161a007d8cJohnny Chen        return "signal"
79be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    elif enum == lldb.eStopReasonException:
8059b8477b020651df9b215396864e2e161a007d8cJohnny Chen        return "exception"
81be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    elif enum == lldb.eStopReasonPlanComplete:
8259b8477b020651df9b215396864e2e161a007d8cJohnny Chen        return "plancomplete"
83be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    else:
84be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen        raise Exception("Unknown stopReason enum")
85be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen
86be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen
87168a61a9d1551d407240395942dc9e005c47ba30Johnny Chen# ==================================================
88168a61a9d1551d407240395942dc9e005c47ba30Johnny Chen# Utility functions related to Threads and Processes
89168a61a9d1551d407240395942dc9e005c47ba30Johnny Chen# ==================================================
90be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen
911605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chendef GetFunctionNames(thread):
921605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    """
931605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    Returns a sequence of function names from the stack frames of this thread.
941605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    """
951605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    def GetFuncName(i):
961605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen        return thread.GetFrameAtIndex(i).GetFunction().GetName()
971605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen
981605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    return map(GetFuncName, range(thread.GetNumFrames()))
991605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen
1001605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen
101b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chendef GetSymbolNames(thread):
102b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen    """
103b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen    Returns a sequence of symbols for this thread.
104b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen    """
105b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen    def GetSymbol(i):
106b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen        return thread.GetFrameAtIndex(i).GetSymbol().GetName()
107b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen
108b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen    return map(GetSymbol, range(thread.GetNumFrames()))
109b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen
110b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen
111b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chendef GetPCAddresses(thread):
112b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen    """
113b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen    Returns a sequence of pc addresses for this thread.
114b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen    """
115b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen    def GetPCAddress(i):
116b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen        return thread.GetFrameAtIndex(i).GetPCAddress()
117b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen
118b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen    return map(GetPCAddress, range(thread.GetNumFrames()))
119b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen
120b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen
1211605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chendef GetFilenames(thread):
1221605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    """
1231605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    Returns a sequence of file names from the stack frames of this thread.
1241605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    """
1251605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    def GetFilename(i):
1261605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen        return thread.GetFrameAtIndex(i).GetLineEntry().GetFileSpec().GetFilename()
1271605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen
1281605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    return map(GetFilename, range(thread.GetNumFrames()))
1291605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen
1301605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen
1311605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chendef GetLineNumbers(thread):
1321605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    """
1331605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    Returns a sequence of line numbers from the stack frames of this thread.
1341605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    """
1351605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    def GetLineNumber(i):
1361605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen        return thread.GetFrameAtIndex(i).GetLineEntry().GetLine()
1371605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen
1381605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    return map(GetLineNumber, range(thread.GetNumFrames()))
1391605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen
1401605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen
1411605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chendef GetModuleNames(thread):
1421605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    """
1431605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    Returns a sequence of module names from the stack frames of this thread.
1441605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    """
1451605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    def GetModuleName(i):
1461605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen        return thread.GetFrameAtIndex(i).GetModule().GetFileSpec().GetFilename()
1471605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen
1481605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    return map(GetModuleName, range(thread.GetNumFrames()))
1491605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen
1501605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen
15188866ac481cd5533c18e00233aeced2eb1fce42bJohnny Chendef GetStackFrames(thread):
15288866ac481cd5533c18e00233aeced2eb1fce42bJohnny Chen    """
15388866ac481cd5533c18e00233aeced2eb1fce42bJohnny Chen    Returns a sequence of stack frames for this thread.
15488866ac481cd5533c18e00233aeced2eb1fce42bJohnny Chen    """
15588866ac481cd5533c18e00233aeced2eb1fce42bJohnny Chen    def GetStackFrame(i):
15688866ac481cd5533c18e00233aeced2eb1fce42bJohnny Chen        return thread.GetFrameAtIndex(i)
15788866ac481cd5533c18e00233aeced2eb1fce42bJohnny Chen
15888866ac481cd5533c18e00233aeced2eb1fce42bJohnny Chen    return map(GetStackFrame, range(thread.GetNumFrames()))
15988866ac481cd5533c18e00233aeced2eb1fce42bJohnny Chen
16088866ac481cd5533c18e00233aeced2eb1fce42bJohnny Chen
16130425e9677342cff9995cd4937fdc12354b6b24bJohnny Chendef PrintStackTrace(thread, string_buffer = False):
1621605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    """Prints a simple stack trace of this thread."""
16330425e9677342cff9995cd4937fdc12354b6b24bJohnny Chen
164ed5f04ef51b18d6bedbc8589fa06544491977b9cJohnny Chen    output = StringIO.StringIO() if string_buffer else sys.stdout
165b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen    target = thread.GetProcess().GetTarget()
166b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen
1671605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    depth = thread.GetNumFrames()
1681605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen
1691605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    mods = GetModuleNames(thread)
1701605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    funcs = GetFunctionNames(thread)
171b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen    symbols = GetSymbolNames(thread)
1721605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    files = GetFilenames(thread)
1731605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    lines = GetLineNumbers(thread)
174b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen    addrs = GetPCAddresses(thread)
17530425e9677342cff9995cd4937fdc12354b6b24bJohnny Chen
176ad5fd40cb92070593d248b8f44b9902be0bcb4bfJohnny Chen    if thread.GetStopReason() != lldb.eStopReasonInvalid:
177ad5fd40cb92070593d248b8f44b9902be0bcb4bfJohnny Chen        desc =  "stop reason=" + StopReasonString(thread.GetStopReason())
178ad5fd40cb92070593d248b8f44b9902be0bcb4bfJohnny Chen    else:
179ad5fd40cb92070593d248b8f44b9902be0bcb4bfJohnny Chen        desc = ""
180ad5fd40cb92070593d248b8f44b9902be0bcb4bfJohnny Chen    print >> output, "Stack trace for thread id={0:#x} name={1} queue={2} ".format(
181ad5fd40cb92070593d248b8f44b9902be0bcb4bfJohnny Chen        thread.GetThreadID(), thread.GetName(), thread.GetQueueName()) + desc
1821605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen
183b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen    for i in range(depth):
184b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen        frame = thread.GetFrameAtIndex(i)
185b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen        function = frame.GetFunction()
186b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen
187b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen        load_addr = addrs[i].GetLoadAddress(target)
188b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen        if not function.IsValid():
189b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen            file_addr = addrs[i].GetFileAddress()
190b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen            print >> output, "  frame #{num}: {addr:#016x} {mod}`{symbol} + ????".format(
191b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen                num=i, addr=load_addr, mod=mods[i], symbol=symbols[i])
192b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen        else:
193b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen            print >> output, "  frame #{num}: {addr:#016x} {mod}`{func} at {file}:{line}".format(
194b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen                num=i, addr=load_addr, mod=mods[i], func=funcs[i], file=files[i], line=lines[i])
195b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen
196b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen    if string_buffer:
197ed5f04ef51b18d6bedbc8589fa06544491977b9cJohnny Chen        return output.getvalue()
198b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen
199b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen
200b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chendef PrintStackTraces(process, string_buffer = False):
201b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen    """Prints the stack traces of all the threads."""
202b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen
203ed5f04ef51b18d6bedbc8589fa06544491977b9cJohnny Chen    output = StringIO.StringIO() if string_buffer else sys.stdout
204b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen
205b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen    print >> output, "Stack traces for " + repr(process)
2061605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen
207b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen    for i in range(process.GetNumThreads()):
208b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen        print >> output, PrintStackTrace(process.GetThreadAtIndex(i), string_buffer=True)
20930425e9677342cff9995cd4937fdc12354b6b24bJohnny Chen
21030425e9677342cff9995cd4937fdc12354b6b24bJohnny Chen    if string_buffer:
211ed5f04ef51b18d6bedbc8589fa06544491977b9cJohnny Chen        return output.getvalue()
212