xref: /llvm-project/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_setFunctionBreakpoints.py (revision fa6377119c0624773cb698935692d46843e9f6ec)
101263c6cSJonas Devlieghere"""
201263c6cSJonas DevlieghereTest lldb-dap setBreakpoints request
301263c6cSJonas Devlieghere"""
401263c6cSJonas Devlieghere
501263c6cSJonas Devlieghere
601263c6cSJonas Devlieghereimport dap_server
701263c6cSJonas Devliegherefrom lldbsuite.test.decorators import *
801263c6cSJonas Devliegherefrom lldbsuite.test.lldbtest import *
901263c6cSJonas Devliegherefrom lldbsuite.test import lldbutil
1001263c6cSJonas Devlieghereimport lldbdap_testcase
1101263c6cSJonas Devlieghere
1201263c6cSJonas Devlieghere
1301263c6cSJonas Devlieghereclass TestDAP_setFunctionBreakpoints(lldbdap_testcase.DAPTestCaseBase):
1401263c6cSJonas Devlieghere    @skipIfWindows
1501263c6cSJonas Devlieghere    def test_set_and_clear(self):
1601263c6cSJonas Devlieghere        """Tests setting and clearing function breakpoints.
1701263c6cSJonas Devlieghere        This packet is a bit tricky on the debug adaptor side since there
1801263c6cSJonas Devlieghere        is no "clearFunction Breakpoints" packet. Function breakpoints
1901263c6cSJonas Devlieghere        are set by sending a "setFunctionBreakpoints" packet with zero or
2001263c6cSJonas Devlieghere        more function names. If function breakpoints have been set before,
2101263c6cSJonas Devlieghere        any existing breakpoints must remain set, and any new breakpoints
2201263c6cSJonas Devlieghere        must be created, and any breakpoints that were in previous requests
2301263c6cSJonas Devlieghere        and are not in the current request must be removed. This function
2401263c6cSJonas Devlieghere        tests this setting and clearing and makes sure things happen
2501263c6cSJonas Devlieghere        correctly. It doesn't test hitting breakpoints and the functionality
2601263c6cSJonas Devlieghere        of each breakpoint, like 'conditions' and 'hitCondition' settings.
2701263c6cSJonas Devlieghere        """
2801263c6cSJonas Devlieghere        # Visual Studio Code Debug Adaptors have no way to specify the file
2901263c6cSJonas Devlieghere        # without launching or attaching to a process, so we must start a
3001263c6cSJonas Devlieghere        # process in order to be able to set breakpoints.
3101263c6cSJonas Devlieghere        program = self.getBuildArtifact("a.out")
3201263c6cSJonas Devlieghere        self.build_and_launch(program)
3301263c6cSJonas Devlieghere        bp_id_12 = None
3401263c6cSJonas Devlieghere        functions = ["twelve"]
3501263c6cSJonas Devlieghere        # Set a function breakpoint at 'twelve'
3601263c6cSJonas Devlieghere        response = self.dap_server.request_setFunctionBreakpoints(functions)
3701263c6cSJonas Devlieghere        if response:
3801263c6cSJonas Devlieghere            breakpoints = response["body"]["breakpoints"]
39*80fcecb1SJonas Devlieghere            self.assertEqual(
4001263c6cSJonas Devlieghere                len(breakpoints),
4101263c6cSJonas Devlieghere                len(functions),
4201263c6cSJonas Devlieghere                "expect %u source breakpoints" % (len(functions)),
4301263c6cSJonas Devlieghere            )
4401263c6cSJonas Devlieghere            for breakpoint in breakpoints:
4501263c6cSJonas Devlieghere                bp_id_12 = breakpoint["id"]
4601263c6cSJonas Devlieghere                self.assertTrue(breakpoint["verified"], "expect breakpoint verified")
4701263c6cSJonas Devlieghere
4801263c6cSJonas Devlieghere        # Add an extra name and make sure we have two breakpoints after this
4901263c6cSJonas Devlieghere        functions.append("thirteen")
5001263c6cSJonas Devlieghere        response = self.dap_server.request_setFunctionBreakpoints(functions)
5101263c6cSJonas Devlieghere        if response:
5201263c6cSJonas Devlieghere            breakpoints = response["body"]["breakpoints"]
53*80fcecb1SJonas Devlieghere            self.assertEqual(
5401263c6cSJonas Devlieghere                len(breakpoints),
5501263c6cSJonas Devlieghere                len(functions),
5601263c6cSJonas Devlieghere                "expect %u source breakpoints" % (len(functions)),
5701263c6cSJonas Devlieghere            )
5801263c6cSJonas Devlieghere            for breakpoint in breakpoints:
5901263c6cSJonas Devlieghere                self.assertTrue(breakpoint["verified"], "expect breakpoint verified")
6001263c6cSJonas Devlieghere
6101263c6cSJonas Devlieghere        # There is no breakpoint delete packet, clients just send another
6201263c6cSJonas Devlieghere        # setFunctionBreakpoints packet with the different function names.
6301263c6cSJonas Devlieghere        functions.remove("thirteen")
6401263c6cSJonas Devlieghere        response = self.dap_server.request_setFunctionBreakpoints(functions)
6501263c6cSJonas Devlieghere        if response:
6601263c6cSJonas Devlieghere            breakpoints = response["body"]["breakpoints"]
67*80fcecb1SJonas Devlieghere            self.assertEqual(
6801263c6cSJonas Devlieghere                len(breakpoints),
6901263c6cSJonas Devlieghere                len(functions),
7001263c6cSJonas Devlieghere                "expect %u source breakpoints" % (len(functions)),
7101263c6cSJonas Devlieghere            )
7201263c6cSJonas Devlieghere            for breakpoint in breakpoints:
7301263c6cSJonas Devlieghere                bp_id = breakpoint["id"]
74*80fcecb1SJonas Devlieghere                self.assertEqual(
7501263c6cSJonas Devlieghere                    bp_id, bp_id_12, 'verify "twelve" breakpoint ID is same'
7601263c6cSJonas Devlieghere                )
7701263c6cSJonas Devlieghere                self.assertTrue(
7801263c6cSJonas Devlieghere                    breakpoint["verified"], "expect breakpoint still verified"
7901263c6cSJonas Devlieghere                )
8001263c6cSJonas Devlieghere
8101263c6cSJonas Devlieghere        # Now get the full list of breakpoints set in the target and verify
8201263c6cSJonas Devlieghere        # we have only 1 breakpoints set. The response above could have told
8301263c6cSJonas Devlieghere        # us about 1 breakpoints, but we want to make sure we don't have the
8401263c6cSJonas Devlieghere        # second one still set in the target
8501263c6cSJonas Devlieghere        response = self.dap_server.request_testGetTargetBreakpoints()
8601263c6cSJonas Devlieghere        if response:
8701263c6cSJonas Devlieghere            breakpoints = response["body"]["breakpoints"]
88*80fcecb1SJonas Devlieghere            self.assertEqual(
8901263c6cSJonas Devlieghere                len(breakpoints),
9001263c6cSJonas Devlieghere                len(functions),
9101263c6cSJonas Devlieghere                "expect %u source breakpoints" % (len(functions)),
9201263c6cSJonas Devlieghere            )
9301263c6cSJonas Devlieghere            for breakpoint in breakpoints:
9401263c6cSJonas Devlieghere                bp_id = breakpoint["id"]
95*80fcecb1SJonas Devlieghere                self.assertEqual(
9601263c6cSJonas Devlieghere                    bp_id, bp_id_12, 'verify "twelve" breakpoint ID is same'
9701263c6cSJonas Devlieghere                )
9801263c6cSJonas Devlieghere                self.assertTrue(
9901263c6cSJonas Devlieghere                    breakpoint["verified"], "expect breakpoint still verified"
10001263c6cSJonas Devlieghere                )
10101263c6cSJonas Devlieghere
10201263c6cSJonas Devlieghere        # Now clear all breakpoints for the source file by passing down an
10301263c6cSJonas Devlieghere        # empty lines array
10401263c6cSJonas Devlieghere        functions = []
10501263c6cSJonas Devlieghere        response = self.dap_server.request_setFunctionBreakpoints(functions)
10601263c6cSJonas Devlieghere        if response:
10701263c6cSJonas Devlieghere            breakpoints = response["body"]["breakpoints"]
108*80fcecb1SJonas Devlieghere            self.assertEqual(
10901263c6cSJonas Devlieghere                len(breakpoints),
11001263c6cSJonas Devlieghere                len(functions),
11101263c6cSJonas Devlieghere                "expect %u source breakpoints" % (len(functions)),
11201263c6cSJonas Devlieghere            )
11301263c6cSJonas Devlieghere
11401263c6cSJonas Devlieghere        # Verify with the target that all breakpoints have been cleared
11501263c6cSJonas Devlieghere        response = self.dap_server.request_testGetTargetBreakpoints()
11601263c6cSJonas Devlieghere        if response:
11701263c6cSJonas Devlieghere            breakpoints = response["body"]["breakpoints"]
118*80fcecb1SJonas Devlieghere            self.assertEqual(
11901263c6cSJonas Devlieghere                len(breakpoints),
12001263c6cSJonas Devlieghere                len(functions),
12101263c6cSJonas Devlieghere                "expect %u source breakpoints" % (len(functions)),
12201263c6cSJonas Devlieghere            )
12301263c6cSJonas Devlieghere
12401263c6cSJonas Devlieghere    @skipIfWindows
12501263c6cSJonas Devlieghere    def test_functionality(self):
12601263c6cSJonas Devlieghere        """Tests hitting breakpoints and the functionality of a single
12701263c6cSJonas Devlieghere        breakpoint, like 'conditions' and 'hitCondition' settings."""
12801263c6cSJonas Devlieghere
12901263c6cSJonas Devlieghere        program = self.getBuildArtifact("a.out")
13001263c6cSJonas Devlieghere        self.build_and_launch(program)
13101263c6cSJonas Devlieghere        # Set a breakpoint on "twelve" with no condition and no hitCondition
13201263c6cSJonas Devlieghere        functions = ["twelve"]
13301263c6cSJonas Devlieghere        breakpoint_ids = self.set_function_breakpoints(functions)
13401263c6cSJonas Devlieghere
135*80fcecb1SJonas Devlieghere        self.assertEqual(len(breakpoint_ids), len(functions), "expect one breakpoint")
13601263c6cSJonas Devlieghere
13701263c6cSJonas Devlieghere        # Verify we hit the breakpoint we just set
13801263c6cSJonas Devlieghere        self.continue_to_breakpoints(breakpoint_ids)
13901263c6cSJonas Devlieghere
14001263c6cSJonas Devlieghere        # Make sure i is zero at first breakpoint
14101263c6cSJonas Devlieghere        i = int(self.dap_server.get_local_variable_value("i"))
142*80fcecb1SJonas Devlieghere        self.assertEqual(i, 0, "i != 0 after hitting breakpoint")
14301263c6cSJonas Devlieghere
14401263c6cSJonas Devlieghere        # Update the condition on our breakpoint
14501263c6cSJonas Devlieghere        new_breakpoint_ids = self.set_function_breakpoints(functions, condition="i==4")
146*80fcecb1SJonas Devlieghere        self.assertEqual(
14701263c6cSJonas Devlieghere            breakpoint_ids,
14801263c6cSJonas Devlieghere            new_breakpoint_ids,
14901263c6cSJonas Devlieghere            "existing breakpoint should have its condition " "updated",
15001263c6cSJonas Devlieghere        )
15101263c6cSJonas Devlieghere
15201263c6cSJonas Devlieghere        self.continue_to_breakpoints(breakpoint_ids)
15301263c6cSJonas Devlieghere        i = int(self.dap_server.get_local_variable_value("i"))
154*80fcecb1SJonas Devlieghere        self.assertEqual(i, 4, "i != 4 showing conditional works")
15501263c6cSJonas Devlieghere        new_breakpoint_ids = self.set_function_breakpoints(functions, hitCondition="2")
15601263c6cSJonas Devlieghere
157*80fcecb1SJonas Devlieghere        self.assertEqual(
15801263c6cSJonas Devlieghere            breakpoint_ids,
15901263c6cSJonas Devlieghere            new_breakpoint_ids,
16001263c6cSJonas Devlieghere            "existing breakpoint should have its condition " "updated",
16101263c6cSJonas Devlieghere        )
16201263c6cSJonas Devlieghere
16301263c6cSJonas Devlieghere        # Continue with a hitCondition of 2 and expect it to skip 1 value
16401263c6cSJonas Devlieghere        self.continue_to_breakpoints(breakpoint_ids)
16501263c6cSJonas Devlieghere        i = int(self.dap_server.get_local_variable_value("i"))
166*80fcecb1SJonas Devlieghere        self.assertEqual(i, 6, "i != 6 showing hitCondition works")
16701263c6cSJonas Devlieghere
16801263c6cSJonas Devlieghere        # continue after hitting our hitCondition and make sure it only goes
16901263c6cSJonas Devlieghere        # up by 1
17001263c6cSJonas Devlieghere        self.continue_to_breakpoints(breakpoint_ids)
17101263c6cSJonas Devlieghere        i = int(self.dap_server.get_local_variable_value("i"))
172*80fcecb1SJonas Devlieghere        self.assertEqual(i, 7, "i != 7 showing post hitCondition hits every time")
173