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