""" Test lldb-dap RestartRequest. """ from lldbsuite.test.decorators import * from lldbsuite.test.lldbtest import line_number import lldbdap_testcase class TestDAP_restart(lldbdap_testcase.DAPTestCaseBase): @skipIfWindows def test_basic_functionality(self): """ Tests the basic restarting functionality: set two breakpoints in sequence, restart at the second, check that we hit the first one. """ line_A = line_number("main.c", "// breakpoint A") line_B = line_number("main.c", "// breakpoint B") program = self.getBuildArtifact("a.out") self.build_and_launch(program) [bp_A, bp_B] = self.set_source_breakpoints("main.c", [line_A, line_B]) # Verify we hit A, then B. self.continue_to_breakpoints([bp_A]) self.continue_to_breakpoints([bp_B]) # Make sure i has been modified from its initial value of 0. self.assertEqual( int(self.dap_server.get_local_variable_value("i")), 1234, "i != 1234 after hitting breakpoint B", ) # Restart then check we stop back at A and program state has been reset. resp = self.dap_server.request_restart() self.assertTrue(resp["success"]) self.verify_breakpoint_hit([bp_A]) self.assertEqual( int(self.dap_server.get_local_variable_value("i")), 0, "i != 0 after hitting breakpoint A on restart", ) @skipIfWindows def test_stopOnEntry(self): """ Check that the stopOnEntry setting is still honored after a restart. """ program = self.getBuildArtifact("a.out") self.build_and_launch(program, stopOnEntry=True) [bp_main] = self.set_function_breakpoints(["main"]) self.dap_server.request_configurationDone() self.dap_server.wait_for_stopped() # Once the "configuration done" event is sent, we should get a stopped # event immediately because of stopOnEntry. self.assertTrue( len(self.dap_server.thread_stop_reasons) > 0, "expected stopped event during launch", ) for _, body in self.dap_server.thread_stop_reasons.items(): if "reason" in body: reason = body["reason"] self.assertNotEqual( reason, "breakpoint", 'verify stop isn\'t "main" breakpoint' ) # Then, if we continue, we should hit the breakpoint at main. self.continue_to_breakpoints([bp_main]) # Restart and check that we still get a stopped event before reaching # main. resp = self.dap_server.request_restart() self.assertTrue(resp["success"]) stopped_events = self.dap_server.wait_for_stopped() for stopped_event in stopped_events: if "body" in stopped_event: body = stopped_event["body"] if "reason" in body: reason = body["reason"] self.assertNotEqual( reason, "breakpoint", 'verify stop after restart isn\'t "main" breakpoint', ) @skipIfWindows def test_arguments(self): """ Tests that lldb-dap will use updated launch arguments included with a restart request. """ line_A = line_number("main.c", "// breakpoint A") program = self.getBuildArtifact("a.out") self.build_and_launch(program) [bp_A] = self.set_source_breakpoints("main.c", [line_A]) # Verify we hit A, then B. self.continue_to_breakpoints([bp_A]) # We don't set any arguments in the initial launch request, so argc # should be 1. self.assertEqual( int(self.dap_server.get_local_variable_value("argc")), 1, "argc != 1 before restart", ) # Restart with some extra 'args' and check that the new argc reflects # the updated launch config. resp = self.dap_server.request_restart( restartArguments={ "arguments": { "program": program, "args": ["a", "b", "c", "d"], } } ) self.assertTrue(resp["success"]) self.verify_breakpoint_hit([bp_A]) self.assertEqual( int(self.dap_server.get_local_variable_value("argc")), 5, "argc != 5 after restart", )