1""" 2Test completing types using information from other shared libraries. 3""" 4 5import os 6import lldb 7from lldbsuite.test.decorators import * 8from lldbsuite.test.lldbtest import * 9from lldbsuite.test import lldbutil 10 11 12class LimitDebugInfoTestCase(TestBase): 13 14 mydir = TestBase.compute_mydir(__file__) 15 16 def _check_type(self, target, name): 17 exe = target.FindModule(lldb.SBFileSpec("a.out")) 18 type_ = exe.FindFirstType(name) 19 self.trace("type_: %s"%type_) 20 self.assertTrue(type_) 21 base = type_.GetDirectBaseClassAtIndex(0).GetType() 22 self.trace("base:%s"%base) 23 self.assertTrue(base) 24 self.assertEquals(base.GetNumberOfFields(), 0) 25 26 def _check_debug_info_is_limited(self, target): 27 # Without other shared libraries we should only see the member declared 28 # in the derived class. This serves as a sanity check that we are truly 29 # building with limited debug info. 30 self._check_type(target, "InheritsFromOne") 31 self._check_type(target, "InheritsFromTwo") 32 33 @skipIf(bugnumber="pr46284", debug_info="gmodules") 34 @skipIfWindows # Clang emits type info even with -flimit-debug-info 35 # Requires DW_CC_pass_by_* attributes from Clang 7 to correctly call 36 # by-value functions. 37 @skipIf(compiler="clang", compiler_version=['<', '7.0']) 38 def test_one_and_two_debug(self): 39 self.build() 40 target = self.dbg.CreateTarget(self.getBuildArtifact("a.out")) 41 42 self._check_debug_info_is_limited(target) 43 44 lldbutil.run_to_name_breakpoint(self, "main", 45 extra_images=["one", "two"]) 46 47 # But when other shared libraries are loaded, we should be able to see 48 # all members. 49 self.expect_expr("inherits_from_one.member", result_value="47") 50 self.expect_expr("inherits_from_one.one", result_value="142") 51 self.expect_expr("inherits_from_two.member", result_value="47") 52 self.expect_expr("inherits_from_two.one", result_value="142") 53 self.expect_expr("inherits_from_two.two", result_value="242") 54 55 self.expect_expr("one_as_member.member", result_value="47") 56 self.expect_expr("one_as_member.one.member", result_value="147") 57 self.expect_expr("two_as_member.member", result_value="47") 58 self.expect_expr("two_as_member.two.one.member", result_value="147") 59 self.expect_expr("two_as_member.two.member", result_value="247") 60 61 self.expect_expr("array_of_one[2].member", result_value="174") 62 self.expect_expr("array_of_two[2].one[2].member", result_value="174") 63 self.expect_expr("array_of_two[2].member", result_value="274") 64 65 self.expect_expr("get_one().member", result_value="124") 66 self.expect_expr("get_two().one().member", result_value="124") 67 self.expect_expr("get_two().member", result_value="224") 68 69 self.expect_expr("shadowed_one.member", result_value="47") 70 self.expect_expr("shadowed_one.one", result_value="142") 71 72 @skipIf(bugnumber="pr46284", debug_info="gmodules") 73 @skipIfWindows # Clang emits type info even with -flimit-debug-info 74 # Requires DW_CC_pass_by_* attributes from Clang 7 to correctly call 75 # by-value functions. 76 @skipIf(compiler="clang", compiler_version=['<', '7.0']) 77 def test_two_debug(self): 78 self.build(dictionary=dict(STRIP_ONE="1")) 79 target = self.dbg.CreateTarget(self.getBuildArtifact("a.out")) 80 81 self._check_debug_info_is_limited(target) 82 83 lldbutil.run_to_name_breakpoint(self, "main", 84 extra_images=["one", "two"]) 85 86 # This time, we should only see the members from the second library. 87 self.expect_expr("inherits_from_one.member", result_value="47") 88 self.expect("expr inherits_from_one.one", error=True, 89 substrs=["no member named 'one' in 'InheritsFromOne'"]) 90 self.expect_expr("inherits_from_two.member", result_value="47") 91 self.expect("expr inherits_from_two.one", error=True, 92 substrs=["no member named 'one' in 'InheritsFromTwo'"]) 93 self.expect_expr("inherits_from_two.two", result_value="242") 94 95 self.expect_expr("one_as_member.member", result_value="47") 96 self.expect("expr one_as_member.one.member", error=True, 97 substrs=["no member named 'member' in 'member::One'"]) 98 self.expect_expr("two_as_member.member", result_value="47") 99 self.expect("expr two_as_member.two.one.member", error=True, 100 substrs=["no member named 'member' in 'member::One'"]) 101 self.expect_expr("two_as_member.two.member", result_value="247") 102 103 self.expect("expr array_of_one[2].member", error=True, 104 substrs=["no member named 'member' in 'array::One'"]) 105 self.expect("expr array_of_two[2].one[2].member", error=True, 106 substrs=["no member named 'member' in 'array::One'"]) 107 self.expect_expr("array_of_two[2].member", result_value="274") 108 109 self.expect("expr get_one().member", error=True, 110 substrs=["calling 'get_one' with incomplete return type 'result::One'"]) 111 self.expect("expr get_two().one().member", error=True, 112 substrs=["calling 'one' with incomplete return type 'result::One'"]) 113 self.expect_expr("get_two().member", result_value="224") 114 115 @skipIf(bugnumber="pr46284", debug_info="gmodules") 116 @skipIfWindows # Clang emits type info even with -flimit-debug-info 117 # Requires DW_CC_pass_by_* attributes from Clang 7 to correctly call 118 # by-value functions. 119 @skipIf(compiler="clang", compiler_version=['<', '7.0']) 120 def test_one_debug(self): 121 self.build(dictionary=dict(STRIP_TWO="1")) 122 target = self.dbg.CreateTarget(self.getBuildArtifact("a.out")) 123 124 self._check_debug_info_is_limited(target) 125 126 lldbutil.run_to_name_breakpoint(self, "main", 127 extra_images=["one", "two"]) 128 129 # In this case we should only see the members from the second library. 130 # Note that we cannot see inherits_from_two.one because without debug 131 # info for "Two", we cannot determine that it in fact inherits from 132 # "One". 133 self.expect_expr("inherits_from_one.member", result_value="47") 134 self.expect_expr("inherits_from_one.one", result_value="142") 135 self.expect_expr("inherits_from_two.member", result_value="47") 136 self.expect("expr inherits_from_two.one", error=True, 137 substrs=["no member named 'one' in 'InheritsFromTwo'"]) 138 self.expect("expr inherits_from_two.two", error=True, 139 substrs=["no member named 'two' in 'InheritsFromTwo'"]) 140 141 self.expect_expr("one_as_member.member", result_value="47") 142 self.expect_expr("one_as_member.one.member", result_value="147") 143 self.expect_expr("two_as_member.member", result_value="47") 144 self.expect("expr two_as_member.two.one.member", error=True, 145 substrs=["no member named 'one' in 'member::Two'"]) 146 self.expect("expr two_as_member.two.member", error=True, 147 substrs=["no member named 'member' in 'member::Two'"]) 148 149 self.expect_expr("array_of_one[2].member", result_value="174") 150 self.expect("expr array_of_two[2].one[2].member", error=True, 151 substrs=["no member named 'one' in 'array::Two'"]) 152 self.expect("expr array_of_two[2].member", error=True, 153 substrs=["no member named 'member' in 'array::Two'"]) 154 155 self.expect_expr("get_one().member", result_value="124") 156 self.expect("expr get_two().one().member", error=True, 157 substrs=["calling 'get_two' with incomplete return type 'result::Two'"]) 158 self.expect("expr get_two().member", error=True, 159 substrs=["calling 'get_two' with incomplete return type 'result::Two'"]) 160