def symtab_access_python(self): """Test symbol table access with Python APIs.""" exe = os.path.join(os.getcwd(), "a.out") self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) target = self.dbg.CreateTarget(exe) self.assertTrue(target.IsValid(), VALID_TARGET) # Launch the process, and do not stop at the entry point. error = lldb.SBError() process = target.Launch (self.dbg.GetListener(), None, None, os.ctermid(), os.ctermid(), os.ctermid(), None, 0, False, error) # # Exercise Python APIs to access the symbol table entries. # # Create the filespec by which to locate our a.out module. filespec = lldb.SBFileSpec(exe, False) module = target.FindModule(filespec) self.assertTrue(module.IsValid(), VALID_MODULE) # Create the set of known symbols. As we iterate through the symbol # table, remove the symbol from the set if it is a known symbol. expected_symbols = set(self.symbols_list) from lldbutil import lldb_iter for symbol in lldb_iter(module, 'GetNumSymbols', 'GetSymbolAtIndex'): self.assertTrue(symbol.IsValid(), VALID_SYMBOL) #print "symbol:", symbol name = symbol.GetName() if name in expected_symbols: #print "Removing %s from known_symbols %s" % (name, expected_symbols) expected_symbols.remove(name) # At this point, the known_symbols set should have become an empty set. # If not, raise an error. #print "symbols unaccounted for:", expected_symbols self.assertTrue(len(expected_symbols) == 0, "All the known symbols are accounted for")
def disassemble_call_stack_python(self): """Disassemble each call frame when stopped on C's constructor.""" self.breakOnCtor() # Now use the Python API to get at each function on the call stack and # disassemble it. target = self.dbg.GetSelectedTarget() process = target.GetProcess() thread = process.GetThreadAtIndex(0) depth = thread.GetNumFrames() for i in range(depth - 1): frame = thread.GetFrameAtIndex(i) function = frame.GetFunction() # Print the function header. print print function if function.IsValid(): # Get all instructions for this function and print them out. insts = function.GetInstructions(target) from lldbutil import lldb_iter for i in lldb_iter(insts, 'GetSize', 'GetInstructionAtIndex'): print i
def do_get_arg_vals(self): """Get argument vals for the call stack when stopped on a breakpoint.""" exe = os.path.join(os.getcwd(), "a.out") # Create a target by the debugger. target = self.dbg.CreateTarget(exe) self.assertTrue(target.IsValid(), VALID_TARGET) # Now create a breakpoint on main.c by name 'c'. breakpoint = target.BreakpointCreateByName('c', 'a.out') #print "breakpoint:", breakpoint self.assertTrue(breakpoint.IsValid() and breakpoint.GetNumLocations() == 1, VALID_BREAKPOINT) # Now launch the process, and do not stop at the entry point. # Note that we don't assign the process to self.process as in other test # cases. We want the inferior to run till it exits and there's no need # for the testing framework to kill the inferior upon tearDown(). error = lldb.SBError() process = target.Launch (self.dbg.GetListener(), None, None, os.ctermid(), os.ctermid(), os.ctermid(), None, 0, False, error) process = target.GetProcess() self.assertTrue(process.GetState() == lldb.eStateStopped, PROCESS_STOPPED) # Keeps track of the number of times 'a' is called where it is within a # depth of 3 of the 'c' leaf function. callsOfA = 0 import StringIO session = StringIO.StringIO() while process.GetState() == lldb.eStateStopped: thread = process.GetThreadAtIndex(0) # Inspect at most 3 frames. numFrames = min(3, thread.GetNumFrames()) for i in range(numFrames): frame = thread.GetFrameAtIndex(i) print "frame:", frame #print "frame.FindValue('val', lldb.eValueTypeVariableArgument)", frame.FindValue('val', lldb.eValueTypeVariableArgument).GetValue(frame) #print "frame.FindValue('ch', lldb.eValueTypeVariableArgument)", frame.FindValue('ch', lldb.eValueTypeVariableArgument).GetValue(frame) #print "frame.EvaluateExpression('val'):", frame.EvaluateExpression('val').GetValue(frame) #print "frame.EvaluateExpression('ch'):", frame.EvaluateExpression('ch').GetValue(frame) name = frame.GetFunction().GetName() if name == 'a': callsOfA = callsOfA + 1 # We'll inspect only the arguments for the current frame: # # arguments => True # locals => False # statics => False # in_scope_only => True valList = frame.GetVariables(True, False, False, True) argList = [] from lldbutil import lldb_iter for val in lldb_iter(valList, 'GetSize', 'GetValueAtIndex'): #self.DebugSBValue(frame, val) argList.append("(%s)%s=%s" % (val.GetTypeName(), val.GetName(), val.GetValue(frame))) print >> session, "%s(%s)" % (name, ", ".join(argList)) print >> session, "---" process.Continue() # At this point, the inferior process should have exited. self.assertTrue(process.GetState() == lldb.eStateExited, PROCESS_EXITED) # Expect to find 'a' on the call stacks two times. self.assertTrue(callsOfA == 2, "Expect to find 'a' on the call stacks two times") # By design, the 'a' call frame has the following arg vals: # o a((int)val=1, (char)ch='A') # o a((int)val=3, (char)ch='A') print "Full stack traces when stopped on the breakpoint 'c':" print session.getvalue() self.expect(session.getvalue(), "Argugment values displayed correctly", exe=False, substrs = ["a((int)val=1, (char)ch='A')", "a((int)val=3, (char)ch='A')"])
def static_variable_python(self): """Test Python APIs on file and class static variables.""" exe = os.path.join(os.getcwd(), "a.out") target = self.dbg.CreateTarget(exe) self.assertTrue(target.IsValid(), VALID_TARGET) breakpoint = target.BreakpointCreateByLocation("main.cpp", self.line) self.assertTrue(breakpoint.IsValid(), VALID_BREAKPOINT) # Now launch the process, and do not stop at entry point. error = lldb.SBError() self.process = target.Launch( self.dbg.GetListener(), None, None, os.ctermid(), os.ctermid(), os.ctermid(), None, 0, False, error ) self.process = target.GetProcess() self.assertTrue(self.process.IsValid(), PROCESS_IS_VALID) # The stop reason of the thread should be breakpoint. thread = self.process.GetThreadAtIndex(0) if thread.GetStopReason() != lldb.eStopReasonBreakpoint: from lldbutil import StopReasonString self.fail(STOPPED_DUE_TO_BREAKPOINT_WITH_STOP_REASON_AS % StopReasonString(thread.GetStopReason())) # Get the SBValue of 'A::g_points' and 'g_points'. frame = thread.GetFrameAtIndex(0) # arguments => False # locals => False # statics => True # in_scope_only => False valList = frame.GetVariables(False, False, True, False) from lldbutil import lldb_iter for val in lldb_iter(valList, "GetSize", "GetValueAtIndex"): self.DebugSBValue(frame, val) self.assertTrue(val.GetValueType() == lldb.eValueTypeVariableGlobal) name = val.GetName() self.assertTrue(name in ["g_points", "A::g_points"]) if name == "g_points": self.assertTrue(val.GetNumChildren() == 2) elif name == "A::g_points" and self.getCompiler() in ["clang", "llvm-gcc"]: # On Mac OS X, gcc 4.2 emits the wrong debug info for A::g_points. self.assertTrue(val.GetNumChildren() == 2) child1 = val.GetChildAtIndex(1) self.DebugSBValue(frame, child1) child1_x = child1.GetChildAtIndex(0) self.DebugSBValue(frame, child1_x) self.assertTrue(child1_x.GetTypeName() == "int" and child1_x.GetValue(frame) == "11") # SBFrame.FindValue() should also work. val = frame.FindValue("A::g_points", lldb.eValueTypeVariableGlobal) self.DebugSBValue(frame, val) self.assertTrue(val.GetName() == "A::g_points") # Also exercise the "parameter" and "local" scopes while we are at it. val = frame.FindValue("argc", lldb.eValueTypeVariableArgument) self.DebugSBValue(frame, val) self.assertTrue(val.GetName() == "argc") val = frame.FindValue("argv", lldb.eValueTypeVariableArgument) self.DebugSBValue(frame, val) self.assertTrue(val.GetName() == "argv") val = frame.FindValue("hello_world", lldb.eValueTypeVariableLocal) self.DebugSBValue(frame, val) self.assertTrue(val.GetName() == "hello_world")