Add a test case which uses the SBProcess and SBThread APIs to iterate through
the threads and print their stack traces when stopped on a breakpoint.
Add a PrintStackTraces(process) utility function into the lldbutil.py module.
git-svn-id: https://llvm.org/svn/llvm-project/llvdb/trunk@115983 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/lldbutil.py b/test/lldbutil.py
index 9ff2c26..1e0bcd3 100644
--- a/test/lldbutil.py
+++ b/test/lldbutil.py
@@ -1,5 +1,5 @@
"""
-LLDB modules which contains miscellaneous utilities.
+This LLDB module contains miscellaneous utilities.
"""
import lldb
@@ -16,6 +16,26 @@
return map(GetFuncName, range(thread.GetNumFrames()))
+def GetSymbolNames(thread):
+ """
+ Returns a sequence of symbols for this thread.
+ """
+ def GetSymbol(i):
+ return thread.GetFrameAtIndex(i).GetSymbol().GetName()
+
+ return map(GetSymbol, range(thread.GetNumFrames()))
+
+
+def GetPCAddresses(thread):
+ """
+ Returns a sequence of pc addresses for this thread.
+ """
+ def GetPCAddress(i):
+ return thread.GetFrameAtIndex(i).GetPCAddress()
+
+ return map(GetPCAddress, range(thread.GetNumFrames()))
+
+
def GetFilenames(thread):
"""
Returns a sequence of file names from the stack frames of this thread.
@@ -59,23 +79,47 @@
def PrintStackTrace(thread, string_buffer = False):
"""Prints a simple stack trace of this thread."""
+ output = StringIO.StringIO() if string_buffer else sys.stdout
+ target = thread.GetProcess().GetTarget()
+
depth = thread.GetNumFrames()
mods = GetModuleNames(thread)
funcs = GetFunctionNames(thread)
+ symbols = GetSymbolNames(thread)
files = GetFilenames(thread)
lines = GetLineNumbers(thread)
-
- output = StringIO.StringIO() if string_buffer else sys.stdout
+ addrs = GetPCAddresses(thread)
print >> output, "Stack trace for thread id={0:#x} name={1} queue={2}:".format(
thread.GetThreadID(), thread.GetName(), thread.GetQueueName())
- for i in range(depth - 1):
- print >> output, " frame #{num}: {mod}`{func} at {file}:{line}".format(
- num=i, mod=mods[i], func=funcs[i], file=files[i], line=lines[i])
+ for i in range(depth):
+ frame = thread.GetFrameAtIndex(i)
+ function = frame.GetFunction()
- print >> output, " frame #{num}: {mod}`start".format(num=depth-1, mod=mods[depth-1])
+ load_addr = addrs[i].GetLoadAddress(target)
+ if not function.IsValid():
+ file_addr = addrs[i].GetFileAddress()
+ print >> output, " frame #{num}: {addr:#016x} {mod}`{symbol} + ????".format(
+ num=i, addr=load_addr, mod=mods[i], symbol=symbols[i])
+ else:
+ print >> output, " frame #{num}: {addr:#016x} {mod}`{func} at {file}:{line}".format(
+ num=i, addr=load_addr, mod=mods[i], func=funcs[i], file=files[i], line=lines[i])
+
+ if string_buffer:
+ return output.getvalue()
+
+
+def PrintStackTraces(process, string_buffer = False):
+ """Prints the stack traces of all the threads."""
+
+ output = StringIO.StringIO() if string_buffer else sys.stdout
+
+ print >> output, "Stack traces for " + repr(process)
+
+ for i in range(process.GetNumThreads()):
+ print >> output, PrintStackTrace(process.GetThreadAtIndex(i), string_buffer=True)
if string_buffer:
return output.getvalue()