xref: /llvm-project/lldb/test/API/python_api/frame/TestFrames.py (revision 4b0beb4f5ec42aea58461df7994e2fa40f335bb6)
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