1""" 2Test lldb-dap RestartRequest. 3""" 4 5import os 6from lldbsuite.test.decorators import * 7from lldbsuite.test.lldbtest import line_number 8import lldbdap_testcase 9 10 11class TestDAP_restart_runInTerminal(lldbdap_testcase.DAPTestCaseBase): 12 def isTestSupported(self): 13 try: 14 # We skip this test for debug builds because it takes too long 15 # parsing lldb's own debug info. Release builds are fine. 16 # Checking the size of the lldb-dap binary seems to be a decent 17 # proxy for a quick detection. It should be far less than 1 MB in 18 # Release builds. 19 return os.path.getsize(os.environ["LLDBDAP_EXEC"]) < 1000000 20 except: 21 return False 22 23 @skipIfWindows 24 @skipIf(archs=["arm"]) # Always times out on buildbot 25 def test_basic_functionality(self): 26 """ 27 Test basic restarting functionality when the process is running in 28 a terminal. 29 """ 30 if not self.isTestSupported(): 31 return 32 line_A = line_number("main.c", "// breakpoint A") 33 line_B = line_number("main.c", "// breakpoint B") 34 35 program = self.getBuildArtifact("a.out") 36 self.build_and_launch(program, runInTerminal=True) 37 [bp_A, bp_B] = self.set_source_breakpoints("main.c", [line_A, line_B]) 38 39 # Verify we hit A, then B. 40 self.dap_server.request_configurationDone() 41 self.verify_breakpoint_hit([bp_A]) 42 self.dap_server.request_continue() 43 self.verify_breakpoint_hit([bp_B]) 44 45 # Make sure i has been modified from its initial value of 0. 46 self.assertEqual( 47 int(self.dap_server.get_local_variable_value("i")), 48 1234, 49 "i != 1234 after hitting breakpoint B", 50 ) 51 52 # Restart. 53 self.dap_server.request_restart() 54 55 # Finally, check we stop back at A and program state has been reset. 56 self.verify_breakpoint_hit([bp_A]) 57 self.assertEqual( 58 int(self.dap_server.get_local_variable_value("i")), 59 0, 60 "i != 0 after hitting breakpoint A on restart", 61 ) 62 63 @skipIfWindows 64 @skipIf(archs=["arm"]) # Always times out on buildbot 65 def test_stopOnEntry(self): 66 """ 67 Check that stopOnEntry works correctly when using runInTerminal. 68 """ 69 if not self.isTestSupported(): 70 return 71 line_A = line_number("main.c", "// breakpoint A") 72 line_B = line_number("main.c", "// breakpoint B") 73 74 program = self.getBuildArtifact("a.out") 75 self.build_and_launch(program, runInTerminal=True, stopOnEntry=True) 76 [bp_main] = self.set_function_breakpoints(["main"]) 77 self.dap_server.request_configurationDone() 78 79 # When using stopOnEntry, configurationDone doesn't result in a running 80 # process, we should immediately get a stopped event instead. 81 stopped_events = self.dap_server.wait_for_stopped() 82 # We should be stopped at the entry point. 83 for stopped_event in stopped_events: 84 if "body" in stopped_event: 85 body = stopped_event["body"] 86 if "reason" in body: 87 reason = body["reason"] 88 self.assertNotEqual( 89 reason, "breakpoint", "verify stop isn't a breakpoint" 90 ) 91 92 # Then, if we continue, we should hit the breakpoint at main. 93 self.dap_server.request_continue() 94 self.verify_breakpoint_hit([bp_main]) 95 96 # Restart and check that we still get a stopped event before reaching 97 # main. 98 self.dap_server.request_restart() 99 stopped_events = self.dap_server.wait_for_stopped() 100 for stopped_event in stopped_events: 101 if "body" in stopped_event: 102 body = stopped_event["body"] 103 if "reason" in body: 104 reason = body["reason"] 105 self.assertNotEqual( 106 reason, 107 "breakpoint", 108 'verify stop after restart isn\'t "main" breakpoint', 109 ) 110