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