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 656f9cfe3SDave Leeimport io 799451b44SJordan Rupprecht 899451b44SJordan Rupprechtimport lldb 999451b44SJordan Rupprechtfrom lldbsuite.test.decorators import * 1099451b44SJordan Rupprechtfrom lldbsuite.test.lldbtest import * 1199451b44SJordan Rupprechtfrom lldbsuite.test import lldbutil 1299451b44SJordan Rupprecht 1399451b44SJordan Rupprecht 1499451b44SJordan Rupprechtclass FrameAPITestCase(TestBase): 1599451b44SJordan Rupprecht def test_get_arg_vals_for_call_stack(self): 1699451b44SJordan Rupprecht """Exercise SBFrame.GetVariables() API to get argument vals.""" 1799451b44SJordan Rupprecht self.build() 1899451b44SJordan Rupprecht exe = self.getBuildArtifact("a.out") 1999451b44SJordan Rupprecht 2099451b44SJordan Rupprecht # Create a target by the debugger. 2199451b44SJordan Rupprecht target = self.dbg.CreateTarget(exe) 2299451b44SJordan Rupprecht self.assertTrue(target, VALID_TARGET) 2399451b44SJordan Rupprecht 2499451b44SJordan Rupprecht # Now create a breakpoint on main.c by name 'c'. 252238dcc3SJonas Devlieghere breakpoint = target.BreakpointCreateByName("c", "a.out") 26b321b429SJonas Devlieghere self.trace("breakpoint:", breakpoint) 272238dcc3SJonas Devlieghere self.assertTrue( 282238dcc3SJonas Devlieghere breakpoint and breakpoint.GetNumLocations() == 1, VALID_BREAKPOINT 292238dcc3SJonas Devlieghere ) 3099451b44SJordan Rupprecht 3199451b44SJordan Rupprecht # Now launch the process, and do not stop at the entry point. 322238dcc3SJonas Devlieghere process = target.LaunchSimple(None, None, self.get_process_working_directory()) 3399451b44SJordan Rupprecht 3499451b44SJordan Rupprecht process = target.GetProcess() 352238dcc3SJonas Devlieghere self.assertState(process.GetState(), lldb.eStateStopped, PROCESS_STOPPED) 3699451b44SJordan Rupprecht 3799451b44SJordan Rupprecht # Keeps track of the number of times 'a' is called where it is within a 3899451b44SJordan Rupprecht # depth of 3 of the 'c' leaf function. 3999451b44SJordan Rupprecht callsOfA = 0 4099451b44SJordan Rupprecht 4156f9cfe3SDave Lee session = io.StringIO() 4299451b44SJordan Rupprecht while process.GetState() == lldb.eStateStopped: 432238dcc3SJonas Devlieghere thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint) 4499451b44SJordan Rupprecht self.assertIsNotNone(thread) 4599451b44SJordan Rupprecht # Inspect at most 3 frames. 4699451b44SJordan Rupprecht numFrames = min(3, thread.GetNumFrames()) 4799451b44SJordan Rupprecht for i in range(numFrames): 4899451b44SJordan Rupprecht frame = thread.GetFrameAtIndex(i) 4999451b44SJordan Rupprecht if self.TraceOn(): 5099451b44SJordan Rupprecht print("frame:", frame) 5199451b44SJordan Rupprecht 5299451b44SJordan Rupprecht name = frame.GetFunction().GetName() 532238dcc3SJonas Devlieghere if name == "a": 5499451b44SJordan Rupprecht callsOfA = callsOfA + 1 5599451b44SJordan Rupprecht 5699451b44SJordan Rupprecht # We'll inspect only the arguments for the current frame: 5799451b44SJordan Rupprecht # 5899451b44SJordan Rupprecht # arguments => True 5999451b44SJordan Rupprecht # locals => False 6099451b44SJordan Rupprecht # statics => False 6199451b44SJordan Rupprecht # in_scope_only => True 6299451b44SJordan Rupprecht valList = frame.GetVariables(True, False, False, True) 6399451b44SJordan Rupprecht argList = [] 6499451b44SJordan Rupprecht for val in valList: 652238dcc3SJonas Devlieghere argList.append( 662238dcc3SJonas Devlieghere "(%s)%s=%s" % (val.GetTypeName(), val.GetName(), val.GetValue()) 672238dcc3SJonas Devlieghere ) 6899451b44SJordan Rupprecht print("%s(%s)" % (name, ", ".join(argList)), file=session) 6999451b44SJordan Rupprecht 7099451b44SJordan Rupprecht # Also check the generic pc & stack pointer. We can't test their absolute values, 7199451b44SJordan Rupprecht # but they should be valid. Uses get_GPRs() from the lldbutil 7299451b44SJordan Rupprecht # module. 7399451b44SJordan Rupprecht gpr_reg_set = lldbutil.get_GPRs(frame) 7499451b44SJordan Rupprecht pc_value = gpr_reg_set.GetChildMemberWithName("pc") 7599451b44SJordan Rupprecht self.assertTrue(pc_value, "We should have a valid PC.") 76*4b0beb4fSjimingham 77*4b0beb4fSjimingham 7899451b44SJordan Rupprecht # Make sure on arm targets we dont mismatch PC value on the basis of thumb bit. 7999451b44SJordan Rupprecht # Frame PC will not have thumb bit set in case of a thumb 8099451b44SJordan Rupprecht # instruction as PC. 81*4b0beb4fSjimingham pc_value_int = int(pc_value.GetValue(), 0) 822238dcc3SJonas Devlieghere if self.getArchitecture() in ["arm", "armv7", "armv7k"]: 8399451b44SJordan Rupprecht pc_value_int &= ~1 840ed758b2SDave Lee self.assertEqual( 852238dcc3SJonas Devlieghere pc_value_int, 862238dcc3SJonas Devlieghere frame.GetPC(), 872238dcc3SJonas Devlieghere "PC gotten as a value should equal frame's GetPC", 882238dcc3SJonas Devlieghere ) 8999451b44SJordan Rupprecht sp_value = gpr_reg_set.GetChildMemberWithName("sp") 902238dcc3SJonas Devlieghere self.assertTrue(sp_value, "We should have a valid Stack Pointer.") 91619e2e09SDave Lee self.assertEqual( 922238dcc3SJonas Devlieghere int(sp_value.GetValue(), 0), 932238dcc3SJonas Devlieghere frame.GetSP(), 942238dcc3SJonas Devlieghere "SP gotten as a value should equal frame's GetSP", 952238dcc3SJonas Devlieghere ) 96*4b0beb4fSjimingham # Test that the "register" property's flat list matches the list from 97*4b0beb4fSjimingham # the "registers" property that returns register sets: 98*4b0beb4fSjimingham register_regs = set() 99*4b0beb4fSjimingham flattened_regs = set() 100*4b0beb4fSjimingham for reg_set in frame.registers: 101*4b0beb4fSjimingham for reg in reg_set: 102*4b0beb4fSjimingham flattened_regs.add(reg.name) 103*4b0beb4fSjimingham for reg in frame.register: 104*4b0beb4fSjimingham register_regs.add(reg.name) 105*4b0beb4fSjimingham self.assertEqual(register_regs, flattened_regs, "register matches registers") 10699451b44SJordan Rupprecht 10799451b44SJordan Rupprecht print("---", file=session) 10899451b44SJordan Rupprecht process.Continue() 10999451b44SJordan Rupprecht 11099451b44SJordan Rupprecht # At this point, the inferior process should have exited. 1112238dcc3SJonas Devlieghere self.assertEqual(process.GetState(), lldb.eStateExited, PROCESS_EXITED) 11299451b44SJordan Rupprecht 11399451b44SJordan Rupprecht # Expect to find 'a' on the call stacks two times. 1142238dcc3SJonas Devlieghere self.assertEqual(callsOfA, 2, "Expect to find 'a' on the call stacks two times") 11599451b44SJordan Rupprecht # By design, the 'a' call frame has the following arg vals: 11699451b44SJordan Rupprecht # o a((int)val=1, (char)ch='A') 11799451b44SJordan Rupprecht # o a((int)val=3, (char)ch='A') 11899451b44SJordan Rupprecht if self.TraceOn(): 11999451b44SJordan Rupprecht print("Full stack traces when stopped on the breakpoint 'c':") 12099451b44SJordan Rupprecht print(session.getvalue()) 1212238dcc3SJonas Devlieghere self.expect( 1222238dcc3SJonas Devlieghere session.getvalue(), 1232238dcc3SJonas Devlieghere "Argument values displayed correctly", 12499451b44SJordan Rupprecht exe=False, 1252238dcc3SJonas Devlieghere substrs=["a((int)val=1, (char)ch='A')", "a((int)val=3, (char)ch='A')"], 1262238dcc3SJonas Devlieghere ) 12799451b44SJordan Rupprecht 12899451b44SJordan Rupprecht def test_frame_api_boundary_condition(self): 12999451b44SJordan Rupprecht """Exercise SBFrame APIs with boundary condition inputs.""" 13099451b44SJordan Rupprecht self.build() 13199451b44SJordan Rupprecht exe = self.getBuildArtifact("a.out") 13299451b44SJordan Rupprecht 13399451b44SJordan Rupprecht # Create a target by the debugger. 13499451b44SJordan Rupprecht target = self.dbg.CreateTarget(exe) 13599451b44SJordan Rupprecht self.assertTrue(target, VALID_TARGET) 13699451b44SJordan Rupprecht 13799451b44SJordan Rupprecht # Now create a breakpoint on main.c by name 'c'. 1382238dcc3SJonas Devlieghere breakpoint = target.BreakpointCreateByName("c", "a.out") 139b321b429SJonas Devlieghere self.trace("breakpoint:", breakpoint) 1402238dcc3SJonas Devlieghere self.assertTrue( 1412238dcc3SJonas Devlieghere breakpoint and breakpoint.GetNumLocations() == 1, VALID_BREAKPOINT 1422238dcc3SJonas Devlieghere ) 14399451b44SJordan Rupprecht 14499451b44SJordan Rupprecht # Now launch the process, and do not stop at the entry point. 1452238dcc3SJonas Devlieghere process = target.LaunchSimple(None, None, self.get_process_working_directory()) 14699451b44SJordan Rupprecht 14799451b44SJordan Rupprecht process = target.GetProcess() 1482238dcc3SJonas Devlieghere self.assertState(process.GetState(), lldb.eStateStopped, PROCESS_STOPPED) 14999451b44SJordan Rupprecht 1502238dcc3SJonas Devlieghere thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint) 15199451b44SJordan Rupprecht self.assertIsNotNone(thread) 15299451b44SJordan Rupprecht frame = thread.GetFrameAtIndex(0) 15399451b44SJordan Rupprecht if self.TraceOn(): 15499451b44SJordan Rupprecht print("frame:", frame) 15599451b44SJordan Rupprecht 15699451b44SJordan Rupprecht # Boundary condition testings. 15799451b44SJordan Rupprecht val1 = frame.FindVariable(None, True) 15899451b44SJordan Rupprecht val2 = frame.FindVariable(None, False) 15999451b44SJordan Rupprecht val3 = frame.FindValue(None, lldb.eValueTypeVariableGlobal) 16099451b44SJordan Rupprecht if self.TraceOn(): 16199451b44SJordan Rupprecht print("val1:", val1) 16299451b44SJordan Rupprecht print("val2:", val2) 16399451b44SJordan Rupprecht 16499451b44SJordan Rupprecht frame.EvaluateExpression(None) 16599451b44SJordan Rupprecht 16699451b44SJordan Rupprecht def test_frame_api_IsEqual(self): 16799451b44SJordan Rupprecht """Exercise SBFrame API IsEqual.""" 16899451b44SJordan Rupprecht self.build() 16999451b44SJordan Rupprecht exe = self.getBuildArtifact("a.out") 17099451b44SJordan Rupprecht 17199451b44SJordan Rupprecht # Create a target by the debugger. 17299451b44SJordan Rupprecht target = self.dbg.CreateTarget(exe) 17399451b44SJordan Rupprecht self.assertTrue(target, VALID_TARGET) 17499451b44SJordan Rupprecht 17599451b44SJordan Rupprecht # Now create a breakpoint on main.c by name 'c'. 1762238dcc3SJonas Devlieghere breakpoint = target.BreakpointCreateByName("c", "a.out") 177b321b429SJonas Devlieghere self.trace("breakpoint:", breakpoint) 1782238dcc3SJonas Devlieghere self.assertTrue( 1792238dcc3SJonas Devlieghere breakpoint and breakpoint.GetNumLocations() == 1, VALID_BREAKPOINT 1802238dcc3SJonas Devlieghere ) 18199451b44SJordan Rupprecht 18299451b44SJordan Rupprecht # Now launch the process, and do not stop at the entry point. 1832238dcc3SJonas Devlieghere process = target.LaunchSimple(None, None, self.get_process_working_directory()) 18499451b44SJordan Rupprecht 18599451b44SJordan Rupprecht process = target.GetProcess() 1862238dcc3SJonas Devlieghere self.assertState(process.GetState(), lldb.eStateStopped, PROCESS_STOPPED) 18799451b44SJordan Rupprecht 1882238dcc3SJonas Devlieghere thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint) 18999451b44SJordan Rupprecht self.assertIsNotNone(thread) 19099451b44SJordan Rupprecht 19199451b44SJordan Rupprecht frameEntered = thread.GetFrameAtIndex(0) 19299451b44SJordan Rupprecht if self.TraceOn(): 19399451b44SJordan Rupprecht print(frameEntered) 19499451b44SJordan Rupprecht lldbutil.print_stacktrace(thread) 19599451b44SJordan Rupprecht self.assertTrue(frameEntered) 19699451b44SJordan Rupprecht 19799451b44SJordan Rupprecht # Doing two step overs while still inside c(). 19899451b44SJordan Rupprecht thread.StepOver() 19999451b44SJordan Rupprecht thread.StepOver() 20099451b44SJordan Rupprecht self.assertTrue(thread) 20199451b44SJordan Rupprecht frameNow = thread.GetFrameAtIndex(0) 20299451b44SJordan Rupprecht if self.TraceOn(): 20399451b44SJordan Rupprecht print(frameNow) 20499451b44SJordan Rupprecht lldbutil.print_stacktrace(thread) 20599451b44SJordan Rupprecht self.assertTrue(frameNow) 20699451b44SJordan Rupprecht 20799451b44SJordan Rupprecht # The latest two frames are considered equal. 20899451b44SJordan Rupprecht self.assertTrue(frameEntered.IsEqual(frameNow)) 20999451b44SJordan Rupprecht 21099451b44SJordan Rupprecht # Now let's step out of frame c(). 21199451b44SJordan Rupprecht thread.StepOutOfFrame(frameNow) 21299451b44SJordan Rupprecht frameOutOfC = thread.GetFrameAtIndex(0) 21399451b44SJordan Rupprecht if self.TraceOn(): 21499451b44SJordan Rupprecht print(frameOutOfC) 21599451b44SJordan Rupprecht lldbutil.print_stacktrace(thread) 21699451b44SJordan Rupprecht self.assertTrue(frameOutOfC) 21799451b44SJordan Rupprecht 21899451b44SJordan Rupprecht # The latest two frames should not be equal. 21999451b44SJordan Rupprecht self.assertFalse(frameOutOfC.IsEqual(frameNow)) 220