101263c6cSJonas Devlieghere""" 201263c6cSJonas DevlieghereTest lldb-dap setBreakpoints request 301263c6cSJonas Devlieghere""" 401263c6cSJonas Devlieghere 501263c6cSJonas Devlieghere 601263c6cSJonas Devlieghereimport dap_server 701263c6cSJonas Devliegherefrom lldbsuite.test.decorators import * 801263c6cSJonas Devliegherefrom lldbsuite.test.lldbtest import * 901263c6cSJonas Devliegherefrom lldbsuite.test import lldbutil 1001263c6cSJonas Devlieghereimport lldbdap_testcase 1101263c6cSJonas Devlieghere 1201263c6cSJonas Devlieghere 1301263c6cSJonas Devlieghereclass TestDAP_step(lldbdap_testcase.DAPTestCaseBase): 1401263c6cSJonas Devlieghere @skipIfWindows 1501263c6cSJonas Devlieghere def test_step(self): 1601263c6cSJonas Devlieghere """ 1701263c6cSJonas Devlieghere Tests the stepping in/out/over in threads. 1801263c6cSJonas Devlieghere """ 1901263c6cSJonas Devlieghere program = self.getBuildArtifact("a.out") 2001263c6cSJonas Devlieghere self.build_and_launch(program) 2101263c6cSJonas Devlieghere source = "main.cpp" 2201263c6cSJonas Devlieghere # source_path = os.path.join(os.getcwd(), source) 2301263c6cSJonas Devlieghere breakpoint1_line = line_number(source, "// breakpoint 1") 2401263c6cSJonas Devlieghere lines = [breakpoint1_line] 2501263c6cSJonas Devlieghere # Set breakpoint in the thread function so we can step the threads 2601263c6cSJonas Devlieghere breakpoint_ids = self.set_source_breakpoints(source, lines) 2701263c6cSJonas Devlieghere self.assertEqual( 2801263c6cSJonas Devlieghere len(breakpoint_ids), len(lines), "expect correct number of breakpoints" 2901263c6cSJonas Devlieghere ) 3001263c6cSJonas Devlieghere self.continue_to_breakpoints(breakpoint_ids) 3101263c6cSJonas Devlieghere threads = self.dap_server.get_threads() 3201263c6cSJonas Devlieghere for thread in threads: 3301263c6cSJonas Devlieghere if "reason" in thread: 3401263c6cSJonas Devlieghere reason = thread["reason"] 3501263c6cSJonas Devlieghere if reason == "breakpoint": 3601263c6cSJonas Devlieghere # We have a thread that is stopped at our breakpoint. 3701263c6cSJonas Devlieghere # Get the value of "x" and get the source file and line. 3801263c6cSJonas Devlieghere # These will help us determine if we are stepping 3901263c6cSJonas Devlieghere # correctly. If we step a thread correctly we will verify 4001263c6cSJonas Devlieghere # the correct falue for x as it progresses through the 4101263c6cSJonas Devlieghere # program. 4201263c6cSJonas Devlieghere tid = thread["id"] 4301263c6cSJonas Devlieghere x1 = self.get_local_as_int("x", threadId=tid) 4401263c6cSJonas Devlieghere (src1, line1) = self.get_source_and_line(threadId=tid) 4501263c6cSJonas Devlieghere 4601263c6cSJonas Devlieghere # Now step into the "recurse()" function call again and 4701263c6cSJonas Devlieghere # verify, using the new value of "x" and the source file 4801263c6cSJonas Devlieghere # and line if we stepped correctly 4901263c6cSJonas Devlieghere self.stepIn(threadId=tid, waitForStop=True) 5001263c6cSJonas Devlieghere x2 = self.get_local_as_int("x", threadId=tid) 5101263c6cSJonas Devlieghere (src2, line2) = self.get_source_and_line(threadId=tid) 5201263c6cSJonas Devlieghere self.assertEqual(x1, x2 + 1, "verify step in variable") 5301263c6cSJonas Devlieghere self.assertLess(line2, line1, "verify step in line") 5401263c6cSJonas Devlieghere self.assertEqual(src1, src2, "verify step in source") 5501263c6cSJonas Devlieghere 5601263c6cSJonas Devlieghere # Now step out and verify 5701263c6cSJonas Devlieghere self.stepOut(threadId=tid, waitForStop=True) 5801263c6cSJonas Devlieghere x3 = self.get_local_as_int("x", threadId=tid) 5901263c6cSJonas Devlieghere (src3, line3) = self.get_source_and_line(threadId=tid) 6001263c6cSJonas Devlieghere self.assertEqual(x1, x3, "verify step out variable") 6101263c6cSJonas Devlieghere self.assertGreaterEqual(line3, line1, "verify step out line") 6201263c6cSJonas Devlieghere self.assertEqual(src1, src3, "verify step in source") 6301263c6cSJonas Devlieghere 6401263c6cSJonas Devlieghere # Step over and verify 6501263c6cSJonas Devlieghere self.stepOver(threadId=tid, waitForStop=True) 6601263c6cSJonas Devlieghere x4 = self.get_local_as_int("x", threadId=tid) 6701263c6cSJonas Devlieghere (src4, line4) = self.get_source_and_line(threadId=tid) 6801263c6cSJonas Devlieghere self.assertEqual(x4, x3, "verify step over variable") 6901263c6cSJonas Devlieghere self.assertGreater(line4, line3, "verify step over line") 7001263c6cSJonas Devlieghere self.assertEqual(src1, src4, "verify step over source") 71*6257a98bSAdrian Vogelsgesang 72*6257a98bSAdrian Vogelsgesang # Step a single assembly instruction. 73*6257a98bSAdrian Vogelsgesang # Unfortunately, there is no portable way to verify the correct 74*6257a98bSAdrian Vogelsgesang # stepping behavior here, because the generated assembly code 75*6257a98bSAdrian Vogelsgesang # depends highly on the compiler, its version, the operating 76*6257a98bSAdrian Vogelsgesang # system, and many more factors. 77*6257a98bSAdrian Vogelsgesang self.stepOver( 78*6257a98bSAdrian Vogelsgesang threadId=tid, waitForStop=True, granularity="instruction" 79*6257a98bSAdrian Vogelsgesang ) 80*6257a98bSAdrian Vogelsgesang self.stepIn( 81*6257a98bSAdrian Vogelsgesang threadId=tid, waitForStop=True, granularity="instruction" 82*6257a98bSAdrian Vogelsgesang ) 83*6257a98bSAdrian Vogelsgesang 8401263c6cSJonas Devlieghere # only step one thread that is at the breakpoint and stop 8501263c6cSJonas Devlieghere break 86