lldbutil.py revision 84a6d6f10f3010accf9b717b2995f9acb6bee60c
11605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen"""
2b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny ChenThis LLDB module contains miscellaneous utilities.
31605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen"""
41605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen
51605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chenimport lldb
630425e9677342cff9995cd4937fdc12354b6b24bJohnny Chenimport sys
730425e9677342cff9995cd4937fdc12354b6b24bJohnny Chenimport StringIO
81605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen
984a6d6f10f3010accf9b717b2995f9acb6bee60cJohnny Chen################################################
1084a6d6f10f3010accf9b717b2995f9acb6bee60cJohnny Chen#                                              #
1184a6d6f10f3010accf9b717b2995f9acb6bee60cJohnny Chen# Iterator for lldb aggregate data structures. #
1284a6d6f10f3010accf9b717b2995f9acb6bee60cJohnny Chen#                                              #
1384a6d6f10f3010accf9b717b2995f9acb6bee60cJohnny Chen################################################
1484a6d6f10f3010accf9b717b2995f9acb6bee60cJohnny Chen
154d72c746131d8ae86217dfb35edc2e4417330b7bJohnny Chendef lldb_iter(obj, getsize, getelem):
16164bf887534ab18c939dc46525efb3db9de2613dJohnny Chen    """
17164bf887534ab18c939dc46525efb3db9de2613dJohnny Chen    A generator adaptor for lldb aggregate data structures.
18164bf887534ab18c939dc46525efb3db9de2613dJohnny Chen
194d72c746131d8ae86217dfb35edc2e4417330b7bJohnny Chen    API clients pass in the aggregate object, the name of the method to get the
204d72c746131d8ae86217dfb35edc2e4417330b7bJohnny Chen    size of the object, and the name of the method to get the element given an
214d72c746131d8ae86217dfb35edc2e4417330b7bJohnny Chen    index.
22164bf887534ab18c939dc46525efb3db9de2613dJohnny Chen
23164bf887534ab18c939dc46525efb3db9de2613dJohnny Chen    Example usage:
24164bf887534ab18c939dc46525efb3db9de2613dJohnny Chen
25164bf887534ab18c939dc46525efb3db9de2613dJohnny Chen    def disassemble_instructions (insts):
264d72c746131d8ae86217dfb35edc2e4417330b7bJohnny Chen        from lldbutil import lldb_iter
274d72c746131d8ae86217dfb35edc2e4417330b7bJohnny Chen        for i in lldb_iter(insts, 'GetSize', 'GetInstructionAtIndex'):
28164bf887534ab18c939dc46525efb3db9de2613dJohnny Chen            print i
29164bf887534ab18c939dc46525efb3db9de2613dJohnny Chen    """
304d72c746131d8ae86217dfb35edc2e4417330b7bJohnny Chen    size = getattr(obj, getsize)
314d72c746131d8ae86217dfb35edc2e4417330b7bJohnny Chen    elem = getattr(obj, getelem)
324d72c746131d8ae86217dfb35edc2e4417330b7bJohnny Chen    for i in range(size()):
334d72c746131d8ae86217dfb35edc2e4417330b7bJohnny Chen        yield elem(i)
34164bf887534ab18c939dc46525efb3db9de2613dJohnny Chen
35164bf887534ab18c939dc46525efb3db9de2613dJohnny Chen
36be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen########################################################
37be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen#                                                      #
38be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen# Convert some enum value to its string's counterpart. #
39be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen#                                                      #
40be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen########################################################
41be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen
42be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chendef StateTypeString(enum):
43be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    """Returns the stateType string given an enum."""
44be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    if enum == lldb.eStateInvalid:
45be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen        return "Invalid"
46be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    elif enum == lldb.eStateUnloaded:
47be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen        return "Unloaded"
48be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    elif enum == lldb.eStateAttaching:
49be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen        return "Attaching"
50be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    elif enum == lldb.eStateLaunching:
51be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen        return "Launching"
52be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    elif enum == lldb.eStateStopped:
53be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen        return "Stopped"
54be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    elif enum == lldb.eStateRunning:
55be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen        return "Running"
56be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    elif enum == lldb.eStateStepping:
57be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen        return "Stepping"
58be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    elif enum == lldb.eStateCrashed:
59be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen        return "Crashed"
60be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    elif enum == lldb.eStateDetached:
61be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen        return "Detached"
62be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    elif enum == lldb.eStateExited:
63be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen        return "Exited"
64be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    elif enum == lldb.eStateSuspended:
65be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen        return "Suspended"
66be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    else:
67be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen        raise Exception("Unknown stopReason enum")
68be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen
69be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chendef StopReasonString(enum):
70be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    """Returns the stopReason string given an enum."""
71be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    if enum == lldb.eStopReasonInvalid:
72be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen        return "Invalid"
73be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    elif enum == lldb.eStopReasonNone:
74be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen        return "None"
75be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    elif enum == lldb.eStopReasonTrace:
76be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen        return "Trace"
77be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    elif enum == lldb.eStopReasonBreakpoint:
78be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen        return "Breakpoint"
79be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    elif enum == lldb.eStopReasonWatchpoint:
80be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen        return "Watchpoint"
81be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    elif enum == lldb.eStopReasonSignal:
82be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen        return "Signal"
83be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    elif enum == lldb.eStopReasonException:
84be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen        return "Exception"
85be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    elif enum == lldb.eStopReasonPlanComplete:
86be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen        return "PlanComplete"
87be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen    else:
88be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen        raise Exception("Unknown stopReason enum")
89be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen
90be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen
91be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen#######################################################
92be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen#                                                     #
93be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen# Utility functions related to Threads and Processes. #
94be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen#                                                     #
95be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen#######################################################
96be683bc054db1f6c7fbe2bbf712266f9f70c6389Johnny Chen
971605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chendef GetFunctionNames(thread):
981605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    """
991605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    Returns a sequence of function names from the stack frames of this thread.
1001605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    """
1011605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    def GetFuncName(i):
1021605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen        return thread.GetFrameAtIndex(i).GetFunction().GetName()
1031605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen
1041605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    return map(GetFuncName, range(thread.GetNumFrames()))
1051605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen
1061605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen
107b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chendef GetSymbolNames(thread):
108b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen    """
109b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen    Returns a sequence of symbols for this thread.
110b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen    """
111b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen    def GetSymbol(i):
112b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen        return thread.GetFrameAtIndex(i).GetSymbol().GetName()
113b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen
114b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen    return map(GetSymbol, range(thread.GetNumFrames()))
115b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen
116b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen
117b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chendef GetPCAddresses(thread):
118b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen    """
119b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen    Returns a sequence of pc addresses for this thread.
120b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen    """
121b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen    def GetPCAddress(i):
122b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen        return thread.GetFrameAtIndex(i).GetPCAddress()
123b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen
124b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen    return map(GetPCAddress, range(thread.GetNumFrames()))
125b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen
126b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen
1271605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chendef GetFilenames(thread):
1281605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    """
1291605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    Returns a sequence of file names from the stack frames of this thread.
1301605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    """
1311605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    def GetFilename(i):
1321605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen        return thread.GetFrameAtIndex(i).GetLineEntry().GetFileSpec().GetFilename()
1331605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen
1341605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    return map(GetFilename, range(thread.GetNumFrames()))
1351605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen
1361605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen
1371605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chendef GetLineNumbers(thread):
1381605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    """
1391605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    Returns a sequence of line numbers from the stack frames of this thread.
1401605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    """
1411605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    def GetLineNumber(i):
1421605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen        return thread.GetFrameAtIndex(i).GetLineEntry().GetLine()
1431605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen
1441605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    return map(GetLineNumber, range(thread.GetNumFrames()))
1451605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen
1461605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen
1471605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chendef GetModuleNames(thread):
1481605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    """
1491605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    Returns a sequence of module names from the stack frames of this thread.
1501605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    """
1511605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    def GetModuleName(i):
1521605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen        return thread.GetFrameAtIndex(i).GetModule().GetFileSpec().GetFilename()
1531605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen
1541605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    return map(GetModuleName, range(thread.GetNumFrames()))
1551605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen
1561605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen
15788866ac481cd5533c18e00233aeced2eb1fce42bJohnny Chendef GetStackFrames(thread):
15888866ac481cd5533c18e00233aeced2eb1fce42bJohnny Chen    """
15988866ac481cd5533c18e00233aeced2eb1fce42bJohnny Chen    Returns a sequence of stack frames for this thread.
16088866ac481cd5533c18e00233aeced2eb1fce42bJohnny Chen    """
16188866ac481cd5533c18e00233aeced2eb1fce42bJohnny Chen    def GetStackFrame(i):
16288866ac481cd5533c18e00233aeced2eb1fce42bJohnny Chen        return thread.GetFrameAtIndex(i)
16388866ac481cd5533c18e00233aeced2eb1fce42bJohnny Chen
16488866ac481cd5533c18e00233aeced2eb1fce42bJohnny Chen    return map(GetStackFrame, range(thread.GetNumFrames()))
16588866ac481cd5533c18e00233aeced2eb1fce42bJohnny Chen
16688866ac481cd5533c18e00233aeced2eb1fce42bJohnny Chen
16730425e9677342cff9995cd4937fdc12354b6b24bJohnny Chendef PrintStackTrace(thread, string_buffer = False):
1681605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    """Prints a simple stack trace of this thread."""
16930425e9677342cff9995cd4937fdc12354b6b24bJohnny Chen
170b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen    output = StringIO.StringIO() if string_buffer else sys.stdout
171b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen    target = thread.GetProcess().GetTarget()
172b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen
1731605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    depth = thread.GetNumFrames()
1741605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen
1751605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    mods = GetModuleNames(thread)
1761605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    funcs = GetFunctionNames(thread)
177b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen    symbols = GetSymbolNames(thread)
1781605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    files = GetFilenames(thread)
1791605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen    lines = GetLineNumbers(thread)
180b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen    addrs = GetPCAddresses(thread)
18130425e9677342cff9995cd4937fdc12354b6b24bJohnny Chen
18230425e9677342cff9995cd4937fdc12354b6b24bJohnny Chen    print >> output, "Stack trace for thread id={0:#x} name={1} queue={2}:".format(
1831605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen        thread.GetThreadID(), thread.GetName(), thread.GetQueueName())
1841605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen
185b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen    for i in range(depth):
186b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen        frame = thread.GetFrameAtIndex(i)
187b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen        function = frame.GetFunction()
188b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen
189b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen        load_addr = addrs[i].GetLoadAddress(target)
190b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen        if not function.IsValid():
191b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen            file_addr = addrs[i].GetFileAddress()
192b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen            print >> output, "  frame #{num}: {addr:#016x} {mod}`{symbol} + ????".format(
193b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen                num=i, addr=load_addr, mod=mods[i], symbol=symbols[i])
194b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen        else:
195b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen            print >> output, "  frame #{num}: {addr:#016x} {mod}`{func} at {file}:{line}".format(
196b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen                num=i, addr=load_addr, mod=mods[i], func=funcs[i], file=files[i], line=lines[i])
197b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen
198b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen    if string_buffer:
199b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen        return output.getvalue()
200b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen
201b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen
202b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chendef PrintStackTraces(process, string_buffer = False):
203b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen    """Prints the stack traces of all the threads."""
204b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen
205b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen    output = StringIO.StringIO() if string_buffer else sys.stdout
206b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen
207b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen    print >> output, "Stack traces for " + repr(process)
2081605cf6d06d95bfe381693ced84a216899ecac6fJohnny Chen
209b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen    for i in range(process.GetNumThreads()):
210b51d87d4b31ca2bf024633d03aeeba8e095745e3Johnny Chen        print >> output, PrintStackTrace(process.GetThreadAtIndex(i), string_buffer=True)
21130425e9677342cff9995cd4937fdc12354b6b24bJohnny Chen
21230425e9677342cff9995cd4937fdc12354b6b24bJohnny Chen    if string_buffer:
21330425e9677342cff9995cd4937fdc12354b6b24bJohnny Chen        return output.getvalue()
214