xref: /llvm-project/lldb/test/API/tools/lldb-dap/restart/TestDAP_restart_runInTerminal.py (revision fa6377119c0624773cb698935692d46843e9f6ec)
101263c6cSJonas Devlieghere"""
201263c6cSJonas DevlieghereTest lldb-dap RestartRequest.
301263c6cSJonas Devlieghere"""
401263c6cSJonas Devlieghere
501263c6cSJonas Devlieghereimport os
601263c6cSJonas Devliegherefrom lldbsuite.test.decorators import *
701263c6cSJonas Devliegherefrom lldbsuite.test.lldbtest import line_number
801263c6cSJonas Devlieghereimport lldbdap_testcase
901263c6cSJonas Devlieghere
1001263c6cSJonas Devlieghere
1101263c6cSJonas Devlieghereclass TestDAP_restart_runInTerminal(lldbdap_testcase.DAPTestCaseBase):
1201263c6cSJonas Devlieghere    def isTestSupported(self):
1301263c6cSJonas Devlieghere        try:
1401263c6cSJonas Devlieghere            # We skip this test for debug builds because it takes too long
1501263c6cSJonas Devlieghere            # parsing lldb's own debug info. Release builds are fine.
1601263c6cSJonas Devlieghere            # Checking the size of the lldb-dap binary seems to be a decent
1701263c6cSJonas Devlieghere            # proxy for a quick detection. It should be far less than 1 MB in
1801263c6cSJonas Devlieghere            # Release builds.
1901263c6cSJonas Devlieghere            return os.path.getsize(os.environ["LLDBDAP_EXEC"]) < 1000000
2001263c6cSJonas Devlieghere        except:
2101263c6cSJonas Devlieghere            return False
2201263c6cSJonas Devlieghere
2301263c6cSJonas Devlieghere    @skipIfWindows
2401263c6cSJonas Devlieghere    @skipIf(archs=["arm"])  # Always times out on buildbot
2501263c6cSJonas Devlieghere    def test_basic_functionality(self):
2601263c6cSJonas Devlieghere        """
2701263c6cSJonas Devlieghere        Test basic restarting functionality when the process is running in
2801263c6cSJonas Devlieghere        a terminal.
2901263c6cSJonas Devlieghere        """
3001263c6cSJonas Devlieghere        if not self.isTestSupported():
3101263c6cSJonas Devlieghere            return
3201263c6cSJonas Devlieghere        line_A = line_number("main.c", "// breakpoint A")
3301263c6cSJonas Devlieghere        line_B = line_number("main.c", "// breakpoint B")
3401263c6cSJonas Devlieghere
3501263c6cSJonas Devlieghere        program = self.getBuildArtifact("a.out")
3601263c6cSJonas Devlieghere        self.build_and_launch(program, runInTerminal=True)
3701263c6cSJonas Devlieghere        [bp_A, bp_B] = self.set_source_breakpoints("main.c", [line_A, line_B])
3801263c6cSJonas Devlieghere
3901263c6cSJonas Devlieghere        # Verify we hit A, then B.
4001263c6cSJonas Devlieghere        self.dap_server.request_configurationDone()
4101263c6cSJonas Devlieghere        self.verify_breakpoint_hit([bp_A])
4201263c6cSJonas Devlieghere        self.dap_server.request_continue()
4301263c6cSJonas Devlieghere        self.verify_breakpoint_hit([bp_B])
4401263c6cSJonas Devlieghere
4501263c6cSJonas Devlieghere        # Make sure i has been modified from its initial value of 0.
46*80fcecb1SJonas Devlieghere        self.assertEqual(
4701263c6cSJonas Devlieghere            int(self.dap_server.get_local_variable_value("i")),
4801263c6cSJonas Devlieghere            1234,
4901263c6cSJonas Devlieghere            "i != 1234 after hitting breakpoint B",
5001263c6cSJonas Devlieghere        )
5101263c6cSJonas Devlieghere
5201263c6cSJonas Devlieghere        # Restart.
5301263c6cSJonas Devlieghere        self.dap_server.request_restart()
5401263c6cSJonas Devlieghere
5501263c6cSJonas Devlieghere        # Finally, check we stop back at A and program state has been reset.
5601263c6cSJonas Devlieghere        self.verify_breakpoint_hit([bp_A])
57*80fcecb1SJonas Devlieghere        self.assertEqual(
5801263c6cSJonas Devlieghere            int(self.dap_server.get_local_variable_value("i")),
5901263c6cSJonas Devlieghere            0,
6001263c6cSJonas Devlieghere            "i != 0 after hitting breakpoint A on restart",
6101263c6cSJonas Devlieghere        )
6201263c6cSJonas Devlieghere
6301263c6cSJonas Devlieghere    @skipIfWindows
6401263c6cSJonas Devlieghere    @skipIf(archs=["arm"])  # Always times out on buildbot
6501263c6cSJonas Devlieghere    def test_stopOnEntry(self):
6601263c6cSJonas Devlieghere        """
6701263c6cSJonas Devlieghere        Check that stopOnEntry works correctly when using runInTerminal.
6801263c6cSJonas Devlieghere        """
6901263c6cSJonas Devlieghere        if not self.isTestSupported():
7001263c6cSJonas Devlieghere            return
7101263c6cSJonas Devlieghere        line_A = line_number("main.c", "// breakpoint A")
7201263c6cSJonas Devlieghere        line_B = line_number("main.c", "// breakpoint B")
7301263c6cSJonas Devlieghere
7401263c6cSJonas Devlieghere        program = self.getBuildArtifact("a.out")
7501263c6cSJonas Devlieghere        self.build_and_launch(program, runInTerminal=True, stopOnEntry=True)
7601263c6cSJonas Devlieghere        [bp_main] = self.set_function_breakpoints(["main"])
7701263c6cSJonas Devlieghere        self.dap_server.request_configurationDone()
7801263c6cSJonas Devlieghere
7901263c6cSJonas Devlieghere        # When using stopOnEntry, configurationDone doesn't result in a running
8001263c6cSJonas Devlieghere        # process, we should immediately get a stopped event instead.
8101263c6cSJonas Devlieghere        stopped_events = self.dap_server.wait_for_stopped()
8201263c6cSJonas Devlieghere        # We should be stopped at the entry point.
8301263c6cSJonas Devlieghere        for stopped_event in stopped_events:
8401263c6cSJonas Devlieghere            if "body" in stopped_event:
8501263c6cSJonas Devlieghere                body = stopped_event["body"]
8601263c6cSJonas Devlieghere                if "reason" in body:
8701263c6cSJonas Devlieghere                    reason = body["reason"]
8801263c6cSJonas Devlieghere                    self.assertNotEqual(
8901263c6cSJonas Devlieghere                        reason, "breakpoint", "verify stop isn't a breakpoint"
9001263c6cSJonas Devlieghere                    )
9101263c6cSJonas Devlieghere
9201263c6cSJonas Devlieghere        # Then, if we continue, we should hit the breakpoint at main.
9301263c6cSJonas Devlieghere        self.dap_server.request_continue()
9401263c6cSJonas Devlieghere        self.verify_breakpoint_hit([bp_main])
9501263c6cSJonas Devlieghere
9601263c6cSJonas Devlieghere        # Restart and check that we still get a stopped event before reaching
9701263c6cSJonas Devlieghere        # main.
9801263c6cSJonas Devlieghere        self.dap_server.request_restart()
9901263c6cSJonas Devlieghere        stopped_events = self.dap_server.wait_for_stopped()
10001263c6cSJonas Devlieghere        for stopped_event in stopped_events:
10101263c6cSJonas Devlieghere            if "body" in stopped_event:
10201263c6cSJonas Devlieghere                body = stopped_event["body"]
10301263c6cSJonas Devlieghere                if "reason" in body:
10401263c6cSJonas Devlieghere                    reason = body["reason"]
10501263c6cSJonas Devlieghere                    self.assertNotEqual(
10601263c6cSJonas Devlieghere                        reason,
10701263c6cSJonas Devlieghere                        "breakpoint",
10801263c6cSJonas Devlieghere                        'verify stop after restart isn\'t "main" breakpoint',
10901263c6cSJonas Devlieghere                    )
110