xref: /llvm-project/lldb/test/API/tools/lldb-dap/variables/TestDAP_variables.py (revision 8f18f36b4906872ee0838ade2c0367c77b6f5bc0)
101263c6cSJonas Devlieghere"""
201263c6cSJonas DevlieghereTest lldb-dap setBreakpoints request
301263c6cSJonas Devlieghere"""
401263c6cSJonas Devlieghere
501263c6cSJonas Devlieghereimport os
601263c6cSJonas Devlieghere
701263c6cSJonas Devlieghereimport dap_server
80ea19bd3SWalter Erquinigoimport lldbdap_testcase
901263c6cSJonas Devliegherefrom lldbsuite.test import lldbutil
1001263c6cSJonas Devliegherefrom lldbsuite.test.decorators import *
1101263c6cSJonas Devliegherefrom lldbsuite.test.lldbtest import *
1201263c6cSJonas Devlieghere
1301263c6cSJonas Devlieghere
1401263c6cSJonas Devliegheredef make_buffer_verify_dict(start_idx, count, offset=0):
1501263c6cSJonas Devlieghere    verify_dict = {}
1601263c6cSJonas Devlieghere    for i in range(start_idx, start_idx + count):
1701263c6cSJonas Devlieghere        verify_dict["[%i]" % (i)] = {"type": "int", "value": str(i + offset)}
1801263c6cSJonas Devlieghere    return verify_dict
1901263c6cSJonas Devlieghere
2001263c6cSJonas Devlieghere
2101263c6cSJonas Devlieghereclass TestDAP_variables(lldbdap_testcase.DAPTestCaseBase):
2201263c6cSJonas Devlieghere    def verify_values(self, verify_dict, actual, varref_dict=None, expression=None):
2301263c6cSJonas Devlieghere        if "equals" in verify_dict:
2401263c6cSJonas Devlieghere            verify = verify_dict["equals"]
2501263c6cSJonas Devlieghere            for key in verify:
2601263c6cSJonas Devlieghere                verify_value = verify[key]
2701263c6cSJonas Devlieghere                actual_value = actual[key]
2801263c6cSJonas Devlieghere                self.assertEqual(
2901263c6cSJonas Devlieghere                    verify_value,
3001263c6cSJonas Devlieghere                    actual_value,
3101263c6cSJonas Devlieghere                    '"%s" keys don\'t match (%s != %s) from:\n%s'
3201263c6cSJonas Devlieghere                    % (key, actual_value, verify_value, actual),
3301263c6cSJonas Devlieghere                )
3401263c6cSJonas Devlieghere        if "startswith" in verify_dict:
3501263c6cSJonas Devlieghere            verify = verify_dict["startswith"]
3601263c6cSJonas Devlieghere            for key in verify:
3701263c6cSJonas Devlieghere                verify_value = verify[key]
3801263c6cSJonas Devlieghere                actual_value = actual[key]
3901263c6cSJonas Devlieghere                startswith = actual_value.startswith(verify_value)
4001263c6cSJonas Devlieghere                self.assertTrue(
4101263c6cSJonas Devlieghere                    startswith,
4240a361acSJohn Harrison                    ('"%s" value "%s" doesn\'t start with "%s")')
4340a361acSJohn Harrison                    % (key, actual_value, verify_value),
4440a361acSJohn Harrison                )
4540a361acSJohn Harrison        if "matches" in verify_dict:
4640a361acSJohn Harrison            verify = verify_dict["matches"]
4740a361acSJohn Harrison            for key in verify:
4840a361acSJohn Harrison                verify_value = verify[key]
4940a361acSJohn Harrison                actual_value = actual[key]
5040a361acSJohn Harrison                self.assertRegex(
5140a361acSJohn Harrison                    actual_value,
5240a361acSJohn Harrison                    verify_value,
5340a361acSJohn Harrison                    ('"%s" value "%s" doesn\'t match pattern "%s")')
5401263c6cSJonas Devlieghere                    % (key, actual_value, verify_value),
5501263c6cSJonas Devlieghere                )
5601263c6cSJonas Devlieghere        if "contains" in verify_dict:
5701263c6cSJonas Devlieghere            verify = verify_dict["contains"]
5801263c6cSJonas Devlieghere            for key in verify:
5901263c6cSJonas Devlieghere                contains_array = verify[key]
6001263c6cSJonas Devlieghere                actual_value = actual[key]
619c246882SJordan Rupprecht                self.assertIsInstance(contains_array, list)
6201263c6cSJonas Devlieghere                for verify_value in contains_array:
6301263c6cSJonas Devlieghere                    self.assertIn(verify_value, actual_value)
6401263c6cSJonas Devlieghere        if "missing" in verify_dict:
6501263c6cSJonas Devlieghere            missing = verify_dict["missing"]
6601263c6cSJonas Devlieghere            for key in missing:
679c246882SJordan Rupprecht                self.assertNotIn(
689c246882SJordan Rupprecht                    key, actual, 'key "%s" is not expected in %s' % (key, actual)
6901263c6cSJonas Devlieghere                )
7001263c6cSJonas Devlieghere        hasVariablesReference = "variablesReference" in actual
7101263c6cSJonas Devlieghere        varRef = None
7201263c6cSJonas Devlieghere        if hasVariablesReference:
7301263c6cSJonas Devlieghere            # Remember variable references in case we want to test further
7401263c6cSJonas Devlieghere            # by using the evaluate name.
7501263c6cSJonas Devlieghere            varRef = actual["variablesReference"]
7601263c6cSJonas Devlieghere            if varRef != 0 and varref_dict is not None:
7701263c6cSJonas Devlieghere                if expression is None:
7801263c6cSJonas Devlieghere                    evaluateName = actual["evaluateName"]
7901263c6cSJonas Devlieghere                else:
8001263c6cSJonas Devlieghere                    evaluateName = expression
8101263c6cSJonas Devlieghere                varref_dict[evaluateName] = varRef
8201263c6cSJonas Devlieghere        if (
8301263c6cSJonas Devlieghere            "hasVariablesReference" in verify_dict
8401263c6cSJonas Devlieghere            and verify_dict["hasVariablesReference"]
8501263c6cSJonas Devlieghere        ):
8601263c6cSJonas Devlieghere            self.assertTrue(hasVariablesReference, "verify variable reference")
8701263c6cSJonas Devlieghere        if "children" in verify_dict:
8801263c6cSJonas Devlieghere            self.assertTrue(
8901263c6cSJonas Devlieghere                hasVariablesReference and varRef is not None and varRef != 0,
9001263c6cSJonas Devlieghere                ("children verify values specified for " "variable without children"),
9101263c6cSJonas Devlieghere            )
9201263c6cSJonas Devlieghere
9301263c6cSJonas Devlieghere            response = self.dap_server.request_variables(varRef)
9401263c6cSJonas Devlieghere            self.verify_variables(
9501263c6cSJonas Devlieghere                verify_dict["children"], response["body"]["variables"], varref_dict
9601263c6cSJonas Devlieghere            )
9701263c6cSJonas Devlieghere
9801263c6cSJonas Devlieghere    def verify_variables(self, verify_dict, variables, varref_dict=None):
9901263c6cSJonas Devlieghere        for variable in variables:
10001263c6cSJonas Devlieghere            name = variable["name"]
101638a8393SMichael Buch            if not name.startswith("std::"):
10201263c6cSJonas Devlieghere                self.assertIn(
10301263c6cSJonas Devlieghere                    name, verify_dict, 'variable "%s" in verify dictionary' % (name)
10401263c6cSJonas Devlieghere                )
10501263c6cSJonas Devlieghere                self.verify_values(verify_dict[name], variable, varref_dict)
10601263c6cSJonas Devlieghere
10701263c6cSJonas Devlieghere    def darwin_dwarf_missing_obj(self, initCommands):
10801263c6cSJonas Devlieghere        self.build(debug_info="dwarf")
10901263c6cSJonas Devlieghere        program = self.getBuildArtifact("a.out")
11001263c6cSJonas Devlieghere        main_obj = self.getBuildArtifact("main.o")
11101263c6cSJonas Devlieghere        self.assertTrue(os.path.exists(main_obj))
11201263c6cSJonas Devlieghere        # Delete the main.o file that contains the debug info so we force an
11301263c6cSJonas Devlieghere        # error when we run to main and try to get variables
11401263c6cSJonas Devlieghere        os.unlink(main_obj)
11501263c6cSJonas Devlieghere
11601263c6cSJonas Devlieghere        self.create_debug_adaptor()
11701263c6cSJonas Devlieghere        self.assertTrue(os.path.exists(program), "executable must exist")
11801263c6cSJonas Devlieghere
11901263c6cSJonas Devlieghere        self.launch(program=program, initCommands=initCommands)
12001263c6cSJonas Devlieghere
12101263c6cSJonas Devlieghere        functions = ["main"]
12201263c6cSJonas Devlieghere        breakpoint_ids = self.set_function_breakpoints(functions)
12380fcecb1SJonas Devlieghere        self.assertEqual(len(breakpoint_ids), len(functions), "expect one breakpoint")
12401263c6cSJonas Devlieghere        self.continue_to_breakpoints(breakpoint_ids)
12501263c6cSJonas Devlieghere
12601263c6cSJonas Devlieghere        locals = self.dap_server.get_local_variables()
12701263c6cSJonas Devlieghere
12801263c6cSJonas Devlieghere        verify_locals = {
12901263c6cSJonas Devlieghere            "<error>": {
13001263c6cSJonas Devlieghere                "equals": {"type": "const char *"},
13101263c6cSJonas Devlieghere                "contains": {
13201263c6cSJonas Devlieghere                    "value": [
13301263c6cSJonas Devlieghere                        "debug map object file ",
13401263c6cSJonas Devlieghere                        'main.o" containing debug info does not exist, debug info will not be loaded',
13501263c6cSJonas Devlieghere                    ]
13601263c6cSJonas Devlieghere                },
13701263c6cSJonas Devlieghere            },
13801263c6cSJonas Devlieghere        }
13901263c6cSJonas Devlieghere        varref_dict = {}
14001263c6cSJonas Devlieghere        self.verify_variables(verify_locals, locals, varref_dict)
14101263c6cSJonas Devlieghere
14201263c6cSJonas Devlieghere    def do_test_scopes_variables_setVariable_evaluate(
14301263c6cSJonas Devlieghere        self, enableAutoVariableSummaries: bool
14401263c6cSJonas Devlieghere    ):
14501263c6cSJonas Devlieghere        """
14601263c6cSJonas Devlieghere        Tests the "scopes", "variables", "setVariable", and "evaluate"
14701263c6cSJonas Devlieghere        packets.
14801263c6cSJonas Devlieghere        """
14901263c6cSJonas Devlieghere        program = self.getBuildArtifact("a.out")
15001263c6cSJonas Devlieghere        self.build_and_launch(
15101263c6cSJonas Devlieghere            program, enableAutoVariableSummaries=enableAutoVariableSummaries
15201263c6cSJonas Devlieghere        )
15301263c6cSJonas Devlieghere        source = "main.cpp"
15401263c6cSJonas Devlieghere        breakpoint1_line = line_number(source, "// breakpoint 1")
15501263c6cSJonas Devlieghere        lines = [breakpoint1_line]
15601263c6cSJonas Devlieghere        # Set breakpoint in the thread function so we can step the threads
15701263c6cSJonas Devlieghere        breakpoint_ids = self.set_source_breakpoints(source, lines)
15801263c6cSJonas Devlieghere        self.assertEqual(
15901263c6cSJonas Devlieghere            len(breakpoint_ids), len(lines), "expect correct number of breakpoints"
16001263c6cSJonas Devlieghere        )
16101263c6cSJonas Devlieghere        self.continue_to_breakpoints(breakpoint_ids)
16201263c6cSJonas Devlieghere        locals = self.dap_server.get_local_variables()
16301263c6cSJonas Devlieghere        globals = self.dap_server.get_global_variables()
16440a361acSJohn Harrison        buffer_children = make_buffer_verify_dict(0, 16)
16501263c6cSJonas Devlieghere        verify_locals = {
1660ea19bd3SWalter Erquinigo            "argc": {
167ffd173baSWalter Erquinigo                "equals": {
168ffd173baSWalter Erquinigo                    "type": "int",
169ffd173baSWalter Erquinigo                    "value": "1",
170ffd173baSWalter Erquinigo                },
171ffd173baSWalter Erquinigo                "$__lldb_extensions": {
172ffd173baSWalter Erquinigo                    "equals": {
173ffd173baSWalter Erquinigo                        "value": "1",
174ffd173baSWalter Erquinigo                    },
1750ea19bd3SWalter Erquinigo                    "declaration": {
1760ea19bd3SWalter Erquinigo                        "equals": {"line": 12, "column": 14},
1770ea19bd3SWalter Erquinigo                        "contains": {"path": ["lldb-dap", "variables", "main.cpp"]},
1780ea19bd3SWalter Erquinigo                    },
1790ea19bd3SWalter Erquinigo                },
180ffd173baSWalter Erquinigo            },
18101263c6cSJonas Devlieghere            "argv": {
18201263c6cSJonas Devlieghere                "equals": {"type": "const char **"},
18301263c6cSJonas Devlieghere                "startswith": {"value": "0x"},
18401263c6cSJonas Devlieghere                "hasVariablesReference": True,
18501263c6cSJonas Devlieghere            },
18601263c6cSJonas Devlieghere            "pt": {
187ffd173baSWalter Erquinigo                "equals": {
188ffd173baSWalter Erquinigo                    "type": "PointType",
189ffd173baSWalter Erquinigo                },
19001263c6cSJonas Devlieghere                "hasVariablesReference": True,
19101263c6cSJonas Devlieghere                "children": {
19201263c6cSJonas Devlieghere                    "x": {"equals": {"type": "int", "value": "11"}},
19301263c6cSJonas Devlieghere                    "y": {"equals": {"type": "int", "value": "22"}},
19401263c6cSJonas Devlieghere                    "buffer": {"children": buffer_children},
19501263c6cSJonas Devlieghere                },
19601263c6cSJonas Devlieghere            },
19701263c6cSJonas Devlieghere            "x": {"equals": {"type": "int"}},
19801263c6cSJonas Devlieghere        }
199ffd173baSWalter Erquinigo        if enableAutoVariableSummaries:
200ffd173baSWalter Erquinigo            verify_locals["pt"]["$__lldb_extensions"] = {
201ffd173baSWalter Erquinigo                "equals": {"autoSummary": "{x:11, y:22}"}
202ffd173baSWalter Erquinigo            }
203a3cd8d76SDavid Spickett
20401263c6cSJonas Devlieghere        verify_globals = {
20501263c6cSJonas Devlieghere            "s_local": {"equals": {"type": "float", "value": "2.25"}},
20601263c6cSJonas Devlieghere        }
207a3cd8d76SDavid Spickett        s_global = {"equals": {"type": "int", "value": "234"}}
208a3cd8d76SDavid Spickett        g_global = {"equals": {"type": "int", "value": "123"}}
209a3cd8d76SDavid Spickett        if lldbplatformutil.getHostPlatform() == "windows":
210a3cd8d76SDavid Spickett            verify_globals["::s_global"] = s_global
211a3cd8d76SDavid Spickett            verify_globals["g_global"] = g_global
212a3cd8d76SDavid Spickett        else:
213a3cd8d76SDavid Spickett            verify_globals["s_global"] = s_global
214a3cd8d76SDavid Spickett            verify_globals["::g_global"] = g_global
215a3cd8d76SDavid Spickett
21601263c6cSJonas Devlieghere        varref_dict = {}
21701263c6cSJonas Devlieghere        self.verify_variables(verify_locals, locals, varref_dict)
21801263c6cSJonas Devlieghere        self.verify_variables(verify_globals, globals, varref_dict)
21901263c6cSJonas Devlieghere        # pprint.PrettyPrinter(indent=4).pprint(varref_dict)
22001263c6cSJonas Devlieghere        # We need to test the functionality of the "variables" request as it
22101263c6cSJonas Devlieghere        # has optional parameters like "start" and "count" to limit the number
22201263c6cSJonas Devlieghere        # of variables that are fetched
22301263c6cSJonas Devlieghere        varRef = varref_dict["pt.buffer"]
22401263c6cSJonas Devlieghere        response = self.dap_server.request_variables(varRef)
22501263c6cSJonas Devlieghere        self.verify_variables(buffer_children, response["body"]["variables"])
22601263c6cSJonas Devlieghere        # Verify setting start=0 in the arguments still gets all children
22701263c6cSJonas Devlieghere        response = self.dap_server.request_variables(varRef, start=0)
22801263c6cSJonas Devlieghere        self.verify_variables(buffer_children, response["body"]["variables"])
22901263c6cSJonas Devlieghere        # Verify setting count=0 in the arguments still gets all children.
23001263c6cSJonas Devlieghere        # If count is zero, it means to get all children.
23101263c6cSJonas Devlieghere        response = self.dap_server.request_variables(varRef, count=0)
23201263c6cSJonas Devlieghere        self.verify_variables(buffer_children, response["body"]["variables"])
23301263c6cSJonas Devlieghere        # Verify setting count to a value that is too large in the arguments
23401263c6cSJonas Devlieghere        # still gets all children, and no more
23501263c6cSJonas Devlieghere        response = self.dap_server.request_variables(varRef, count=1000)
23601263c6cSJonas Devlieghere        self.verify_variables(buffer_children, response["body"]["variables"])
23701263c6cSJonas Devlieghere        # Verify setting the start index and count gets only the children we
23801263c6cSJonas Devlieghere        # want
23901263c6cSJonas Devlieghere        response = self.dap_server.request_variables(varRef, start=5, count=5)
24001263c6cSJonas Devlieghere        self.verify_variables(
24101263c6cSJonas Devlieghere            make_buffer_verify_dict(5, 5), response["body"]["variables"]
24201263c6cSJonas Devlieghere        )
24301263c6cSJonas Devlieghere        # Verify setting the start index to a value that is out of range
24401263c6cSJonas Devlieghere        # results in an empty list
24501263c6cSJonas Devlieghere        response = self.dap_server.request_variables(varRef, start=32, count=1)
24601263c6cSJonas Devlieghere        self.assertEqual(
24701263c6cSJonas Devlieghere            len(response["body"]["variables"]),
24801263c6cSJonas Devlieghere            0,
24901263c6cSJonas Devlieghere            "verify we get no variable back for invalid start",
25001263c6cSJonas Devlieghere        )
25101263c6cSJonas Devlieghere
25201263c6cSJonas Devlieghere        # Test evaluate
25301263c6cSJonas Devlieghere        expressions = {
25401263c6cSJonas Devlieghere            "pt.x": {
25501263c6cSJonas Devlieghere                "equals": {"result": "11", "type": "int"},
25601263c6cSJonas Devlieghere                "hasVariablesReference": False,
25701263c6cSJonas Devlieghere            },
25801263c6cSJonas Devlieghere            "pt.buffer[2]": {
25901263c6cSJonas Devlieghere                "equals": {"result": "2", "type": "int"},
26001263c6cSJonas Devlieghere                "hasVariablesReference": False,
26101263c6cSJonas Devlieghere            },
26201263c6cSJonas Devlieghere            "pt": {
26301263c6cSJonas Devlieghere                "equals": {"type": "PointType"},
26401263c6cSJonas Devlieghere                "startswith": {
265a4ad0528SJonas Devlieghere                    "result": (
266a4ad0528SJonas Devlieghere                        "{x:11, y:22, buffer:{...}}"
26701263c6cSJonas Devlieghere                        if enableAutoVariableSummaries
26801263c6cSJonas Devlieghere                        else "PointType @ 0x"
269a4ad0528SJonas Devlieghere                    )
27001263c6cSJonas Devlieghere                },
27101263c6cSJonas Devlieghere                "hasVariablesReference": True,
27201263c6cSJonas Devlieghere            },
27301263c6cSJonas Devlieghere            "pt.buffer": {
27440a361acSJohn Harrison                "equals": {"type": "int[16]"},
27501263c6cSJonas Devlieghere                "startswith": {
276a4ad0528SJonas Devlieghere                    "result": (
277a4ad0528SJonas Devlieghere                        "{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ...}"
27801263c6cSJonas Devlieghere                        if enableAutoVariableSummaries
27940a361acSJohn Harrison                        else "int[16] @ 0x"
280a4ad0528SJonas Devlieghere                    )
28101263c6cSJonas Devlieghere                },
28201263c6cSJonas Devlieghere                "hasVariablesReference": True,
28301263c6cSJonas Devlieghere            },
28401263c6cSJonas Devlieghere            "argv": {
28501263c6cSJonas Devlieghere                "equals": {"type": "const char **"},
28601263c6cSJonas Devlieghere                "startswith": {"result": "0x"},
28701263c6cSJonas Devlieghere                "hasVariablesReference": True,
28801263c6cSJonas Devlieghere            },
28901263c6cSJonas Devlieghere            "argv[0]": {
29001263c6cSJonas Devlieghere                "equals": {"type": "const char *"},
29101263c6cSJonas Devlieghere                "startswith": {"result": "0x"},
29201263c6cSJonas Devlieghere                "hasVariablesReference": True,
29301263c6cSJonas Devlieghere            },
29401263c6cSJonas Devlieghere            "2+3": {
29501263c6cSJonas Devlieghere                "equals": {"result": "5", "type": "int"},
29601263c6cSJonas Devlieghere                "hasVariablesReference": False,
29701263c6cSJonas Devlieghere            },
29801263c6cSJonas Devlieghere        }
29901263c6cSJonas Devlieghere        for expression in expressions:
30001263c6cSJonas Devlieghere            response = self.dap_server.request_evaluate(expression)
30101263c6cSJonas Devlieghere            self.verify_values(expressions[expression], response["body"])
30201263c6cSJonas Devlieghere
30301263c6cSJonas Devlieghere        # Test setting variables
30401263c6cSJonas Devlieghere        self.set_local("argc", 123)
30501263c6cSJonas Devlieghere        argc = self.get_local_as_int("argc")
30601263c6cSJonas Devlieghere        self.assertEqual(argc, 123, "verify argc was set to 123 (123 != %i)" % (argc))
30701263c6cSJonas Devlieghere
30801263c6cSJonas Devlieghere        self.set_local("argv", 0x1234)
30901263c6cSJonas Devlieghere        argv = self.get_local_as_int("argv")
31001263c6cSJonas Devlieghere        self.assertEqual(
31101263c6cSJonas Devlieghere            argv, 0x1234, "verify argv was set to 0x1234 (0x1234 != %#x)" % (argv)
31201263c6cSJonas Devlieghere        )
31301263c6cSJonas Devlieghere
31401263c6cSJonas Devlieghere        # Set a variable value whose name is synthetic, like a variable index
31501263c6cSJonas Devlieghere        # and verify the value by reading it
31601263c6cSJonas Devlieghere        self.dap_server.request_setVariable(varRef, "[0]", 100)
31701263c6cSJonas Devlieghere        response = self.dap_server.request_variables(varRef, start=0, count=1)
31801263c6cSJonas Devlieghere        self.verify_variables(
31901263c6cSJonas Devlieghere            make_buffer_verify_dict(0, 1, 100), response["body"]["variables"]
32001263c6cSJonas Devlieghere        )
32101263c6cSJonas Devlieghere
32201263c6cSJonas Devlieghere        # Set a variable value whose name is a real child value, like "pt.x"
32301263c6cSJonas Devlieghere        # and verify the value by reading it
32401263c6cSJonas Devlieghere        varRef = varref_dict["pt"]
32501263c6cSJonas Devlieghere        self.dap_server.request_setVariable(varRef, "x", 111)
32601263c6cSJonas Devlieghere        response = self.dap_server.request_variables(varRef, start=0, count=1)
32701263c6cSJonas Devlieghere        value = response["body"]["variables"][0]["value"]
32801263c6cSJonas Devlieghere        self.assertEqual(
32901263c6cSJonas Devlieghere            value, "111", "verify pt.x got set to 111 (111 != %s)" % (value)
33001263c6cSJonas Devlieghere        )
33101263c6cSJonas Devlieghere
33201263c6cSJonas Devlieghere        # We check shadowed variables and that a new get_local_variables request
33301263c6cSJonas Devlieghere        # gets the right data
33401263c6cSJonas Devlieghere        breakpoint2_line = line_number(source, "// breakpoint 2")
33501263c6cSJonas Devlieghere        lines = [breakpoint2_line]
33601263c6cSJonas Devlieghere        breakpoint_ids = self.set_source_breakpoints(source, lines)
33701263c6cSJonas Devlieghere        self.assertEqual(
33801263c6cSJonas Devlieghere            len(breakpoint_ids), len(lines), "expect correct number of breakpoints"
33901263c6cSJonas Devlieghere        )
34001263c6cSJonas Devlieghere        self.continue_to_breakpoints(breakpoint_ids)
34101263c6cSJonas Devlieghere
34201263c6cSJonas Devlieghere        verify_locals["argc"]["equals"]["value"] = "123"
34301263c6cSJonas Devlieghere        verify_locals["pt"]["children"]["x"]["equals"]["value"] = "111"
34401263c6cSJonas Devlieghere        verify_locals["x @ main.cpp:17"] = {"equals": {"type": "int", "value": "89"}}
34501263c6cSJonas Devlieghere        verify_locals["x @ main.cpp:19"] = {"equals": {"type": "int", "value": "42"}}
34601263c6cSJonas Devlieghere        verify_locals["x @ main.cpp:21"] = {"equals": {"type": "int", "value": "72"}}
34701263c6cSJonas Devlieghere
34801263c6cSJonas Devlieghere        self.verify_variables(verify_locals, self.dap_server.get_local_variables())
34901263c6cSJonas Devlieghere
35001263c6cSJonas Devlieghere        # Now we verify that we correctly change the name of a variable with and without differentiator suffix
35101263c6cSJonas Devlieghere        self.assertFalse(self.dap_server.request_setVariable(1, "x2", 9)["success"])
35201263c6cSJonas Devlieghere        self.assertFalse(
35301263c6cSJonas Devlieghere            self.dap_server.request_setVariable(1, "x @ main.cpp:0", 9)["success"]
35401263c6cSJonas Devlieghere        )
35501263c6cSJonas Devlieghere
35601263c6cSJonas Devlieghere        self.assertTrue(
35701263c6cSJonas Devlieghere            self.dap_server.request_setVariable(1, "x @ main.cpp:17", 17)["success"]
35801263c6cSJonas Devlieghere        )
35901263c6cSJonas Devlieghere        self.assertTrue(
36001263c6cSJonas Devlieghere            self.dap_server.request_setVariable(1, "x @ main.cpp:19", 19)["success"]
36101263c6cSJonas Devlieghere        )
36201263c6cSJonas Devlieghere        self.assertTrue(
36301263c6cSJonas Devlieghere            self.dap_server.request_setVariable(1, "x @ main.cpp:21", 21)["success"]
36401263c6cSJonas Devlieghere        )
36501263c6cSJonas Devlieghere
36601263c6cSJonas Devlieghere        # The following should have no effect
36701263c6cSJonas Devlieghere        self.assertFalse(
36801263c6cSJonas Devlieghere            self.dap_server.request_setVariable(1, "x @ main.cpp:21", "invalid")[
36901263c6cSJonas Devlieghere                "success"
37001263c6cSJonas Devlieghere            ]
37101263c6cSJonas Devlieghere        )
37201263c6cSJonas Devlieghere
37301263c6cSJonas Devlieghere        verify_locals["x @ main.cpp:17"]["equals"]["value"] = "17"
37401263c6cSJonas Devlieghere        verify_locals["x @ main.cpp:19"]["equals"]["value"] = "19"
37501263c6cSJonas Devlieghere        verify_locals["x @ main.cpp:21"]["equals"]["value"] = "21"
37601263c6cSJonas Devlieghere
37701263c6cSJonas Devlieghere        self.verify_variables(verify_locals, self.dap_server.get_local_variables())
37801263c6cSJonas Devlieghere
37901263c6cSJonas Devlieghere        # The plain x variable shold refer to the innermost x
38001263c6cSJonas Devlieghere        self.assertTrue(self.dap_server.request_setVariable(1, "x", 22)["success"])
38101263c6cSJonas Devlieghere        verify_locals["x @ main.cpp:21"]["equals"]["value"] = "22"
38201263c6cSJonas Devlieghere
38301263c6cSJonas Devlieghere        self.verify_variables(verify_locals, self.dap_server.get_local_variables())
38401263c6cSJonas Devlieghere
38501263c6cSJonas Devlieghere        # In breakpoint 3, there should be no shadowed variables
38601263c6cSJonas Devlieghere        breakpoint3_line = line_number(source, "// breakpoint 3")
38701263c6cSJonas Devlieghere        lines = [breakpoint3_line]
38801263c6cSJonas Devlieghere        breakpoint_ids = self.set_source_breakpoints(source, lines)
38901263c6cSJonas Devlieghere        self.assertEqual(
39001263c6cSJonas Devlieghere            len(breakpoint_ids), len(lines), "expect correct number of breakpoints"
39101263c6cSJonas Devlieghere        )
39201263c6cSJonas Devlieghere        self.continue_to_breakpoints(breakpoint_ids)
39301263c6cSJonas Devlieghere
39401263c6cSJonas Devlieghere        locals = self.dap_server.get_local_variables()
39501263c6cSJonas Devlieghere        names = [var["name"] for var in locals]
39601263c6cSJonas Devlieghere        # The first shadowed x shouldn't have a suffix anymore
39701263c6cSJonas Devlieghere        verify_locals["x"] = {"equals": {"type": "int", "value": "17"}}
39801263c6cSJonas Devlieghere        self.assertNotIn("x @ main.cpp:17", names)
39901263c6cSJonas Devlieghere        self.assertNotIn("x @ main.cpp:19", names)
40001263c6cSJonas Devlieghere        self.assertNotIn("x @ main.cpp:21", names)
40101263c6cSJonas Devlieghere
40201263c6cSJonas Devlieghere        self.verify_variables(verify_locals, locals)
40301263c6cSJonas Devlieghere
40401263c6cSJonas Devlieghere    def test_scopes_variables_setVariable_evaluate(self):
40501263c6cSJonas Devlieghere        self.do_test_scopes_variables_setVariable_evaluate(
40601263c6cSJonas Devlieghere            enableAutoVariableSummaries=False
40701263c6cSJonas Devlieghere        )
40801263c6cSJonas Devlieghere
40901263c6cSJonas Devlieghere    def test_scopes_variables_setVariable_evaluate_with_descriptive_summaries(self):
41001263c6cSJonas Devlieghere        self.do_test_scopes_variables_setVariable_evaluate(
41101263c6cSJonas Devlieghere            enableAutoVariableSummaries=True
41201263c6cSJonas Devlieghere        )
41301263c6cSJonas Devlieghere
41401263c6cSJonas Devlieghere    def do_test_scopes_and_evaluate_expansion(self, enableAutoVariableSummaries: bool):
41501263c6cSJonas Devlieghere        """
41601263c6cSJonas Devlieghere        Tests the evaluated expression expands successfully after "scopes" packets
41701263c6cSJonas Devlieghere        and permanent expressions persist.
41801263c6cSJonas Devlieghere        """
41901263c6cSJonas Devlieghere        program = self.getBuildArtifact("a.out")
42001263c6cSJonas Devlieghere        self.build_and_launch(
42101263c6cSJonas Devlieghere            program, enableAutoVariableSummaries=enableAutoVariableSummaries
42201263c6cSJonas Devlieghere        )
42301263c6cSJonas Devlieghere        source = "main.cpp"
42401263c6cSJonas Devlieghere        breakpoint1_line = line_number(source, "// breakpoint 1")
42501263c6cSJonas Devlieghere        lines = [breakpoint1_line]
42601263c6cSJonas Devlieghere        # Set breakpoint in the thread function so we can step the threads
42701263c6cSJonas Devlieghere        breakpoint_ids = self.set_source_breakpoints(source, lines)
42801263c6cSJonas Devlieghere        self.assertEqual(
42901263c6cSJonas Devlieghere            len(breakpoint_ids), len(lines), "expect correct number of breakpoints"
43001263c6cSJonas Devlieghere        )
43101263c6cSJonas Devlieghere        self.continue_to_breakpoints(breakpoint_ids)
43201263c6cSJonas Devlieghere
43301263c6cSJonas Devlieghere        # Verify locals
43401263c6cSJonas Devlieghere        locals = self.dap_server.get_local_variables()
43501263c6cSJonas Devlieghere        buffer_children = make_buffer_verify_dict(0, 32)
43601263c6cSJonas Devlieghere        verify_locals = {
43701263c6cSJonas Devlieghere            "argc": {
43801263c6cSJonas Devlieghere                "equals": {"type": "int", "value": "1"},
43901263c6cSJonas Devlieghere                "missing": ["indexedVariables"],
44001263c6cSJonas Devlieghere            },
44101263c6cSJonas Devlieghere            "argv": {
44201263c6cSJonas Devlieghere                "equals": {"type": "const char **"},
44301263c6cSJonas Devlieghere                "startswith": {"value": "0x"},
44401263c6cSJonas Devlieghere                "hasVariablesReference": True,
44501263c6cSJonas Devlieghere                "missing": ["indexedVariables"],
44601263c6cSJonas Devlieghere            },
44701263c6cSJonas Devlieghere            "pt": {
44801263c6cSJonas Devlieghere                "equals": {"type": "PointType"},
44901263c6cSJonas Devlieghere                "hasVariablesReference": True,
45001263c6cSJonas Devlieghere                "missing": ["indexedVariables"],
45101263c6cSJonas Devlieghere                "children": {
45201263c6cSJonas Devlieghere                    "x": {
45301263c6cSJonas Devlieghere                        "equals": {"type": "int", "value": "11"},
45401263c6cSJonas Devlieghere                        "missing": ["indexedVariables"],
45501263c6cSJonas Devlieghere                    },
45601263c6cSJonas Devlieghere                    "y": {
45701263c6cSJonas Devlieghere                        "equals": {"type": "int", "value": "22"},
45801263c6cSJonas Devlieghere                        "missing": ["indexedVariables"],
45901263c6cSJonas Devlieghere                    },
46001263c6cSJonas Devlieghere                    "buffer": {
46101263c6cSJonas Devlieghere                        "children": buffer_children,
46240a361acSJohn Harrison                        "equals": {"indexedVariables": 16},
46301263c6cSJonas Devlieghere                    },
46401263c6cSJonas Devlieghere                },
46501263c6cSJonas Devlieghere            },
46601263c6cSJonas Devlieghere            "x": {
46701263c6cSJonas Devlieghere                "equals": {"type": "int"},
46801263c6cSJonas Devlieghere                "missing": ["indexedVariables"],
46901263c6cSJonas Devlieghere            },
47001263c6cSJonas Devlieghere        }
47101263c6cSJonas Devlieghere        self.verify_variables(verify_locals, locals)
47201263c6cSJonas Devlieghere
47301263c6cSJonas Devlieghere        # Evaluate expandable expression twice: once permanent (from repl)
47401263c6cSJonas Devlieghere        # the other temporary (from other UI).
47501263c6cSJonas Devlieghere        expandable_expression = {
47601263c6cSJonas Devlieghere            "name": "pt",
47740a361acSJohn Harrison            "context": {
47840a361acSJohn Harrison                "repl": {
47940a361acSJohn Harrison                    "equals": {"type": "PointType"},
48040a361acSJohn Harrison                    "equals": {
48140a361acSJohn Harrison                        "result": """(PointType) $0 = {
48240a361acSJohn Harrison  x = 11
48340a361acSJohn Harrison  y = 22
48440a361acSJohn Harrison  buffer = {
48540a361acSJohn Harrison    [0] = 0
48640a361acSJohn Harrison    [1] = 1
48740a361acSJohn Harrison    [2] = 2
48840a361acSJohn Harrison    [3] = 3
48940a361acSJohn Harrison    [4] = 4
49040a361acSJohn Harrison    [5] = 5
49140a361acSJohn Harrison    [6] = 6
49240a361acSJohn Harrison    [7] = 7
49340a361acSJohn Harrison    [8] = 8
49440a361acSJohn Harrison    [9] = 9
49540a361acSJohn Harrison    [10] = 10
49640a361acSJohn Harrison    [11] = 11
49740a361acSJohn Harrison    [12] = 12
49840a361acSJohn Harrison    [13] = 13
49940a361acSJohn Harrison    [14] = 14
50040a361acSJohn Harrison    [15] = 15
50140a361acSJohn Harrison  }
50240a361acSJohn Harrison}"""
50340a361acSJohn Harrison                    },
50440a361acSJohn Harrison                    "missing": ["indexedVariables"],
50540a361acSJohn Harrison                    "hasVariablesReference": True,
50640a361acSJohn Harrison                },
50740a361acSJohn Harrison                "hover": {
50840a361acSJohn Harrison                    "equals": {"type": "PointType"},
509af8f1554SPavel Labath                    "startswith": {
510af8f1554SPavel Labath                        "result": (
511af8f1554SPavel Labath                            "{x:11, y:22, buffer:{...}}"
512af8f1554SPavel Labath                            if enableAutoVariableSummaries
513af8f1554SPavel Labath                            else "PointType @ 0x"
514af8f1554SPavel Labath                        )
51540a361acSJohn Harrison                    },
51640a361acSJohn Harrison                    "missing": ["indexedVariables"],
51740a361acSJohn Harrison                    "hasVariablesReference": True,
51840a361acSJohn Harrison                },
51940a361acSJohn Harrison                "watch": {
52001263c6cSJonas Devlieghere                    "equals": {"type": "PointType"},
52101263c6cSJonas Devlieghere                    "startswith": {
522a4ad0528SJonas Devlieghere                        "result": (
523a4ad0528SJonas Devlieghere                            "{x:11, y:22, buffer:{...}}"
52401263c6cSJonas Devlieghere                            if enableAutoVariableSummaries
52501263c6cSJonas Devlieghere                            else "PointType @ 0x"
526a4ad0528SJonas Devlieghere                        )
52701263c6cSJonas Devlieghere                    },
52801263c6cSJonas Devlieghere                    "missing": ["indexedVariables"],
52901263c6cSJonas Devlieghere                    "hasVariablesReference": True,
53001263c6cSJonas Devlieghere                },
53140a361acSJohn Harrison                "variables": {
53240a361acSJohn Harrison                    "equals": {"type": "PointType"},
53340a361acSJohn Harrison                    "startswith": {
534a4ad0528SJonas Devlieghere                        "result": (
535a4ad0528SJonas Devlieghere                            "{x:11, y:22, buffer:{...}}"
53640a361acSJohn Harrison                            if enableAutoVariableSummaries
53740a361acSJohn Harrison                            else "PointType @ 0x"
538a4ad0528SJonas Devlieghere                        )
53940a361acSJohn Harrison                    },
54040a361acSJohn Harrison                    "missing": ["indexedVariables"],
54140a361acSJohn Harrison                    "hasVariablesReference": True,
54240a361acSJohn Harrison                },
54340a361acSJohn Harrison            },
54401263c6cSJonas Devlieghere            "children": {
54501263c6cSJonas Devlieghere                "x": {"equals": {"type": "int", "value": "11"}},
54601263c6cSJonas Devlieghere                "y": {"equals": {"type": "int", "value": "22"}},
54701263c6cSJonas Devlieghere                "buffer": {"children": buffer_children},
54801263c6cSJonas Devlieghere            },
54901263c6cSJonas Devlieghere        }
55001263c6cSJonas Devlieghere
55140a361acSJohn Harrison        # Evaluate from known contexts.
55240a361acSJohn Harrison        expr_varref_dict = {}
55340a361acSJohn Harrison        for context, verify_dict in expandable_expression["context"].items():
55401263c6cSJonas Devlieghere            response = self.dap_server.request_evaluate(
55501263c6cSJonas Devlieghere                expandable_expression["name"],
55640a361acSJohn Harrison                frameIndex=0,
55740a361acSJohn Harrison                threadId=None,
55840a361acSJohn Harrison                context=context,
55901263c6cSJonas Devlieghere            )
56001263c6cSJonas Devlieghere            self.verify_values(
56140a361acSJohn Harrison                verify_dict,
56201263c6cSJonas Devlieghere                response["body"],
56340a361acSJohn Harrison                expr_varref_dict,
56401263c6cSJonas Devlieghere                expandable_expression["name"],
56501263c6cSJonas Devlieghere            )
56601263c6cSJonas Devlieghere
56701263c6cSJonas Devlieghere        # Evaluate locals again.
56801263c6cSJonas Devlieghere        locals = self.dap_server.get_local_variables()
56901263c6cSJonas Devlieghere        self.verify_variables(verify_locals, locals)
57001263c6cSJonas Devlieghere
57101263c6cSJonas Devlieghere        # Verify the evaluated expressions before second locals evaluation
57201263c6cSJonas Devlieghere        # can be expanded.
57340a361acSJohn Harrison        var_ref = expr_varref_dict[expandable_expression["name"]]
57401263c6cSJonas Devlieghere        response = self.dap_server.request_variables(var_ref)
57501263c6cSJonas Devlieghere        self.verify_variables(
57601263c6cSJonas Devlieghere            expandable_expression["children"], response["body"]["variables"]
57701263c6cSJonas Devlieghere        )
57801263c6cSJonas Devlieghere
57901263c6cSJonas Devlieghere        # Continue to breakpoint 3, permanent variable should still exist
58001263c6cSJonas Devlieghere        # after resume.
58101263c6cSJonas Devlieghere        breakpoint3_line = line_number(source, "// breakpoint 3")
58201263c6cSJonas Devlieghere        lines = [breakpoint3_line]
58301263c6cSJonas Devlieghere        breakpoint_ids = self.set_source_breakpoints(source, lines)
58401263c6cSJonas Devlieghere        self.assertEqual(
58501263c6cSJonas Devlieghere            len(breakpoint_ids), len(lines), "expect correct number of breakpoints"
58601263c6cSJonas Devlieghere        )
58701263c6cSJonas Devlieghere        self.continue_to_breakpoints(breakpoint_ids)
58801263c6cSJonas Devlieghere
58940a361acSJohn Harrison        var_ref = expr_varref_dict[expandable_expression["name"]]
59001263c6cSJonas Devlieghere        response = self.dap_server.request_variables(var_ref)
59101263c6cSJonas Devlieghere        self.verify_variables(
59201263c6cSJonas Devlieghere            expandable_expression["children"], response["body"]["variables"]
59301263c6cSJonas Devlieghere        )
59401263c6cSJonas Devlieghere
59501263c6cSJonas Devlieghere        # Test that frame scopes have corresponding presentation hints.
59601263c6cSJonas Devlieghere        frame_id = self.dap_server.get_stackFrame()["id"]
59701263c6cSJonas Devlieghere        scopes = self.dap_server.request_scopes(frame_id)["body"]["scopes"]
59801263c6cSJonas Devlieghere
59901263c6cSJonas Devlieghere        scope_names = [scope["name"] for scope in scopes]
60001263c6cSJonas Devlieghere        self.assertIn("Locals", scope_names)
60101263c6cSJonas Devlieghere        self.assertIn("Registers", scope_names)
60201263c6cSJonas Devlieghere
60301263c6cSJonas Devlieghere        for scope in scopes:
60401263c6cSJonas Devlieghere            if scope["name"] == "Locals":
60580fcecb1SJonas Devlieghere                self.assertEqual(scope.get("presentationHint"), "locals")
60601263c6cSJonas Devlieghere            if scope["name"] == "Registers":
60780fcecb1SJonas Devlieghere                self.assertEqual(scope.get("presentationHint"), "registers")
60801263c6cSJonas Devlieghere
60901263c6cSJonas Devlieghere    def test_scopes_and_evaluate_expansion(self):
61001263c6cSJonas Devlieghere        self.do_test_scopes_and_evaluate_expansion(enableAutoVariableSummaries=False)
61101263c6cSJonas Devlieghere
61201263c6cSJonas Devlieghere    def test_scopes_and_evaluate_expansion_with_descriptive_summaries(self):
61301263c6cSJonas Devlieghere        self.do_test_scopes_and_evaluate_expansion(enableAutoVariableSummaries=True)
61401263c6cSJonas Devlieghere
61501263c6cSJonas Devlieghere    def do_test_indexedVariables(self, enableSyntheticChildDebugging: bool):
61601263c6cSJonas Devlieghere        """
61701263c6cSJonas Devlieghere        Tests that arrays and lldb.SBValue objects that have synthetic child
61801263c6cSJonas Devlieghere        providers have "indexedVariables" key/value pairs. This helps the IDE
61901263c6cSJonas Devlieghere        not to fetch too many children all at once.
62001263c6cSJonas Devlieghere        """
62101263c6cSJonas Devlieghere        program = self.getBuildArtifact("a.out")
62201263c6cSJonas Devlieghere        self.build_and_launch(
62301263c6cSJonas Devlieghere            program, enableSyntheticChildDebugging=enableSyntheticChildDebugging
62401263c6cSJonas Devlieghere        )
62501263c6cSJonas Devlieghere        source = "main.cpp"
62601263c6cSJonas Devlieghere        breakpoint1_line = line_number(source, "// breakpoint 4")
62701263c6cSJonas Devlieghere        lines = [breakpoint1_line]
62801263c6cSJonas Devlieghere        # Set breakpoint in the thread function so we can step the threads
62901263c6cSJonas Devlieghere        breakpoint_ids = self.set_source_breakpoints(source, lines)
63001263c6cSJonas Devlieghere        self.assertEqual(
63101263c6cSJonas Devlieghere            len(breakpoint_ids), len(lines), "expect correct number of breakpoints"
63201263c6cSJonas Devlieghere        )
63301263c6cSJonas Devlieghere        self.continue_to_breakpoints(breakpoint_ids)
63401263c6cSJonas Devlieghere
63501263c6cSJonas Devlieghere        # Verify locals
63601263c6cSJonas Devlieghere        locals = self.dap_server.get_local_variables()
63701263c6cSJonas Devlieghere        # The vector variables might have one additional entry from the fake
63801263c6cSJonas Devlieghere        # "[raw]" child.
63901263c6cSJonas Devlieghere        raw_child_count = 1 if enableSyntheticChildDebugging else 0
64001263c6cSJonas Devlieghere        verify_locals = {
64101263c6cSJonas Devlieghere            "small_array": {"equals": {"indexedVariables": 5}},
64201263c6cSJonas Devlieghere            "large_array": {"equals": {"indexedVariables": 200}},
64301263c6cSJonas Devlieghere            "small_vector": {"equals": {"indexedVariables": 5 + raw_child_count}},
64401263c6cSJonas Devlieghere            "large_vector": {"equals": {"indexedVariables": 200 + raw_child_count}},
64501263c6cSJonas Devlieghere            "pt": {"missing": ["indexedVariables"]},
64601263c6cSJonas Devlieghere        }
64701263c6cSJonas Devlieghere        self.verify_variables(verify_locals, locals)
64801263c6cSJonas Devlieghere
64901263c6cSJonas Devlieghere        # We also verify that we produce a "[raw]" fake child with the real
65001263c6cSJonas Devlieghere        # SBValue for the synthetic type.
65101263c6cSJonas Devlieghere        verify_children = {
65201263c6cSJonas Devlieghere            "[0]": {"equals": {"type": "int", "value": "0"}},
65301263c6cSJonas Devlieghere            "[1]": {"equals": {"type": "int", "value": "0"}},
65401263c6cSJonas Devlieghere            "[2]": {"equals": {"type": "int", "value": "0"}},
65501263c6cSJonas Devlieghere            "[3]": {"equals": {"type": "int", "value": "0"}},
65601263c6cSJonas Devlieghere            "[4]": {"equals": {"type": "int", "value": "0"}},
65701263c6cSJonas Devlieghere        }
65801263c6cSJonas Devlieghere        if enableSyntheticChildDebugging:
65901263c6cSJonas Devlieghere            verify_children["[raw]"] = ({"contains": {"type": ["vector"]}},)
66001263c6cSJonas Devlieghere
66101263c6cSJonas Devlieghere        children = self.dap_server.request_variables(locals[2]["variablesReference"])[
66201263c6cSJonas Devlieghere            "body"
66301263c6cSJonas Devlieghere        ]["variables"]
66401263c6cSJonas Devlieghere        self.verify_variables(verify_children, children)
66501263c6cSJonas Devlieghere
66601263c6cSJonas Devlieghere    @skipIfWindows
66701263c6cSJonas Devlieghere    def test_indexedVariables(self):
66801263c6cSJonas Devlieghere        self.do_test_indexedVariables(enableSyntheticChildDebugging=False)
66901263c6cSJonas Devlieghere
67001263c6cSJonas Devlieghere    @skipIfWindows
67101263c6cSJonas Devlieghere    def test_indexedVariables_with_raw_child_for_synthetics(self):
67201263c6cSJonas Devlieghere        self.do_test_indexedVariables(enableSyntheticChildDebugging=True)
67301263c6cSJonas Devlieghere
67401263c6cSJonas Devlieghere    @skipIfWindows
675*8f18f36bSAdrian Prantl    @skipIfAsan # FIXME this fails with a non-asan issue on green dragon.
67601263c6cSJonas Devlieghere    def test_registers(self):
67701263c6cSJonas Devlieghere        """
67801263c6cSJonas Devlieghere        Test that registers whose byte size is the size of a pointer on
67901263c6cSJonas Devlieghere        the current system get formatted as lldb::eFormatAddressInfo. This
68001263c6cSJonas Devlieghere        will show the pointer value followed by a description of the address
68101263c6cSJonas Devlieghere        itself. To test this we attempt to find the PC value in the general
68201263c6cSJonas Devlieghere        purpose registers, and since we will be stopped in main.cpp, verify
68301263c6cSJonas Devlieghere        that the value for the PC starts with a pointer and is followed by
68401263c6cSJonas Devlieghere        a description that contains main.cpp.
68501263c6cSJonas Devlieghere        """
68601263c6cSJonas Devlieghere        program = self.getBuildArtifact("a.out")
68701263c6cSJonas Devlieghere        self.build_and_launch(program)
68801263c6cSJonas Devlieghere        source = "main.cpp"
68901263c6cSJonas Devlieghere        breakpoint1_line = line_number(source, "// breakpoint 1")
69001263c6cSJonas Devlieghere        lines = [breakpoint1_line]
69101263c6cSJonas Devlieghere        # Set breakpoint in the thread function so we can step the threads
69201263c6cSJonas Devlieghere        breakpoint_ids = self.set_source_breakpoints(source, lines)
69301263c6cSJonas Devlieghere        self.assertEqual(
69401263c6cSJonas Devlieghere            len(breakpoint_ids), len(lines), "expect correct number of breakpoints"
69501263c6cSJonas Devlieghere        )
69601263c6cSJonas Devlieghere        self.continue_to_breakpoints(breakpoint_ids)
69701263c6cSJonas Devlieghere
69801263c6cSJonas Devlieghere        pc_name = None
69901263c6cSJonas Devlieghere        arch = self.getArchitecture()
70001263c6cSJonas Devlieghere        if arch == "x86_64":
70101263c6cSJonas Devlieghere            pc_name = "rip"
70201263c6cSJonas Devlieghere        elif arch == "x86":
70301263c6cSJonas Devlieghere            pc_name = "rip"
70401263c6cSJonas Devlieghere        elif arch.startswith("arm"):
70501263c6cSJonas Devlieghere            pc_name = "pc"
70601263c6cSJonas Devlieghere
70701263c6cSJonas Devlieghere        if pc_name is None:
70801263c6cSJonas Devlieghere            return
70901263c6cSJonas Devlieghere        # Verify locals
71001263c6cSJonas Devlieghere        reg_sets = self.dap_server.get_registers()
71101263c6cSJonas Devlieghere        for reg_set in reg_sets:
71201263c6cSJonas Devlieghere            if reg_set["name"] == "General Purpose Registers":
71301263c6cSJonas Devlieghere                varRef = reg_set["variablesReference"]
71401263c6cSJonas Devlieghere                regs = self.dap_server.request_variables(varRef)["body"]["variables"]
71501263c6cSJonas Devlieghere                for reg in regs:
71601263c6cSJonas Devlieghere                    if reg["name"] == pc_name:
71701263c6cSJonas Devlieghere                        value = reg["value"]
71801263c6cSJonas Devlieghere                        self.assertTrue(value.startswith("0x"))
7199c246882SJordan Rupprecht                        self.assertIn("a.out`main + ", value)
7209c246882SJordan Rupprecht                        self.assertIn("at main.cpp:", value)
72101263c6cSJonas Devlieghere
72201263c6cSJonas Devlieghere    @no_debug_info_test
72301263c6cSJonas Devlieghere    @skipUnlessDarwin
72401263c6cSJonas Devlieghere    def test_darwin_dwarf_missing_obj(self):
72501263c6cSJonas Devlieghere        """
72601263c6cSJonas Devlieghere        Test that if we build a binary with DWARF in .o files and we remove
72701263c6cSJonas Devlieghere        the .o file for main.cpp, that we get a variable named "<error>"
72801263c6cSJonas Devlieghere        whose value matches the appriopriate error. Errors when getting
72901263c6cSJonas Devlieghere        variables are returned in the LLDB API when the user should be
73001263c6cSJonas Devlieghere        notified of issues that can easily be solved by rebuilding or
73101263c6cSJonas Devlieghere        changing compiler options and are designed to give better feedback
73201263c6cSJonas Devlieghere        to the user.
73301263c6cSJonas Devlieghere        """
73401263c6cSJonas Devlieghere        self.darwin_dwarf_missing_obj(None)
73501263c6cSJonas Devlieghere
73601263c6cSJonas Devlieghere    @no_debug_info_test
73701263c6cSJonas Devlieghere    @skipUnlessDarwin
73801263c6cSJonas Devlieghere    def test_darwin_dwarf_missing_obj_with_symbol_ondemand_enabled(self):
73901263c6cSJonas Devlieghere        """
74001263c6cSJonas Devlieghere        Test that if we build a binary with DWARF in .o files and we remove
74101263c6cSJonas Devlieghere        the .o file for main.cpp, that we get a variable named "<error>"
74201263c6cSJonas Devlieghere        whose value matches the appriopriate error. Test with symbol_ondemand_enabled.
74301263c6cSJonas Devlieghere        """
74401263c6cSJonas Devlieghere        initCommands = ["settings set symbols.load-on-demand true"]
74501263c6cSJonas Devlieghere        self.darwin_dwarf_missing_obj(initCommands)
746b8d38bb5Sjeffreytan81
747b8d38bb5Sjeffreytan81    @no_debug_info_test
748b8d38bb5Sjeffreytan81    @skipIfWindows
749b8d38bb5Sjeffreytan81    def test_value_format(self):
750b8d38bb5Sjeffreytan81        """
751b8d38bb5Sjeffreytan81        Test that toggle variables value format between decimal and hexical works.
752b8d38bb5Sjeffreytan81        """
753b8d38bb5Sjeffreytan81        program = self.getBuildArtifact("a.out")
754b8d38bb5Sjeffreytan81        self.build_and_launch(program)
755b8d38bb5Sjeffreytan81        source = "main.cpp"
756b8d38bb5Sjeffreytan81        breakpoint1_line = line_number(source, "// breakpoint 1")
757b8d38bb5Sjeffreytan81        lines = [breakpoint1_line]
758b8d38bb5Sjeffreytan81
759b8d38bb5Sjeffreytan81        breakpoint_ids = self.set_source_breakpoints(source, lines)
760b8d38bb5Sjeffreytan81        self.assertEqual(
761b8d38bb5Sjeffreytan81            len(breakpoint_ids), len(lines), "expect correct number of breakpoints"
762b8d38bb5Sjeffreytan81        )
763b8d38bb5Sjeffreytan81        self.continue_to_breakpoints(breakpoint_ids)
764b8d38bb5Sjeffreytan81
765b8d38bb5Sjeffreytan81        # Verify locals value format decimal
766b8d38bb5Sjeffreytan81        is_hex = False
767b8d38bb5Sjeffreytan81        var_pt_x = self.dap_server.get_local_variable_child("pt", "x", is_hex=is_hex)
768a4ad0528SJonas Devlieghere        self.assertEqual(var_pt_x["value"], "11")
769b8d38bb5Sjeffreytan81        var_pt_y = self.dap_server.get_local_variable_child("pt", "y", is_hex=is_hex)
770a4ad0528SJonas Devlieghere        self.assertEqual(var_pt_y["value"], "22")
771b8d38bb5Sjeffreytan81
772b8d38bb5Sjeffreytan81        # Verify locals value format hexical
773b8d38bb5Sjeffreytan81        is_hex = True
774b8d38bb5Sjeffreytan81        var_pt_x = self.dap_server.get_local_variable_child("pt", "x", is_hex=is_hex)
775a4ad0528SJonas Devlieghere        self.assertEqual(var_pt_x["value"], "0x0000000b")
776b8d38bb5Sjeffreytan81        var_pt_y = self.dap_server.get_local_variable_child("pt", "y", is_hex=is_hex)
777a4ad0528SJonas Devlieghere        self.assertEqual(var_pt_y["value"], "0x00000016")
778b8d38bb5Sjeffreytan81
779b8d38bb5Sjeffreytan81        # Toggle and verify locals value format decimal again
780b8d38bb5Sjeffreytan81        is_hex = False
781b8d38bb5Sjeffreytan81        var_pt_x = self.dap_server.get_local_variable_child("pt", "x", is_hex=is_hex)
782a4ad0528SJonas Devlieghere        self.assertEqual(var_pt_x["value"], "11")
783b8d38bb5Sjeffreytan81        var_pt_y = self.dap_server.get_local_variable_child("pt", "y", is_hex=is_hex)
784a4ad0528SJonas Devlieghere        self.assertEqual(var_pt_y["value"], "22")
785