""" Test lldb-dap stepInTargets request """ import dap_server from lldbsuite.test.decorators import * from lldbsuite.test.lldbtest import * import lldbdap_testcase from lldbsuite.test import lldbutil class TestDAP_stepInTargets(lldbdap_testcase.DAPTestCaseBase): @expectedFailureAll(oslist=["windows"]) @skipIf(archs=no_match(["x86_64"])) # InstructionControlFlowKind for ARM is not supported yet. # On Windows, lldb-dap seems to ignore targetId when stepping into functions. # For more context, see https://github.com/llvm/llvm-project/issues/98509. def test_basic(self): """ Tests the basic stepping in targets with directly calls. """ program = self.getBuildArtifact("a.out") self.build_and_launch(program) source = "main.cpp" breakpoint_line = line_number(source, "// set breakpoint here") lines = [breakpoint_line] # Set breakpoint in the thread function so we can step the threads breakpoint_ids = self.set_source_breakpoints(source, lines) self.assertEqual( len(breakpoint_ids), len(lines), "expect correct number of breakpoints" ) self.continue_to_breakpoints(breakpoint_ids) threads = self.dap_server.get_threads() self.assertEqual(len(threads), 1, "expect one thread") tid = threads[0]["id"] leaf_frame = self.dap_server.get_stackFrame() self.assertIsNotNone(leaf_frame, "expect a leaf frame") # Request all step in targets list and verify the response. step_in_targets_response = self.dap_server.request_stepInTargets( leaf_frame["id"] ) self.assertEqual(step_in_targets_response["success"], True, "expect success") self.assertIn( "body", step_in_targets_response, "expect body field in response body" ) self.assertIn( "targets", step_in_targets_response["body"], "expect targets field in response body", ) step_in_targets = step_in_targets_response["body"]["targets"] self.assertEqual(len(step_in_targets), 3, "expect 3 step in targets") # Verify the target names are correct. # The order of funcA and funcB may change depending on the compiler ABI. funcA_target = None funcB_target = None for target in step_in_targets[0:2]: if "funcB" in target["label"]: funcB_target = target elif "funcA" in target["label"]: funcA_target = target else: self.fail(f"Unexpected step in target: {target}") self.assertIsNotNone(funcA_target, "expect funcA") self.assertIsNotNone(funcB_target, "expect funcB") self.assertIn("foo", step_in_targets[2]["label"], "expect foo") # Choose to step into second target and verify that we are in the second target, # be it funcA or funcB. self.stepIn(threadId=tid, targetId=step_in_targets[1]["id"], waitForStop=True) leaf_frame = self.dap_server.get_stackFrame() self.assertIsNotNone(leaf_frame, "expect a leaf frame") self.assertEqual(step_in_targets[1]["label"], leaf_frame["name"]) @skipIf(archs=no_match(["x86", "x86_64"])) def test_supported_capability_x86_arch(self): program = self.getBuildArtifact("a.out") self.build_and_launch(program) source = "main.cpp" bp_lines = [line_number(source, "// set breakpoint here")] breakpoint_ids = self.set_source_breakpoints(source, bp_lines) self.assertEqual( len(breakpoint_ids), len(bp_lines), "expect correct number of breakpoints" ) self.continue_to_breakpoints(breakpoint_ids) is_supported = self.dap_server.get_capability("supportsStepInTargetsRequest") self.assertEqual( is_supported, True, f"expect capability `stepInTarget` is supported with architecture {self.getArchitecture()}", ) # clear breakpoints. self.set_source_breakpoints(source, []) self.continue_to_exit() @skipIf(archs=["x86", "x86_64"]) def test_supported_capability_other_archs(self): program = self.getBuildArtifact("a.out") self.build_and_launch(program) source = "main.cpp" bp_lines = [line_number(source, "// set breakpoint here")] breakpoint_ids = self.set_source_breakpoints(source, bp_lines) self.assertEqual( len(breakpoint_ids), len(bp_lines), "expect correct number of breakpoints" ) self.continue_to_breakpoints(breakpoint_ids) try: is_supported = self.dap_server.get_capability( "supportsStepInTargetsRequest" ) except dap_server.NotSupportedError: is_supported = False self.assertEqual( is_supported, False, f"expect capability `stepInTarget` is not supported with architecture {self.getArchitecture()}", ) # clear breakpoints. self.set_source_breakpoints(source, []) self.continue_to_exit()