199451b44SJordan Rupprecht""" 299451b44SJordan RupprechtUse lldb Python SBFrame API to get the argument values of the call stacks. 399451b44SJordan RupprechtAnd other SBFrame API tests. 499451b44SJordan Rupprecht""" 599451b44SJordan Rupprecht 699451b44SJordan Rupprechtfrom __future__ import print_function 799451b44SJordan Rupprecht 899451b44SJordan Rupprecht 999451b44SJordan Rupprechtimport lldb 1099451b44SJordan Rupprechtfrom lldbsuite.test.decorators import * 1199451b44SJordan Rupprechtfrom lldbsuite.test.lldbtest import * 1299451b44SJordan Rupprechtfrom lldbsuite.test import lldbutil 1399451b44SJordan Rupprecht 1499451b44SJordan Rupprecht 1599451b44SJordan Rupprechtclass FrameAPITestCase(TestBase): 1699451b44SJordan Rupprecht 1799451b44SJordan Rupprecht mydir = TestBase.compute_mydir(__file__) 1899451b44SJordan Rupprecht 1999451b44SJordan Rupprecht @add_test_categories(['pyapi']) 2099451b44SJordan Rupprecht def test_get_arg_vals_for_call_stack(self): 2199451b44SJordan Rupprecht """Exercise SBFrame.GetVariables() API to get argument vals.""" 2299451b44SJordan Rupprecht self.build() 2399451b44SJordan Rupprecht exe = self.getBuildArtifact("a.out") 2499451b44SJordan Rupprecht 2599451b44SJordan Rupprecht # Create a target by the debugger. 2699451b44SJordan Rupprecht target = self.dbg.CreateTarget(exe) 2799451b44SJordan Rupprecht self.assertTrue(target, VALID_TARGET) 2899451b44SJordan Rupprecht 2999451b44SJordan Rupprecht # Now create a breakpoint on main.c by name 'c'. 3099451b44SJordan Rupprecht breakpoint = target.BreakpointCreateByName('c', 'a.out') 31*b321b429SJonas Devlieghere self.trace("breakpoint:", breakpoint) 3299451b44SJordan Rupprecht self.assertTrue(breakpoint and 3399451b44SJordan Rupprecht breakpoint.GetNumLocations() == 1, 3499451b44SJordan Rupprecht VALID_BREAKPOINT) 3599451b44SJordan Rupprecht 3699451b44SJordan Rupprecht # Now launch the process, and do not stop at the entry point. 3799451b44SJordan Rupprecht process = target.LaunchSimple( 3899451b44SJordan Rupprecht None, None, self.get_process_working_directory()) 3999451b44SJordan Rupprecht 4099451b44SJordan Rupprecht process = target.GetProcess() 4199451b44SJordan Rupprecht self.assertTrue(process.GetState() == lldb.eStateStopped, 4299451b44SJordan Rupprecht PROCESS_STOPPED) 4399451b44SJordan Rupprecht 4499451b44SJordan Rupprecht # Keeps track of the number of times 'a' is called where it is within a 4599451b44SJordan Rupprecht # depth of 3 of the 'c' leaf function. 4699451b44SJordan Rupprecht callsOfA = 0 4799451b44SJordan Rupprecht 4899451b44SJordan Rupprecht from six import StringIO as SixStringIO 4999451b44SJordan Rupprecht session = SixStringIO() 5099451b44SJordan Rupprecht while process.GetState() == lldb.eStateStopped: 5199451b44SJordan Rupprecht thread = lldbutil.get_stopped_thread( 5299451b44SJordan Rupprecht process, lldb.eStopReasonBreakpoint) 5399451b44SJordan Rupprecht self.assertIsNotNone(thread) 5499451b44SJordan Rupprecht # Inspect at most 3 frames. 5599451b44SJordan Rupprecht numFrames = min(3, thread.GetNumFrames()) 5699451b44SJordan Rupprecht for i in range(numFrames): 5799451b44SJordan Rupprecht frame = thread.GetFrameAtIndex(i) 5899451b44SJordan Rupprecht if self.TraceOn(): 5999451b44SJordan Rupprecht print("frame:", frame) 6099451b44SJordan Rupprecht 6199451b44SJordan Rupprecht name = frame.GetFunction().GetName() 6299451b44SJordan Rupprecht if name == 'a': 6399451b44SJordan Rupprecht callsOfA = callsOfA + 1 6499451b44SJordan Rupprecht 6599451b44SJordan Rupprecht # We'll inspect only the arguments for the current frame: 6699451b44SJordan Rupprecht # 6799451b44SJordan Rupprecht # arguments => True 6899451b44SJordan Rupprecht # locals => False 6999451b44SJordan Rupprecht # statics => False 7099451b44SJordan Rupprecht # in_scope_only => True 7199451b44SJordan Rupprecht valList = frame.GetVariables(True, False, False, True) 7299451b44SJordan Rupprecht argList = [] 7399451b44SJordan Rupprecht for val in valList: 7499451b44SJordan Rupprecht argList.append("(%s)%s=%s" % (val.GetTypeName(), 7599451b44SJordan Rupprecht val.GetName(), 7699451b44SJordan Rupprecht val.GetValue())) 7799451b44SJordan Rupprecht print("%s(%s)" % (name, ", ".join(argList)), file=session) 7899451b44SJordan Rupprecht 7999451b44SJordan Rupprecht # Also check the generic pc & stack pointer. We can't test their absolute values, 8099451b44SJordan Rupprecht # but they should be valid. Uses get_GPRs() from the lldbutil 8199451b44SJordan Rupprecht # module. 8299451b44SJordan Rupprecht gpr_reg_set = lldbutil.get_GPRs(frame) 8399451b44SJordan Rupprecht pc_value = gpr_reg_set.GetChildMemberWithName("pc") 8499451b44SJordan Rupprecht self.assertTrue(pc_value, "We should have a valid PC.") 8599451b44SJordan Rupprecht pc_value_int = int(pc_value.GetValue(), 0) 8699451b44SJordan Rupprecht # Make sure on arm targets we dont mismatch PC value on the basis of thumb bit. 8799451b44SJordan Rupprecht # Frame PC will not have thumb bit set in case of a thumb 8899451b44SJordan Rupprecht # instruction as PC. 8999451b44SJordan Rupprecht if self.getArchitecture() in ['arm', 'armv7', 'armv7k']: 9099451b44SJordan Rupprecht pc_value_int &= ~1 9199451b44SJordan Rupprecht self.assertTrue( 9299451b44SJordan Rupprecht pc_value_int == frame.GetPC(), 9399451b44SJordan Rupprecht "PC gotten as a value should equal frame's GetPC") 9499451b44SJordan Rupprecht sp_value = gpr_reg_set.GetChildMemberWithName("sp") 9599451b44SJordan Rupprecht self.assertTrue( 9699451b44SJordan Rupprecht sp_value, "We should have a valid Stack Pointer.") 9799451b44SJordan Rupprecht self.assertTrue(int(sp_value.GetValue(), 0) == frame.GetSP( 9899451b44SJordan Rupprecht ), "SP gotten as a value should equal frame's GetSP") 9999451b44SJordan Rupprecht 10099451b44SJordan Rupprecht print("---", file=session) 10199451b44SJordan Rupprecht process.Continue() 10299451b44SJordan Rupprecht 10399451b44SJordan Rupprecht # At this point, the inferior process should have exited. 10499451b44SJordan Rupprecht self.assertTrue( 10599451b44SJordan Rupprecht process.GetState() == lldb.eStateExited, 10699451b44SJordan Rupprecht PROCESS_EXITED) 10799451b44SJordan Rupprecht 10899451b44SJordan Rupprecht # Expect to find 'a' on the call stacks two times. 10999451b44SJordan Rupprecht self.assertTrue(callsOfA == 2, 11099451b44SJordan Rupprecht "Expect to find 'a' on the call stacks two times") 11199451b44SJordan Rupprecht # By design, the 'a' call frame has the following arg vals: 11299451b44SJordan Rupprecht # o a((int)val=1, (char)ch='A') 11399451b44SJordan Rupprecht # o a((int)val=3, (char)ch='A') 11499451b44SJordan Rupprecht if self.TraceOn(): 11599451b44SJordan Rupprecht print("Full stack traces when stopped on the breakpoint 'c':") 11699451b44SJordan Rupprecht print(session.getvalue()) 117e9264b74SKazuaki Ishizaki self.expect(session.getvalue(), "Argument values displayed correctly", 11899451b44SJordan Rupprecht exe=False, 11999451b44SJordan Rupprecht substrs=["a((int)val=1, (char)ch='A')", 12099451b44SJordan Rupprecht "a((int)val=3, (char)ch='A')"]) 12199451b44SJordan Rupprecht 12299451b44SJordan Rupprecht @add_test_categories(['pyapi']) 12399451b44SJordan Rupprecht def test_frame_api_boundary_condition(self): 12499451b44SJordan Rupprecht """Exercise SBFrame APIs with boundary condition inputs.""" 12599451b44SJordan Rupprecht self.build() 12699451b44SJordan Rupprecht exe = self.getBuildArtifact("a.out") 12799451b44SJordan Rupprecht 12899451b44SJordan Rupprecht # Create a target by the debugger. 12999451b44SJordan Rupprecht target = self.dbg.CreateTarget(exe) 13099451b44SJordan Rupprecht self.assertTrue(target, VALID_TARGET) 13199451b44SJordan Rupprecht 13299451b44SJordan Rupprecht # Now create a breakpoint on main.c by name 'c'. 13399451b44SJordan Rupprecht breakpoint = target.BreakpointCreateByName('c', 'a.out') 134*b321b429SJonas Devlieghere self.trace("breakpoint:", breakpoint) 13599451b44SJordan Rupprecht self.assertTrue(breakpoint and 13699451b44SJordan Rupprecht breakpoint.GetNumLocations() == 1, 13799451b44SJordan Rupprecht VALID_BREAKPOINT) 13899451b44SJordan Rupprecht 13999451b44SJordan Rupprecht # Now launch the process, and do not stop at the entry point. 14099451b44SJordan Rupprecht process = target.LaunchSimple( 14199451b44SJordan Rupprecht None, None, self.get_process_working_directory()) 14299451b44SJordan Rupprecht 14399451b44SJordan Rupprecht process = target.GetProcess() 14499451b44SJordan Rupprecht self.assertTrue(process.GetState() == lldb.eStateStopped, 14599451b44SJordan Rupprecht PROCESS_STOPPED) 14699451b44SJordan Rupprecht 14799451b44SJordan Rupprecht thread = lldbutil.get_stopped_thread( 14899451b44SJordan Rupprecht process, lldb.eStopReasonBreakpoint) 14999451b44SJordan Rupprecht self.assertIsNotNone(thread) 15099451b44SJordan Rupprecht frame = thread.GetFrameAtIndex(0) 15199451b44SJordan Rupprecht if self.TraceOn(): 15299451b44SJordan Rupprecht print("frame:", frame) 15399451b44SJordan Rupprecht 15499451b44SJordan Rupprecht # Boundary condition testings. 15599451b44SJordan Rupprecht val1 = frame.FindVariable(None, True) 15699451b44SJordan Rupprecht val2 = frame.FindVariable(None, False) 15799451b44SJordan Rupprecht val3 = frame.FindValue(None, lldb.eValueTypeVariableGlobal) 15899451b44SJordan Rupprecht if self.TraceOn(): 15999451b44SJordan Rupprecht print("val1:", val1) 16099451b44SJordan Rupprecht print("val2:", val2) 16199451b44SJordan Rupprecht 16299451b44SJordan Rupprecht frame.EvaluateExpression(None) 16399451b44SJordan Rupprecht 16499451b44SJordan Rupprecht @add_test_categories(['pyapi']) 16599451b44SJordan Rupprecht def test_frame_api_IsEqual(self): 16699451b44SJordan Rupprecht """Exercise SBFrame API IsEqual.""" 16799451b44SJordan Rupprecht self.build() 16899451b44SJordan Rupprecht exe = self.getBuildArtifact("a.out") 16999451b44SJordan Rupprecht 17099451b44SJordan Rupprecht # Create a target by the debugger. 17199451b44SJordan Rupprecht target = self.dbg.CreateTarget(exe) 17299451b44SJordan Rupprecht self.assertTrue(target, VALID_TARGET) 17399451b44SJordan Rupprecht 17499451b44SJordan Rupprecht # Now create a breakpoint on main.c by name 'c'. 17599451b44SJordan Rupprecht breakpoint = target.BreakpointCreateByName('c', 'a.out') 176*b321b429SJonas Devlieghere self.trace("breakpoint:", breakpoint) 17799451b44SJordan Rupprecht self.assertTrue(breakpoint and 17899451b44SJordan Rupprecht breakpoint.GetNumLocations() == 1, 17999451b44SJordan Rupprecht VALID_BREAKPOINT) 18099451b44SJordan Rupprecht 18199451b44SJordan Rupprecht # Now launch the process, and do not stop at the entry point. 18299451b44SJordan Rupprecht process = target.LaunchSimple( 18399451b44SJordan Rupprecht None, None, self.get_process_working_directory()) 18499451b44SJordan Rupprecht 18599451b44SJordan Rupprecht process = target.GetProcess() 18699451b44SJordan Rupprecht self.assertTrue(process.GetState() == lldb.eStateStopped, 18799451b44SJordan Rupprecht PROCESS_STOPPED) 18899451b44SJordan Rupprecht 18999451b44SJordan Rupprecht thread = lldbutil.get_stopped_thread( 19099451b44SJordan Rupprecht process, lldb.eStopReasonBreakpoint) 19199451b44SJordan Rupprecht self.assertIsNotNone(thread) 19299451b44SJordan Rupprecht 19399451b44SJordan Rupprecht frameEntered = thread.GetFrameAtIndex(0) 19499451b44SJordan Rupprecht if self.TraceOn(): 19599451b44SJordan Rupprecht print(frameEntered) 19699451b44SJordan Rupprecht lldbutil.print_stacktrace(thread) 19799451b44SJordan Rupprecht self.assertTrue(frameEntered) 19899451b44SJordan Rupprecht 19999451b44SJordan Rupprecht # Doing two step overs while still inside c(). 20099451b44SJordan Rupprecht thread.StepOver() 20199451b44SJordan Rupprecht thread.StepOver() 20299451b44SJordan Rupprecht self.assertTrue(thread) 20399451b44SJordan Rupprecht frameNow = thread.GetFrameAtIndex(0) 20499451b44SJordan Rupprecht if self.TraceOn(): 20599451b44SJordan Rupprecht print(frameNow) 20699451b44SJordan Rupprecht lldbutil.print_stacktrace(thread) 20799451b44SJordan Rupprecht self.assertTrue(frameNow) 20899451b44SJordan Rupprecht 20999451b44SJordan Rupprecht # The latest two frames are considered equal. 21099451b44SJordan Rupprecht self.assertTrue(frameEntered.IsEqual(frameNow)) 21199451b44SJordan Rupprecht 21299451b44SJordan Rupprecht # Now let's step out of frame c(). 21399451b44SJordan Rupprecht thread.StepOutOfFrame(frameNow) 21499451b44SJordan Rupprecht frameOutOfC = thread.GetFrameAtIndex(0) 21599451b44SJordan Rupprecht if self.TraceOn(): 21699451b44SJordan Rupprecht print(frameOutOfC) 21799451b44SJordan Rupprecht lldbutil.print_stacktrace(thread) 21899451b44SJordan Rupprecht self.assertTrue(frameOutOfC) 21999451b44SJordan Rupprecht 22099451b44SJordan Rupprecht # The latest two frames should not be equal. 22199451b44SJordan Rupprecht self.assertFalse(frameOutOfC.IsEqual(frameNow)) 222