101263c6cSJonas Devlieghere""" 201263c6cSJonas DevlieghereTest lldb-dap setBreakpoints request 301263c6cSJonas Devlieghere""" 401263c6cSJonas Devlieghere 501263c6cSJonas Devlieghereimport dap_server 610664813SWalter Erquinigoimport lldbdap_testcase 710664813SWalter Erquinigofrom lldbsuite.test import lldbutil 801263c6cSJonas Devliegherefrom lldbsuite.test.decorators import * 901263c6cSJonas Devliegherefrom lldbsuite.test.lldbtest import * 1001263c6cSJonas Devlieghere 1101263c6cSJonas Devlieghere 12bab10981SMiro Buckodef get_subprocess(root_process, process_name): 13bab10981SMiro Bucko queue = [root_process] 14ef2ca97fSMiro Bucko while queue: 15bab10981SMiro Bucko process = queue.pop() 16ef2ca97fSMiro Bucko if process.name() == process_name: 17ef2ca97fSMiro Bucko return process 18ef2ca97fSMiro Bucko queue.extend(process.children()) 19ef2ca97fSMiro Bucko 20ef2ca97fSMiro Bucko self.assertTrue(False, "No subprocess with name %s found" % process_name) 21ef2ca97fSMiro Bucko 2201263c6cSJonas Devlieghereclass TestDAP_console(lldbdap_testcase.DAPTestCaseBase): 2310664813SWalter Erquinigo def check_lldb_command( 2410664813SWalter Erquinigo self, lldb_command, contains_string, assert_msg, command_escape_prefix="`" 2510664813SWalter Erquinigo ): 2601263c6cSJonas Devlieghere response = self.dap_server.request_evaluate( 2710664813SWalter Erquinigo f"{command_escape_prefix}{lldb_command}", context="repl" 2801263c6cSJonas Devlieghere ) 2901263c6cSJonas Devlieghere output = response["body"]["result"] 3001263c6cSJonas Devlieghere self.assertIn( 3101263c6cSJonas Devlieghere contains_string, 3201263c6cSJonas Devlieghere output, 3301263c6cSJonas Devlieghere ( 3401263c6cSJonas Devlieghere """Verify %s by checking the command output:\n""" 3501263c6cSJonas Devlieghere """'''\n%s'''\nfor the string: "%s" """ 3601263c6cSJonas Devlieghere % (assert_msg, output, contains_string) 3701263c6cSJonas Devlieghere ), 3801263c6cSJonas Devlieghere ) 3901263c6cSJonas Devlieghere 4001263c6cSJonas Devlieghere def test_scopes_variables_setVariable_evaluate(self): 4101263c6cSJonas Devlieghere """ 4201263c6cSJonas Devlieghere Tests that the "scopes" request causes the currently selected 4301263c6cSJonas Devlieghere thread and frame to be updated. There are no DAP packets that tell 4401263c6cSJonas Devlieghere lldb-dap which thread and frame are selected other than the 4501263c6cSJonas Devlieghere "scopes" request. lldb-dap will now select the thread and frame 4601263c6cSJonas Devlieghere for the latest "scopes" request that it receives. 4701263c6cSJonas Devlieghere 4801263c6cSJonas Devlieghere The LLDB command interpreter needs to have the right thread and 4901263c6cSJonas Devlieghere frame selected so that commands executed in the debug console act 5001263c6cSJonas Devlieghere on the right scope. This applies both to the expressions that are 5101263c6cSJonas Devlieghere evaluated and the lldb commands that start with the backtick 5201263c6cSJonas Devlieghere character. 5301263c6cSJonas Devlieghere """ 5401263c6cSJonas Devlieghere program = self.getBuildArtifact("a.out") 5501263c6cSJonas Devlieghere self.build_and_launch(program) 5601263c6cSJonas Devlieghere source = "main.cpp" 5701263c6cSJonas Devlieghere breakpoint1_line = line_number(source, "// breakpoint 1") 5801263c6cSJonas Devlieghere lines = [breakpoint1_line] 5901263c6cSJonas Devlieghere # Set breakpoint in the thread function so we can step the threads 6001263c6cSJonas Devlieghere breakpoint_ids = self.set_source_breakpoints(source, lines) 6101263c6cSJonas Devlieghere self.assertEqual( 6201263c6cSJonas Devlieghere len(breakpoint_ids), len(lines), "expect correct number of breakpoints" 6301263c6cSJonas Devlieghere ) 6401263c6cSJonas Devlieghere self.continue_to_breakpoints(breakpoint_ids) 6501263c6cSJonas Devlieghere # Cause a "scopes" to be sent for frame zero which should update the 6601263c6cSJonas Devlieghere # selected thread and frame to frame 0. 6701263c6cSJonas Devlieghere self.dap_server.get_local_variables(frameIndex=0) 6801263c6cSJonas Devlieghere # Verify frame #0 is selected in the command interpreter by running 6901263c6cSJonas Devlieghere # the "frame select" command with no frame index which will print the 7001263c6cSJonas Devlieghere # currently selected frame. 7101263c6cSJonas Devlieghere self.check_lldb_command("frame select", "frame #0", "frame 0 is selected") 7201263c6cSJonas Devlieghere 7301263c6cSJonas Devlieghere # Cause a "scopes" to be sent for frame one which should update the 7401263c6cSJonas Devlieghere # selected thread and frame to frame 1. 7501263c6cSJonas Devlieghere self.dap_server.get_local_variables(frameIndex=1) 7601263c6cSJonas Devlieghere # Verify frame #1 is selected in the command interpreter by running 7701263c6cSJonas Devlieghere # the "frame select" command with no frame index which will print the 7801263c6cSJonas Devlieghere # currently selected frame. 7901263c6cSJonas Devlieghere 8001263c6cSJonas Devlieghere self.check_lldb_command("frame select", "frame #1", "frame 1 is selected") 8110664813SWalter Erquinigo 8210664813SWalter Erquinigo def test_custom_escape_prefix(self): 8310664813SWalter Erquinigo program = self.getBuildArtifact("a.out") 8410664813SWalter Erquinigo self.build_and_launch(program, commandEscapePrefix="::") 8510664813SWalter Erquinigo source = "main.cpp" 8610664813SWalter Erquinigo breakpoint1_line = line_number(source, "// breakpoint 1") 8710664813SWalter Erquinigo breakpoint_ids = self.set_source_breakpoints(source, [breakpoint1_line]) 8810664813SWalter Erquinigo self.continue_to_breakpoints(breakpoint_ids) 8910664813SWalter Erquinigo 9010664813SWalter Erquinigo self.check_lldb_command( 9110664813SWalter Erquinigo "help", 9210664813SWalter Erquinigo "For more information on any command", 9310664813SWalter Erquinigo "Help can be invoked", 9410664813SWalter Erquinigo command_escape_prefix="::", 9510664813SWalter Erquinigo ) 9610664813SWalter Erquinigo 9710664813SWalter Erquinigo def test_empty_escape_prefix(self): 9810664813SWalter Erquinigo program = self.getBuildArtifact("a.out") 9910664813SWalter Erquinigo self.build_and_launch(program, commandEscapePrefix="") 10010664813SWalter Erquinigo source = "main.cpp" 10110664813SWalter Erquinigo breakpoint1_line = line_number(source, "// breakpoint 1") 10210664813SWalter Erquinigo breakpoint_ids = self.set_source_breakpoints(source, [breakpoint1_line]) 10310664813SWalter Erquinigo self.continue_to_breakpoints(breakpoint_ids) 10410664813SWalter Erquinigo 10510664813SWalter Erquinigo self.check_lldb_command( 10610664813SWalter Erquinigo "help", 10710664813SWalter Erquinigo "For more information on any command", 10810664813SWalter Erquinigo "Help can be invoked", 10910664813SWalter Erquinigo command_escape_prefix="", 11010664813SWalter Erquinigo ) 111ef2ca97fSMiro Bucko 112ef2ca97fSMiro Bucko @skipIfWindows 113ef2ca97fSMiro Bucko def test_exit_status_message_sigterm(self): 114ef2ca97fSMiro Bucko source = "main.cpp" 115ef2ca97fSMiro Bucko program = self.getBuildArtifact("a.out") 116ef2ca97fSMiro Bucko self.build_and_launch(program, commandEscapePrefix="") 117ef2ca97fSMiro Bucko breakpoint1_line = line_number(source, "// breakpoint 1") 118ef2ca97fSMiro Bucko breakpoint_ids = self.set_source_breakpoints(source, [breakpoint1_line]) 119ef2ca97fSMiro Bucko self.continue_to_breakpoints(breakpoint_ids) 120ef2ca97fSMiro Bucko 121ef2ca97fSMiro Bucko # Kill lldb-server process. 122ef2ca97fSMiro Bucko process_name = ( 123ef2ca97fSMiro Bucko "debugserver" if platform.system() in ["Darwin"] else "lldb-server" 124ef2ca97fSMiro Bucko ) 125bab10981SMiro Bucko 126bab10981SMiro Bucko try: 127bab10981SMiro Bucko import psutil 128bab10981SMiro Bucko except ImportError: 129bab10981SMiro Bucko print( 130bab10981SMiro Bucko "psutil not installed, please install using 'pip install psutil'. " 131bab10981SMiro Bucko "Skipping test_exit_status_message_sigterm test.", 132bab10981SMiro Bucko file=sys.stderr, 133bab10981SMiro Bucko ) 134bab10981SMiro Bucko return 135bab10981SMiro Bucko process = get_subprocess(psutil.Process(os.getpid()), process_name) 136ef2ca97fSMiro Bucko process.terminate() 137ef2ca97fSMiro Bucko process.wait() 138ef2ca97fSMiro Bucko 139ef2ca97fSMiro Bucko # Get the console output 140*11a4d43fSMiro Bucko console_output = self.collect_console( 141*11a4d43fSMiro Bucko timeout_secs=10.0, pattern="exited with status" 142*11a4d43fSMiro Bucko ) 143ef2ca97fSMiro Bucko 144ef2ca97fSMiro Bucko # Verify the exit status message is printed. 145ef2ca97fSMiro Bucko self.assertIn( 146ef2ca97fSMiro Bucko "exited with status = -1 (0xffffffff) debugserver died with signal SIGTERM", 147ef2ca97fSMiro Bucko console_output, 148ef2ca97fSMiro Bucko "Exit status does not contain message 'exited with status'", 149ef2ca97fSMiro Bucko ) 150ef2ca97fSMiro Bucko 151ef2ca97fSMiro Bucko def test_exit_status_message_ok(self): 152ef2ca97fSMiro Bucko program = self.getBuildArtifact("a.out") 153ef2ca97fSMiro Bucko self.build_and_launch(program, commandEscapePrefix="") 154ef2ca97fSMiro Bucko self.continue_to_exit() 155ef2ca97fSMiro Bucko 156ef2ca97fSMiro Bucko # Get the console output 157*11a4d43fSMiro Bucko console_output = self.collect_console( 158*11a4d43fSMiro Bucko timeout_secs=10.0, pattern="exited with status" 159*11a4d43fSMiro Bucko ) 160ef2ca97fSMiro Bucko 161ef2ca97fSMiro Bucko # Verify the exit status message is printed. 162ef2ca97fSMiro Bucko self.assertIn( 163ef2ca97fSMiro Bucko "exited with status = 0 (0x00000000)", 164ef2ca97fSMiro Bucko console_output, 165ef2ca97fSMiro Bucko "Exit status does not contain message 'exited with status'", 166ef2ca97fSMiro Bucko ) 167