brintos

brintos / llvm-project-archived public Read only

0
0
Text · 14.5 KiB · 1837166 Raw
364 lines · python
1"""2Test completing types using information from other shared libraries.3"""4 5import os6import lldb7from lldbsuite.test.decorators import *8from lldbsuite.test.lldbtest import *9from lldbsuite.test import lldbutil10 11 12class LimitDebugInfoTestCase(TestBase):13    def _check_type(self, target, name):14        exe = target.FindModule(lldb.SBFileSpec("a.out"))15        type_ = exe.FindFirstType(name)16        self.trace("type_: %s" % type_)17        self.assertTrue(type_)18        self.assertTrue(type_.IsTypeComplete())19        base = type_.GetDirectBaseClassAtIndex(0).GetType()20        self.trace("base:%s" % base)21        self.assertTrue(base)22        self.assertEqual(base.GetNumberOfFields(), 0)23        self.assertFalse(base.IsTypeComplete())24 25    def _check_debug_info_is_limited(self, target):26        # Without other shared libraries we should only see the member declared27        # in the derived class. This serves as a sanity check that we are truly28        # building with limited debug info.29        self._check_type(target, "InheritsFromOne")30        self._check_type(target, "InheritsFromTwo")31 32        # Check that the statistics show that we had incomplete debug info.33        stats = self.get_stats()34        # Find the a.out module info in the stats and verify it has the35        # "debugInfoHadIncompleteTypes" key value pair set to True36        exe_module_found = False37        for module in stats["modules"]:38            if module["path"].endswith("a.out"):39                self.assertTrue(module["debugInfoHadIncompleteTypes"])40                exe_module_found = True41                break42        self.assertTrue(exe_module_found)43        # Verify that "totalModuleCountWithIncompleteTypes" at the top level44        # is greater than zero which shows we had incomplete debug info in a45        # module46        self.assertGreater(stats["totalModuleCountWithIncompleteTypes"], 0)47 48    def _check_incomplete_frame_variable_output(self):49        # Check that the display of the "frame variable" output identifies the50        # incomplete types. Currently the expression parser will find the real51        # definition for a type when running an expression for any forcefully52        # completed types, but "frame variable" won't. I hope to fix this with53        # a follow up patch, but if we don't find the actual definition we54        # should clearly show this to the user by showing which types were55        # incomplete. So this will test verifies the expected output for such56        # types. We also need to verify the standard "frame variable" output57        # which will inline all of the members on one line, versus the full58        # output from "frame variable --raw" and a few other options.59        # self.expect("frame variable two_as_member", error=True,60        #     substrs=["no member named 'one' in 'InheritsFromOne'"])61 62        command_expect_pairs = [63            # Test standard "frame variable" output for types to make sure64            # "<incomplete type>" shows up where we expect it to65            [66                "var two_as_member",67                [68                    "(TwoAsMember) ::two_as_member = (two = <incomplete type>, member = 47)"69                ],70            ],71            [72                "var inherits_from_one",73                [74                    "(InheritsFromOne) ::inherits_from_one = (One = <incomplete type>, member = 47)"75                ],76            ],77            [78                "var inherits_from_two",79                [80                    "(InheritsFromTwo) ::inherits_from_two = (Two = <incomplete type>, member = 47)"81                ],82            ],83            [84                "var one_as_member",85                [86                    "(OneAsMember) ::one_as_member = (one = <incomplete type>, member = 47)"87                ],88            ],89            [90                "var two_as_member",91                [92                    "(TwoAsMember) ::two_as_member = (two = <incomplete type>, member = 47)"93                ],94            ],95            [96                "var array_of_one",97                [98                    "(array::One[3]) ::array_of_one = ([0] = <incomplete type>, [1] = <incomplete type>, [2] = <incomplete type>)"99                ],100            ],101            [102                "var array_of_two",103                [104                    "(array::Two[3]) ::array_of_two = ([0] = <incomplete type>, [1] = <incomplete type>, [2] = <incomplete type>)"105                ],106            ],107            [108                "var shadowed_one",109                [110                    "(ShadowedOne) ::shadowed_one = (func_shadow::One = <incomplete type>, member = 47)"111                ],112            ],113            # Now test "frame variable --show-types output" which has multi-line114            # output and should not always show classes that were forcefully115            # completed to the user to let them know they have a type that should116            # have been complete but wasn't.117            [118                "var --show-types inherits_from_one",119                [120                    "(InheritsFromOne) ::inherits_from_one = {",121                    "  (One) One = <incomplete type> {}",122                    "  (int) member = 47",123                    "}",124                ],125            ],126            [127                "var --show-types inherits_from_two",128                [129                    "(InheritsFromTwo) ::inherits_from_two = {",130                    "  (Two) Two = <incomplete type> {}",131                    "  (int) member = 47",132                    "}",133                ],134            ],135            [136                "var  --show-types one_as_member",137                [138                    "(OneAsMember) ::one_as_member = {",139                    "  (member::One) one = <incomplete type> {}",140                    "  (int) member = 47",141                    "}",142                ],143            ],144            [145                "var  --show-types two_as_member",146                [147                    "(TwoAsMember) ::two_as_member = {",148                    "  (member::Two) two = <incomplete type> {}",149                    "  (int) member = 47",150                    "}",151                ],152            ],153            [154                "var  --show-types array_of_one",155                [156                    "(array::One[3]) ::array_of_one = {",157                    "  (array::One) [0] = <incomplete type> {}",158                    "  (array::One) [1] = <incomplete type> {}",159                    "  (array::One) [2] = <incomplete type> {}",160                    "}",161                ],162            ],163            [164                "var  --show-types array_of_two",165                [166                    "(array::Two[3]) ::array_of_two = {",167                    "  (array::Two) [0] = <incomplete type> {}",168                    "  (array::Two) [1] = <incomplete type> {}",169                    "  (array::Two) [2] = <incomplete type> {}",170                    "}",171                ],172            ],173            [174                "var  --show-types shadowed_one",175                [176                    "(ShadowedOne) ::shadowed_one = {",177                    "  (func_shadow::One) func_shadow::One = <incomplete type> {}",178                    "  (int) member = 47",179                    "}",180                ],181            ],182        ]183        for command, expect_items in command_expect_pairs:184            self.expect(command, substrs=expect_items)185 186    @skipIf(bugnumber="pr46284", debug_info="gmodules")187    @skipIfWindows  # Clang emits type info even with -flimit-debug-info188    # Requires DW_CC_pass_by_* attributes from Clang 7 to correctly call189    # by-value functions.190    @skipIf(compiler="clang", compiler_version=["<", "7.0"])191    def test_one_and_two_debug(self):192        self.build()193        target = self.dbg.CreateTarget(self.getBuildArtifact("a.out"))194 195        self._check_debug_info_is_limited(target)196 197        lldbutil.run_to_name_breakpoint(self, "main", extra_images=["one", "two"])198 199        # But when other shared libraries are loaded, we should be able to see200        # all members.201        self.expect_expr("inherits_from_one.member", result_value="47")202        self.expect_expr("inherits_from_one.one", result_value="142")203        self.expect_expr("inherits_from_two.member", result_value="47")204        self.expect_expr("inherits_from_two.one", result_value="142")205        self.expect_expr("inherits_from_two.two", result_value="242")206 207        self.expect_expr("one_as_member.member", result_value="47")208        self.expect_expr("one_as_member.one.member", result_value="147")209        self.expect_expr("two_as_member.member", result_value="47")210        self.expect_expr("two_as_member.two.one.member", result_value="147")211        self.expect_expr("two_as_member.two.member", result_value="247")212 213        self.expect_expr("array_of_one[2].member", result_value="174")214        self.expect_expr("array_of_two[2].one[2].member", result_value="174")215        self.expect_expr("array_of_two[2].member", result_value="274")216 217        self.expect_expr("get_one().member", result_value="124")218        self.expect_expr("get_two().one().member", result_value="124")219        self.expect_expr("get_two().member", result_value="224")220 221        self.expect_expr("shadowed_one.member", result_value="47")222        self.expect_expr("shadowed_one.one", result_value="142")223 224        self._check_incomplete_frame_variable_output()225 226    @skipIf(bugnumber="pr46284", debug_info="gmodules")227    @skipIfWindows  # Clang emits type info even with -flimit-debug-info228    # Requires DW_CC_pass_by_* attributes from Clang 7 to correctly call229    # by-value functions.230    @skipIf(compiler="clang", compiler_version=["<", "7.0"])231    def test_two_debug(self):232        self.build(dictionary=dict(STRIP_ONE="1"))233        target = self.dbg.CreateTarget(self.getBuildArtifact("a.out"))234 235        self._check_debug_info_is_limited(target)236 237        lldbutil.run_to_name_breakpoint(self, "main", extra_images=["one", "two"])238 239        # This time, we should only see the members from the second library.240        self.expect_expr("inherits_from_one.member", result_value="47")241        self.expect(242            "expr inherits_from_one.one",243            error=True,244            substrs=["no member named 'one' in 'InheritsFromOne'"],245        )246        self.expect_expr("inherits_from_two.member", result_value="47")247        self.expect(248            "expr inherits_from_two.one",249            error=True,250            substrs=["no member named 'one' in 'InheritsFromTwo'"],251        )252        self.expect_expr("inherits_from_two.two", result_value="242")253 254        self.expect_expr("one_as_member.member", result_value="47")255        self.expect(256            "expr one_as_member.one.member",257            error=True,258            substrs=["no member named 'member' in 'member::One'"],259        )260        self.expect_expr("two_as_member.member", result_value="47")261        self.expect(262            "expr two_as_member.two.one.member",263            error=True,264            substrs=["no member named 'member' in 'member::One'"],265        )266        self.expect_expr("two_as_member.two.member", result_value="247")267 268        self.expect(269            "expr array_of_one[2].member",270            error=True,271            substrs=["no member named 'member' in 'array::One'"],272        )273        self.expect(274            "expr array_of_two[2].one[2].member",275            error=True,276            substrs=["no member named 'member' in 'array::One'"],277        )278        self.expect_expr("array_of_two[2].member", result_value="274")279 280        self.expect(281            "expr get_one().member",282            error=True,283            substrs=["calling 'get_one' with incomplete return type 'result::One'"],284        )285        self.expect(286            "expr get_two().one().member",287            error=True,288            substrs=["calling 'one' with incomplete return type 'result::One'"],289        )290        self.expect_expr("get_two().member", result_value="224")291 292        self._check_incomplete_frame_variable_output()293 294    @skipIf(bugnumber="pr46284", debug_info="gmodules")295    @skipIfWindows  # Clang emits type info even with -flimit-debug-info296    # Requires DW_CC_pass_by_* attributes from Clang 7 to correctly call297    # by-value functions.298    @skipIf(compiler="clang", compiler_version=["<", "7.0"])299    def test_one_debug(self):300        self.build(dictionary=dict(STRIP_TWO="1"))301        target = self.dbg.CreateTarget(self.getBuildArtifact("a.out"))302 303        self._check_debug_info_is_limited(target)304 305        lldbutil.run_to_name_breakpoint(self, "main", extra_images=["one", "two"])306 307        # In this case we should only see the members from the second library.308        # Note that we cannot see inherits_from_two.one because without debug309        # info for "Two", we cannot determine that it in fact inherits from310        # "One".311        self.expect_expr("inherits_from_one.member", result_value="47")312        self.expect_expr("inherits_from_one.one", result_value="142")313        self.expect_expr("inherits_from_two.member", result_value="47")314        self.expect(315            "expr inherits_from_two.one",316            error=True,317            substrs=["no member named 'one' in 'InheritsFromTwo'"],318        )319        self.expect(320            "expr inherits_from_two.two",321            error=True,322            substrs=["no member named 'two' in 'InheritsFromTwo'"],323        )324 325        self.expect_expr("one_as_member.member", result_value="47")326        self.expect_expr("one_as_member.one.member", result_value="147")327        self.expect_expr("two_as_member.member", result_value="47")328        self.expect(329            "expr two_as_member.two.one.member",330            error=True,331            substrs=["no member named 'one' in 'member::Two'"],332        )333        self.expect(334            "expr two_as_member.two.member",335            error=True,336            substrs=["no member named 'member' in 'member::Two'"],337        )338 339        self.expect_expr("array_of_one[2].member", result_value="174")340        self.expect(341            "expr array_of_two[2].one[2].member",342            error=True,343            substrs=["no member named 'one' in 'array::Two'"],344        )345        self.expect(346            "expr array_of_two[2].member",347            error=True,348            substrs=["no member named 'member' in 'array::Two'"],349        )350 351        self.expect_expr("get_one().member", result_value="124")352        self.expect(353            "expr get_two().one().member",354            error=True,355            substrs=["calling 'get_two' with incomplete return type 'result::Two'"],356        )357        self.expect(358            "expr get_two().member",359            error=True,360            substrs=["calling 'get_two' with incomplete return type 'result::Two'"],361        )362 363        self._check_incomplete_frame_variable_output()364