brintos

brintos / llvm-project-archived public Read only

0
0
Text · 33.4 KiB · 977d6ce Raw
837 lines · python
1"""2Test lldb-dap variables request3"""4 5import os6 7import lldbdap_testcase8from lldbsuite.test.decorators import *9from lldbsuite.test.lldbtest import *10 11 12def make_buffer_verify_dict(start_idx, count, offset=0):13    verify_dict = {}14    for i in range(start_idx, start_idx + count):15        verify_dict["[%i]" % (i)] = {"type": "int", "value": str(i + offset)}16    return verify_dict17 18 19class TestDAP_variables(lldbdap_testcase.DAPTestCaseBase):20    def verify_values(self, verify_dict, actual, varref_dict=None, expression=None):21        if "equals" in verify_dict:22            verify = verify_dict["equals"]23            for key in verify:24                verify_value = verify[key]25                actual_value = actual[key]26                self.assertEqual(27                    verify_value,28                    actual_value,29                    '"%s" keys don\'t match (%s != %s) from:\n%s'30                    % (key, actual_value, verify_value, actual),31                )32        if "startswith" in verify_dict:33            verify = verify_dict["startswith"]34            for key in verify:35                verify_value = verify[key]36                actual_value = actual[key]37                startswith = actual_value.startswith(verify_value)38                self.assertTrue(39                    startswith,40                    ('"%s" value "%s" doesn\'t start with "%s")')41                    % (key, actual_value, verify_value),42                )43        if "matches" in verify_dict:44            verify = verify_dict["matches"]45            for key in verify:46                verify_value = verify[key]47                actual_value = actual[key]48                self.assertRegex(49                    actual_value,50                    verify_value,51                    ('"%s" value "%s" doesn\'t match pattern "%s")')52                    % (key, actual_value, verify_value),53                )54        if "contains" in verify_dict:55            verify = verify_dict["contains"]56            for key in verify:57                contains_array = verify[key]58                actual_value = actual[key]59                self.assertIsInstance(contains_array, list)60                for verify_value in contains_array:61                    self.assertIn(verify_value, actual_value)62        if "missing" in verify_dict:63            missing = verify_dict["missing"]64            for key in missing:65                self.assertNotIn(66                    key, actual, 'key "%s" is not expected in %s' % (key, actual)67                )68        isReadOnly = verify_dict.get("readOnly", False)69        attributes = actual.get("presentationHint", {}).get("attributes", [])70        self.assertEqual(71            isReadOnly, "readOnly" in attributes, "%s %s" % (verify_dict, actual)72        )73        hasVariablesReference = "variablesReference" in actual74        varRef = None75        if hasVariablesReference:76            # Remember variable references in case we want to test further77            # by using the evaluate name.78            varRef = actual["variablesReference"]79            if varRef != 0 and varref_dict is not None:80                if expression is None:81                    evaluateName = actual["evaluateName"]82                else:83                    evaluateName = expression84                varref_dict[evaluateName] = varRef85        if (86            "hasVariablesReference" in verify_dict87            and verify_dict["hasVariablesReference"]88        ):89            self.assertTrue(hasVariablesReference, "verify variable reference")90        if "children" in verify_dict:91            self.assertTrue(92                hasVariablesReference and varRef is not None and varRef != 0,93                ("children verify values specified for " "variable without children"),94            )95 96            response = self.dap_server.request_variables(varRef)97            self.verify_variables(98                verify_dict["children"], response["body"]["variables"], varref_dict99            )100 101    def verify_variables(self, verify_dict, variables, varref_dict=None):102        for variable in variables:103            name = variable["name"]104            if not name.startswith("std::"):105                self.assertIn(106                    name, verify_dict, 'variable "%s" in verify dictionary' % (name)107                )108                self.verify_values(verify_dict[name], variable, varref_dict)109 110    def darwin_dwarf_missing_obj(self, initCommands):111        self.build(debug_info="dwarf")112        program = self.getBuildArtifact("a.out")113        main_obj = self.getBuildArtifact("main.o")114        self.assertTrue(os.path.exists(main_obj))115        # Delete the main.o file that contains the debug info so we force an116        # error when we run to main and try to get variables117        os.unlink(main_obj)118 119        self.create_debug_adapter()120        self.assertTrue(os.path.exists(program), "executable must exist")121 122        self.launch(program, initCommands=initCommands)123 124        functions = ["main"]125        breakpoint_ids = self.set_function_breakpoints(functions)126        self.assertEqual(len(breakpoint_ids), len(functions), "expect one breakpoint")127        self.continue_to_breakpoints(breakpoint_ids)128 129        locals = self.dap_server.get_local_variables()130 131        verify_locals = {132            "<error>": {133                "equals": {"type": "const char *"},134                "contains": {135                    "value": [136                        "debug map object file ",137                        'main.o" containing debug info does not exist, debug info will not be loaded',138                    ]139                },140            },141        }142        varref_dict = {}143        self.verify_variables(verify_locals, locals, varref_dict)144 145    def do_test_scopes_variables_setVariable_evaluate(146        self, enableAutoVariableSummaries: bool147    ):148        """149        Tests the "scopes", "variables", "setVariable", and "evaluate" packets.150        """151        program = self.getBuildArtifact("a.out")152        self.build_and_launch(153            program, enableAutoVariableSummaries=enableAutoVariableSummaries154        )155        source = "main.cpp"156        breakpoint1_line = line_number(source, "// breakpoint 1")157        lines = [breakpoint1_line]158        # Set breakpoint in the thread function so we can step the threads159        breakpoint_ids = self.set_source_breakpoints(source, lines)160        self.assertEqual(161            len(breakpoint_ids), len(lines), "expect correct number of breakpoints"162        )163        self.continue_to_breakpoints(breakpoint_ids)164        locals = self.dap_server.get_local_variables()165        globals = self.dap_server.get_global_variables()166        buffer_children = make_buffer_verify_dict(0, 16)167        verify_locals = {168            "argc": {169                "equals": {170                    "type": "int",171                    "value": "1",172                },173            },174            "argv": {175                "equals": {"type": "const char **"},176                "startswith": {"value": "0x"},177                "hasVariablesReference": True,178            },179            "pt": {180                "equals": {181                    "type": "PointType",182                },183                "hasVariablesReference": True,184                "children": {185                    "x": {"equals": {"type": "int", "value": "11"}},186                    "y": {"equals": {"type": "int", "value": "22"}},187                    "buffer": {"children": buffer_children, "readOnly": True},188                },189                "readOnly": True,190            },191            "x": {"equals": {"type": "int"}},192        }193 194        verify_globals = {195            "s_local": {"equals": {"type": "float", "value": "2.25"}},196        }197        s_global = {"equals": {"type": "int", "value": "234"}}198        g_global = {"equals": {"type": "int", "value": "123"}}199        if lldbplatformutil.getHostPlatform() == "windows":200            verify_globals["::s_global"] = s_global201            verify_globals["g_global"] = g_global202        else:203            verify_globals["s_global"] = s_global204            verify_globals["::g_global"] = g_global205 206        varref_dict = {}207        self.verify_variables(verify_locals, locals, varref_dict)208        self.verify_variables(verify_globals, globals, varref_dict)209        # pprint.PrettyPrinter(indent=4).pprint(varref_dict)210        # We need to test the functionality of the "variables" request as it211        # has optional parameters like "start" and "count" to limit the number212        # of variables that are fetched213        varRef = varref_dict["pt.buffer"]214        response = self.dap_server.request_variables(varRef)215        self.verify_variables(buffer_children, response["body"]["variables"])216        # Verify setting start=0 in the arguments still gets all children217        response = self.dap_server.request_variables(varRef, start=0)218        self.verify_variables(buffer_children, response["body"]["variables"])219        # Verify setting count=0 in the arguments still gets all children.220        # If count is zero, it means to get all children.221        response = self.dap_server.request_variables(varRef, count=0)222        self.verify_variables(buffer_children, response["body"]["variables"])223        # Verify setting count to a value that is too large in the arguments224        # still gets all children, and no more225        response = self.dap_server.request_variables(varRef, count=1000)226        self.verify_variables(buffer_children, response["body"]["variables"])227        # Verify setting the start index and count gets only the children we228        # want229        response = self.dap_server.request_variables(varRef, start=5, count=5)230        self.verify_variables(231            make_buffer_verify_dict(5, 5), response["body"]["variables"]232        )233        # Verify setting the start index to a value that is out of range234        # results in an empty list235        response = self.dap_server.request_variables(varRef, start=32, count=1)236        self.assertEqual(237            len(response["body"]["variables"]),238            0,239            "verify we get no variable back for invalid start",240        )241 242        # Test evaluate243        expressions = {244            "pt.x": {245                "equals": {"result": "11", "type": "int"},246                "hasVariablesReference": False,247            },248            "pt.buffer[2]": {249                "equals": {"result": "2", "type": "int"},250                "hasVariablesReference": False,251            },252            "pt": {253                "equals": {"type": "PointType"},254                "startswith": {255                    "result": (256                        "{x:11, y:22, buffer:{...}}"257                        if enableAutoVariableSummaries258                        else "PointType @ 0x"259                    )260                },261                "hasVariablesReference": True,262            },263            "pt.buffer": {264                "equals": {"type": "int[16]"},265                "startswith": {266                    "result": (267                        "{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ...}"268                        if enableAutoVariableSummaries269                        else "int[16] @ 0x"270                    )271                },272                "hasVariablesReference": True,273            },274            "argv": {275                "equals": {"type": "const char **"},276                "startswith": {"result": "0x"},277                "hasVariablesReference": True,278            },279            "argv[0]": {280                "equals": {"type": "const char *"},281                "startswith": {"result": "0x"},282                "hasVariablesReference": True,283            },284            "2+3": {285                "equals": {"result": "5", "type": "int"},286                "hasVariablesReference": False,287            },288        }289        for expression in expressions:290            response = self.dap_server.request_evaluate(expression)291            self.verify_values(expressions[expression], response["body"])292 293        # Test setting variables294        self.set_local("argc", 123)295        argc = self.get_local_as_int("argc")296        self.assertEqual(argc, 123, "verify argc was set to 123 (123 != %i)" % (argc))297 298        self.set_local("argv", 0x1234)299        argv = self.get_local_as_int("argv")300        self.assertEqual(301            argv, 0x1234, "verify argv was set to 0x1234 (0x1234 != %#x)" % (argv)302        )303 304        # Set a variable value whose name is synthetic, like a variable index305        # and verify the value by reading it306        variable_value = 100307        response = self.set_variable(varRef, "[0]", variable_value)308        # Verify dap sent the correct response309        verify_response = {310            "type": "int",311            "value": str(variable_value),312        }313        for key, value in verify_response.items():314            self.assertEqual(value, response["body"][key])315 316        response = self.dap_server.request_variables(varRef, start=0, count=1)317        self.verify_variables(318            make_buffer_verify_dict(0, 1, variable_value), response["body"]["variables"]319        )320 321        # Set a variable value whose name is a real child value, like "pt.x"322        # and verify the value by reading it323        varRef = varref_dict["pt"]324        self.set_variable(varRef, "x", 111)325        response = self.dap_server.request_variables(varRef, start=0, count=1)326        value = response["body"]["variables"][0]["value"]327        self.assertEqual(328            value, "111", "verify pt.x got set to 111 (111 != %s)" % (value)329        )330 331        # We check shadowed variables and that a new get_local_variables request332        # gets the right data333        breakpoint2_line = line_number(source, "// breakpoint 2")334        lines = [breakpoint2_line]335        breakpoint_ids = self.set_source_breakpoints(source, lines)336        self.assertEqual(337            len(breakpoint_ids), len(lines), "expect correct number of breakpoints"338        )339        self.continue_to_breakpoints(breakpoint_ids)340 341        verify_locals["argc"]["equals"]["value"] = "123"342        verify_locals["pt"]["children"]["x"]["equals"]["value"] = "111"343        verify_locals["x @ main.cpp:19"] = {"equals": {"type": "int", "value": "89"}}344        verify_locals["x @ main.cpp:21"] = {"equals": {"type": "int", "value": "42"}}345        verify_locals["x @ main.cpp:23"] = {"equals": {"type": "int", "value": "72"}}346 347        self.verify_variables(verify_locals, self.dap_server.get_local_variables())348 349        # Now we verify that we correctly change the name of a variable with and without differentiator suffix350        self.assertFalse(self.set_local("x2", 9)["success"])351        self.assertFalse(self.set_local("x @ main.cpp:0", 9)["success"])352 353        self.assertTrue(self.set_local("x @ main.cpp:19", 19)["success"])354        self.assertTrue(self.set_local("x @ main.cpp:21", 21)["success"])355        self.assertTrue(self.set_local("x @ main.cpp:23", 23)["success"])356 357        # The following should have no effect358        self.assertFalse(self.set_local("x @ main.cpp:23", "invalid")["success"])359 360        verify_locals["x @ main.cpp:19"]["equals"]["value"] = "19"361        verify_locals["x @ main.cpp:21"]["equals"]["value"] = "21"362        verify_locals["x @ main.cpp:23"]["equals"]["value"] = "23"363 364        self.verify_variables(verify_locals, self.dap_server.get_local_variables())365 366        # The plain x variable shold refer to the innermost x367        self.assertTrue(self.set_local("x", 22)["success"])368        verify_locals["x @ main.cpp:23"]["equals"]["value"] = "22"369 370        self.verify_variables(verify_locals, self.dap_server.get_local_variables())371 372        # In breakpoint 3, there should be no shadowed variables373        breakpoint3_line = line_number(source, "// breakpoint 3")374        lines = [breakpoint3_line]375        breakpoint_ids = self.set_source_breakpoints(source, lines)376        self.assertEqual(377            len(breakpoint_ids), len(lines), "expect correct number of breakpoints"378        )379        self.continue_to_breakpoints(breakpoint_ids)380 381        locals = self.dap_server.get_local_variables()382        names = [var["name"] for var in locals]383        # The first shadowed x shouldn't have a suffix anymore384        verify_locals["x"] = {"equals": {"type": "int", "value": "19"}}385        self.assertNotIn("x @ main.cpp:19", names)386        self.assertNotIn("x @ main.cpp:21", names)387        self.assertNotIn("x @ main.cpp:23", names)388 389        self.verify_variables(verify_locals, locals)390 391    @skipIfWindows392    def test_scopes_variables_setVariable_evaluate(self):393        self.do_test_scopes_variables_setVariable_evaluate(394            enableAutoVariableSummaries=False395        )396 397    @skipIfWindows398    def test_scopes_variables_setVariable_evaluate_with_descriptive_summaries(self):399        self.do_test_scopes_variables_setVariable_evaluate(400            enableAutoVariableSummaries=True401        )402 403    @skipIfWindows404    def do_test_scopes_and_evaluate_expansion(self, enableAutoVariableSummaries: bool):405        """406        Tests the evaluated expression expands successfully after "scopes" packets407        and permanent expressions persist.408        """409        program = self.getBuildArtifact("a.out")410        self.build_and_launch(411            program, enableAutoVariableSummaries=enableAutoVariableSummaries412        )413        source = "main.cpp"414        breakpoint1_line = line_number(source, "// breakpoint 1")415        lines = [breakpoint1_line]416        # Set breakpoint in the thread function so we can step the threads417        breakpoint_ids = self.set_source_breakpoints(source, lines)418        self.assertEqual(419            len(breakpoint_ids), len(lines), "expect correct number of breakpoints"420        )421        self.continue_to_breakpoints(breakpoint_ids)422 423        # Verify locals424        locals = self.dap_server.get_local_variables()425        buffer_children = make_buffer_verify_dict(0, 32)426        verify_locals = {427            "argc": {428                "equals": {"type": "int", "value": "1"},429                "missing": ["indexedVariables"],430            },431            "argv": {432                "equals": {"type": "const char **"},433                "startswith": {"value": "0x"},434                "hasVariablesReference": True,435                "missing": ["indexedVariables"],436            },437            "pt": {438                "equals": {"type": "PointType"},439                "hasVariablesReference": True,440                "missing": ["indexedVariables"],441                "children": {442                    "x": {443                        "equals": {"type": "int", "value": "11"},444                        "missing": ["indexedVariables"],445                    },446                    "y": {447                        "equals": {"type": "int", "value": "22"},448                        "missing": ["indexedVariables"],449                    },450                    "buffer": {451                        "children": buffer_children,452                        "equals": {"indexedVariables": 16},453                        "readOnly": True,454                    },455                },456                "readOnly": True,457            },458            "x": {459                "equals": {"type": "int"},460                "missing": ["indexedVariables"],461            },462        }463        self.verify_variables(verify_locals, locals)464 465        # Evaluate expandable expression twice: once permanent (from repl)466        # the other temporary (from other UI).467        expandable_expression = {468            "name": "pt",469            "context": {470                "repl": {471                    "equals": {"type": "PointType"},472                    "equals": {473                        "result": """(PointType) $0 = {474  x = 11475  y = 22476  buffer = {477    [0] = 0478    [1] = 1479    [2] = 2480    [3] = 3481    [4] = 4482    [5] = 5483    [6] = 6484    [7] = 7485    [8] = 8486    [9] = 9487    [10] = 10488    [11] = 11489    [12] = 12490    [13] = 13491    [14] = 14492    [15] = 15493  }494}"""495                    },496                    "missing": ["indexedVariables"],497                    "hasVariablesReference": True,498                },499                "hover": {500                    "equals": {"type": "PointType"},501                    "startswith": {502                        "result": (503                            "{x:11, y:22, buffer:{...}}"504                            if enableAutoVariableSummaries505                            else "PointType @ 0x"506                        )507                    },508                    "missing": ["indexedVariables"],509                    "hasVariablesReference": True,510                },511                "watch": {512                    "equals": {"type": "PointType"},513                    "startswith": {514                        "result": (515                            "{x:11, y:22, buffer:{...}}"516                            if enableAutoVariableSummaries517                            else "PointType @ 0x"518                        )519                    },520                    "missing": ["indexedVariables"],521                    "hasVariablesReference": True,522                },523                "variables": {524                    "equals": {"type": "PointType"},525                    "startswith": {526                        "result": (527                            "{x:11, y:22, buffer:{...}}"528                            if enableAutoVariableSummaries529                            else "PointType @ 0x"530                        )531                    },532                    "missing": ["indexedVariables"],533                    "hasVariablesReference": True,534                },535            },536            "children": {537                "x": {"equals": {"type": "int", "value": "11"}},538                "y": {"equals": {"type": "int", "value": "22"}},539                "buffer": {"children": buffer_children, "readOnly": True},540            },541        }542 543        # Evaluate from known contexts.544        expr_varref_dict = {}545        for context, verify_dict in expandable_expression["context"].items():546            response = self.dap_server.request_evaluate(547                expandable_expression["name"],548                frameIndex=0,549                threadId=None,550                context=context,551            )552            self.verify_values(553                verify_dict,554                response["body"],555                expr_varref_dict,556                expandable_expression["name"],557            )558 559        # Evaluate locals again.560        locals = self.dap_server.get_local_variables()561        self.verify_variables(verify_locals, locals)562 563        # Verify the evaluated expressions before second locals evaluation564        # can be expanded.565        var_ref = expr_varref_dict[expandable_expression["name"]]566        response = self.dap_server.request_variables(var_ref)567        self.verify_variables(568            expandable_expression["children"], response["body"]["variables"]569        )570 571        # Continue to breakpoint 3, permanent variable should still exist572        # after resume.573        breakpoint3_line = line_number(source, "// breakpoint 3")574        lines = [breakpoint3_line]575        breakpoint_ids = self.set_source_breakpoints(source, lines)576        self.assertEqual(577            len(breakpoint_ids), len(lines), "expect correct number of breakpoints"578        )579        self.continue_to_breakpoints(breakpoint_ids)580 581        var_ref = expr_varref_dict[expandable_expression["name"]]582        response = self.dap_server.request_variables(var_ref)583        self.verify_variables(584            expandable_expression["children"], response["body"]["variables"]585        )586 587        # Test that frame scopes have corresponding presentation hints.588        frame_id = self.dap_server.get_stackFrame()["id"]589        scopes = self.dap_server.request_scopes(frame_id)["body"]["scopes"]590 591        scope_names = [scope["name"] for scope in scopes]592        self.assertIn("Locals", scope_names)593        self.assertIn("Registers", scope_names)594 595        for scope in scopes:596            if scope["name"] == "Locals":597                self.assertEqual(scope.get("presentationHint"), "locals")598            if scope["name"] == "Registers":599                self.assertEqual(scope.get("presentationHint"), "registers")600 601    def test_scopes_and_evaluate_expansion(self):602        self.do_test_scopes_and_evaluate_expansion(enableAutoVariableSummaries=False)603 604    def test_scopes_and_evaluate_expansion_with_descriptive_summaries(self):605        self.do_test_scopes_and_evaluate_expansion(enableAutoVariableSummaries=True)606 607    def do_test_indexedVariables(self, enableSyntheticChildDebugging: bool):608        """609        Tests that arrays and lldb.SBValue objects that have synthetic child610        providers have "indexedVariables" key/value pairs. This helps the IDE611        not to fetch too many children all at once.612        """613        program = self.getBuildArtifact("a.out")614        self.build_and_launch(615            program, enableSyntheticChildDebugging=enableSyntheticChildDebugging616        )617        source = "main.cpp"618        breakpoint1_line = line_number(source, "// breakpoint 4")619        lines = [breakpoint1_line]620        # Set breakpoint in the thread function so we can step the threads621        breakpoint_ids = self.set_source_breakpoints(source, lines)622        self.assertEqual(623            len(breakpoint_ids), len(lines), "expect correct number of breakpoints"624        )625        self.continue_to_breakpoints(breakpoint_ids)626 627        # Verify locals628        locals = self.dap_server.get_local_variables()629        # The vector variables might have one additional entry from the fake630        # "[raw]" child.631        raw_child_count = 1 if enableSyntheticChildDebugging else 0632        verify_locals = {633            "small_array": {"equals": {"indexedVariables": 5}, "readOnly": True},634            "large_array": {"equals": {"indexedVariables": 200}, "readOnly": True},635            "small_vector": {636                "equals": {"indexedVariables": 5 + raw_child_count},637                "readOnly": True,638            },639            "large_vector": {640                "equals": {"indexedVariables": 200 + raw_child_count},641                "readOnly": True,642            },643            "pt": {"missing": ["indexedVariables"], "readOnly": True},644        }645        self.verify_variables(verify_locals, locals)646 647        # We also verify that we produce a "[raw]" fake child with the real648        # SBValue for the synthetic type.649        verify_children = {650            "[0]": {"equals": {"type": "int", "value": "0"}},651            "[1]": {"equals": {"type": "int", "value": "0"}},652            "[2]": {"equals": {"type": "int", "value": "0"}},653            "[3]": {"equals": {"type": "int", "value": "0"}},654            "[4]": {"equals": {"type": "int", "value": "0"}},655        }656        if enableSyntheticChildDebugging:657            verify_children["[raw]"] = {658                "contains": {"type": ["vector"]},659                "readOnly": True,660            }661 662        children = self.dap_server.request_variables(locals[2]["variablesReference"])[663            "body"664        ]["variables"]665        self.verify_variables(verify_children, children)666 667    @skipIfWindows668    def test_return_variables(self):669        """670        Test the stepping out of a function with return value show the variable correctly.671        """672        program = self.getBuildArtifact("a.out")673        self.build_and_launch(program)674 675        return_name = "(Return Value)"676        verify_locals = {677            return_name: {"equals": {"type": "int", "value": "300"}},678            "argc": {},679            "argv": {},680            "pt": {"readOnly": True},681            "x": {},682            "return_result": {"equals": {"type": "int"}},683        }684 685        function_name = "test_return_variable"686        breakpoint_ids = self.set_function_breakpoints([function_name])687 688        self.assertEqual(len(breakpoint_ids), 1)689        self.continue_to_breakpoints(breakpoint_ids)690 691        threads = self.dap_server.get_threads()692        for thread in threads:693            if thread.get("reason") == "breakpoint":694                thread_id = thread["id"]695 696                self.stepOut(threadId=thread_id)697 698                local_variables = self.dap_server.get_local_variables()699                varref_dict = {}700 701                # `verify_variable` function only checks if the local variables702                # are in the `verify_dict` passed  this will cause this test to pass703                # even if there is no return value.704                local_variable_names = [705                    variable["name"] for variable in local_variables706                ]707                self.assertIn(708                    return_name,709                    local_variable_names,710                    "return variable is not in local variables",711                )712 713                self.verify_variables(verify_locals, local_variables, varref_dict)714                break715 716        self.assertFalse(self.set_local("(Return Value)", 20)["success"])717 718    @skipIfWindows719    def test_indexedVariables(self):720        self.do_test_indexedVariables(enableSyntheticChildDebugging=False)721 722    @skipIfWindows723    def test_indexedVariables_with_raw_child_for_synthetics(self):724        self.do_test_indexedVariables(enableSyntheticChildDebugging=True)725 726    @skipIfWindows727    @skipIfAsan  # FIXME this fails with a non-asan issue on green dragon.728    def test_registers(self):729        """730        Test that registers whose byte size is the size of a pointer on731        the current system get formatted as lldb::eFormatAddressInfo. This732        will show the pointer value followed by a description of the address733        itself. To test this we attempt to find the PC value in the general734        purpose registers, and since we will be stopped in main.cpp, verify735        that the value for the PC starts with a pointer and is followed by736        a description that contains main.cpp.737        """738        program = self.getBuildArtifact("a.out")739        self.build_and_launch(program)740        source = "main.cpp"741        breakpoint1_line = line_number(source, "// breakpoint 1")742        lines = [breakpoint1_line]743        # Set breakpoint in the thread function so we can step the threads744        breakpoint_ids = self.set_source_breakpoints(source, lines)745        self.assertEqual(746            len(breakpoint_ids), len(lines), "expect correct number of breakpoints"747        )748        self.continue_to_breakpoints(breakpoint_ids)749 750        pc_name = None751        arch = self.getArchitecture()752        if arch == "x86_64":753            pc_name = "rip"754        elif arch == "x86":755            pc_name = "rip"756        elif arch.startswith("arm"):757            pc_name = "pc"758 759        if pc_name is None:760            return761        # Verify locals762        reg_sets = self.dap_server.get_registers()763        for reg_set in reg_sets:764            if reg_set["name"] == "General Purpose Registers":765                varRef = reg_set["variablesReference"]766                regs = self.dap_server.request_variables(varRef)["body"]["variables"]767                for reg in regs:768                    if reg["name"] == pc_name:769                        value = reg["value"]770                        self.assertTrue(value.startswith("0x"))771                        self.assertIn("a.out`main + ", value)772                        self.assertIn("at main.cpp:", value)773 774    @no_debug_info_test775    @skipUnlessDarwin776    def test_darwin_dwarf_missing_obj(self):777        """778        Test that if we build a binary with DWARF in .o files and we remove779        the .o file for main.cpp, that we get a variable named "<error>"780        whose value matches the appriopriate error. Errors when getting781        variables are returned in the LLDB API when the user should be782        notified of issues that can easily be solved by rebuilding or783        changing compiler options and are designed to give better feedback784        to the user.785        """786        self.darwin_dwarf_missing_obj(None)787 788    @no_debug_info_test789    @skipUnlessDarwin790    def test_darwin_dwarf_missing_obj_with_symbol_ondemand_enabled(self):791        """792        Test that if we build a binary with DWARF in .o files and we remove793        the .o file for main.cpp, that we get a variable named "<error>"794        whose value matches the appriopriate error. Test with symbol_ondemand_enabled.795        """796        initCommands = ["settings set symbols.load-on-demand true"]797        self.darwin_dwarf_missing_obj(initCommands)798 799    @no_debug_info_test800    @skipIfWindows801    def test_value_format(self):802        """803        Test that toggle variables value format between decimal and hexical works.804        """805        program = self.getBuildArtifact("a.out")806        self.build_and_launch(program)807        source = "main.cpp"808        breakpoint1_line = line_number(source, "// breakpoint 1")809        lines = [breakpoint1_line]810 811        breakpoint_ids = self.set_source_breakpoints(source, lines)812        self.assertEqual(813            len(breakpoint_ids), len(lines), "expect correct number of breakpoints"814        )815        self.continue_to_breakpoints(breakpoint_ids)816 817        # Verify locals value format decimal818        is_hex = False819        var_pt_x = self.dap_server.get_local_variable_child("pt", "x", is_hex=is_hex)820        self.assertEqual(var_pt_x["value"], "11")821        var_pt_y = self.dap_server.get_local_variable_child("pt", "y", is_hex=is_hex)822        self.assertEqual(var_pt_y["value"], "22")823 824        # Verify locals value format hexical825        is_hex = True826        var_pt_x = self.dap_server.get_local_variable_child("pt", "x", is_hex=is_hex)827        self.assertEqual(var_pt_x["value"], "0x0000000b")828        var_pt_y = self.dap_server.get_local_variable_child("pt", "y", is_hex=is_hex)829        self.assertEqual(var_pt_y["value"], "0x00000016")830 831        # Toggle and verify locals value format decimal again832        is_hex = False833        var_pt_x = self.dap_server.get_local_variable_child("pt", "x", is_hex=is_hex)834        self.assertEqual(var_pt_x["value"], "11")835        var_pt_y = self.dap_server.get_local_variable_child("pt", "y", is_hex=is_hex)836        self.assertEqual(var_pt_y["value"], "22")837