1""" 2Test using LLDB data formatters with frozen objects coming from the expression parser. 3""" 4 5 6 7import lldb 8from lldbsuite.test.decorators import * 9from lldbsuite.test.lldbtest import * 10from lldbsuite.test import lldbutil 11 12 13class ExprFormattersTestCase(TestBase): 14 15 mydir = TestBase.compute_mydir(__file__) 16 17 def setUp(self): 18 # Call super's setUp(). 19 TestBase.setUp(self) 20 # Find the line number to break for main.cpp. 21 self.line = line_number('main.cpp', 22 '// Stop here') 23 24 @skipIfFreeBSD # llvm.org/pr24691 skipping to avoid crashing the test runner 25 @expectedFailureNetBSD 26 @expectedFailureAll( 27 oslist=['freebsd'], 28 bugnumber='llvm.org/pr19011 Newer Clang omits C1 complete object constructor') 29 @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr21765") 30 @skipIfTargetAndroid() # skipping to avoid crashing the test runner 31 @expectedFailureAndroid('llvm.org/pr24691') # we hit an assertion in clang 32 def test(self): 33 """Test expr + formatters for good interoperability.""" 34 self.build() 35 36 # This is the function to remove the custom formats in order to have a 37 # clean slate for the next test case. 38 def cleanup(): 39 self.runCmd('type summary clear', check=False) 40 self.runCmd('type synthetic clear', check=False) 41 42 # Execute the cleanup function during test case tear down. 43 self.addTearDownHook(cleanup) 44 45 """Test expr + formatters for good interoperability.""" 46 self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) 47 48 lldbutil.run_break_set_by_file_and_line( 49 self, "main.cpp", self.line, loc_exact=True) 50 51 self.runCmd("run", RUN_SUCCEEDED) 52 self.runCmd("command script import formatters.py") 53 self.runCmd("command script import foosynth.py") 54 55 if self.TraceOn(): 56 self.runCmd("frame variable foo1 --show-types") 57 self.runCmd("frame variable foo1.b --show-types") 58 self.runCmd("frame variable foo1.b.b_ref --show-types") 59 60 self.filecheck("expression --show-types -- *(new foo(47))", __file__, 61 '-check-prefix=EXPR-TYPES-NEW-FOO') 62 # EXPR-TYPES-NEW-FOO: (foo) ${{.*}} = { 63 # EXPR-TYPES-NEW-FOO-NEXT: (int) a = 47 64 # EXPR-TYPES-NEW-FOO-NEXT: (int *) a_ptr = 0x 65 # EXPR-TYPES-NEW-FOO-NEXT: (bar) b = { 66 # EXPR-TYPES-NEW-FOO-NEXT: (int) i = 94 67 # EXPR-TYPES-NEW-FOO-NEXT: (int *) i_ptr = 0x 68 # EXPR-TYPES-NEW-FOO-NEXT: (baz) b = { 69 # EXPR-TYPES-NEW-FOO-NEXT: (int) h = 97 70 # EXPR-TYPES-NEW-FOO-NEXT: (int) k = 99 71 # EXPR-TYPES-NEW-FOO-NEXT: } 72 # EXPR-TYPES-NEW-FOO-NEXT: (baz &) b_ref = 0x 73 # EXPR-TYPES-NEW-FOO-NEXT: } 74 # EXPR-TYPES-NEW-FOO-NEXT: } 75 76 77 self.runCmd("type summary add -F formatters.foo_SummaryProvider3 foo") 78 self.filecheck("expression foo1", __file__, '-check-prefix=EXPR-FOO1opts') 79 # EXPR-FOO1opts: (foo) $ 80 # EXPR-FOO1opts-SAME: a = 12 81 # EXPR-FOO1opts-SAME: a_ptr = {{[0-9]+}} -> 13 82 # EXPR-FOO1opts-SAME: i = 24 83 # EXPR-FOO1opts-SAME: i_ptr = {{[0-9]+}} -> 25 84 # EXPR-FOO1opts-SAME: b_ref = {{[0-9]+}} 85 # EXPR-FOO1opts-SAME: h = 27 86 # EXPR-FOO1opts-SAME: k = 29 87 # EXPR-FOO1opts-SAME: WITH_OPTS 88 89 self.runCmd("type summary delete foo") 90 91 self.runCmd("type summary add -F formatters.foo_SummaryProvider foo") 92 93 self.expect("expression new int(12)", 94 substrs=['(int *) $', ' = 0x']) 95 96 self.runCmd( 97 "type summary add -s \"${var%pointer} -> ${*var%decimal}\" \"int *\"") 98 99 self.expect("expression new int(12)", 100 substrs=['(int *) $', '= 0x', ' -> 12']) 101 102 self.expect("expression foo1.a_ptr", 103 substrs=['(int *) $', '= 0x', ' -> 13']) 104 105 self.filecheck("expression foo1", __file__, '-check-prefix=EXPR-FOO1') 106 # EXPR-FOO1: (foo) $ 107 # EXPR-FOO1-SAME: a = 12 108 # EXPR-FOO1-SAME: a_ptr = {{[0-9]+}} -> 13 109 # EXPR-FOO1-SAME: i = 24 110 # EXPR-FOO1-SAME: i_ptr = {{[0-9]+}} -> 25 111 # EXPR-FOO1-SAME: b_ref = {{[0-9]+}} 112 # EXPR-FOO1-SAME: h = 27 113 # EXPR-FOO1-SAME: k = 29 114 115 self.filecheck("expression --ptr-depth=1 -- new foo(47)", __file__, 116 '-check-prefix=EXPR-PTR-DEPTH1') 117 # EXPR-PTR-DEPTH1: (foo *) $ 118 # EXPR-PTR-DEPTH1-SAME: a = 47 119 # EXPR-PTR-DEPTH1-SAME: a_ptr = {{[0-9]+}} -> 48 120 # EXPR-PTR-DEPTH1-SAME: i = 94 121 # EXPR-PTR-DEPTH1-SAME: i_ptr = {{[0-9]+}} -> 95 122 123 self.filecheck("expression foo2", __file__, '-check-prefix=EXPR-FOO2') 124 # EXPR-FOO2: (foo) $ 125 # EXPR-FOO2-SAME: a = 121 126 # EXPR-FOO2-SAME: a_ptr = {{[0-9]+}} -> 122 127 # EXPR-FOO2-SAME: i = 242 128 # EXPR-FOO2-SAME: i_ptr = {{[0-9]+}} -> 243 129 # EXPR-FOO2-SAME: h = 245 130 # EXPR-FOO2-SAME: k = 247 131 132 object_name = self.res.GetOutput() 133 object_name = object_name[7:] 134 object_name = object_name[0:object_name.find(' =')] 135 136 self.filecheck("frame variable foo2", __file__, '-check-prefix=VAR-FOO2') 137 # VAR-FOO2: (foo) foo2 138 # VAR-FOO2-SAME: a = 121 139 # VAR-FOO2-SAME: a_ptr = {{[0-9]+}} -> 122 140 # VAR-FOO2-SAME: i = 242 141 # VAR-FOO2-SAME: i_ptr = {{[0-9]+}} -> 243 142 # VAR-FOO2-SAME: h = 245 143 # VAR-FOO2-SAME: k = 247 144 145 # The object is the same as foo2, so use the EXPR-FOO2 checks. 146 self.filecheck("expression $" + object_name, __file__, 147 '-check-prefix=EXPR-FOO2') 148 149 self.runCmd("type summary delete foo") 150 self.runCmd( 151 "type synthetic add --python-class foosynth.FooSyntheticProvider foo") 152 153 self.expect("expression --show-types -- $" + object_name, 154 substrs=['(foo) $', ' = {', '(int) *i_ptr = 243']) 155 156 self.runCmd("n") 157 self.runCmd("n") 158 159 self.runCmd("type synthetic delete foo") 160 self.runCmd("type summary add -F formatters.foo_SummaryProvider foo") 161 162 self.expect( 163 "expression foo2", 164 substrs=[ 165 '(foo) $', 166 'a = 7777', 167 'a_ptr = ', 168 ' -> 122', 169 'i = 242', 170 'i_ptr = ', 171 ' -> 8888']) 172 173 self.expect("expression $" + object_name + '.a', 174 substrs=['7777']) 175 176 self.expect("expression *$" + object_name + '.b.i_ptr', 177 substrs=['8888']) 178 179 self.expect( 180 "expression $" + 181 object_name, 182 substrs=[ 183 '(foo) $', 184 'a = 121', 185 'a_ptr = ', 186 ' -> 122', 187 'i = 242', 188 'i_ptr = ', 189 ' -> 8888', 190 'h = 245', 191 'k = 247']) 192 193 self.runCmd("type summary delete foo") 194 self.runCmd( 195 "type synthetic add --python-class foosynth.FooSyntheticProvider foo") 196 197 self.expect("expression --show-types -- $" + object_name, 198 substrs=['(foo) $', ' = {', '(int) *i_ptr = 8888']) 199 200 self.runCmd("n") 201 202 self.runCmd("type synthetic delete foo") 203 self.runCmd("type summary add -F formatters.foo_SummaryProvider foo") 204 205 self.expect( 206 "expression $" + 207 object_name, 208 substrs=[ 209 '(foo) $', 210 'a = 121', 211 'a_ptr = ', 212 ' -> 122', 213 'i = 242', 214 'i_ptr = ', 215 ' -> 8888', 216 'k = 247']) 217 218 process = self.dbg.GetSelectedTarget().GetProcess() 219 thread = process.GetThreadAtIndex(0) 220 frame = thread.GetSelectedFrame() 221 222 frozen = frame.EvaluateExpression("$" + object_name + ".a_ptr") 223 224 a_data = frozen.GetPointeeData() 225 226 error = lldb.SBError() 227 self.assertTrue( 228 a_data.GetUnsignedInt32( 229 error, 230 0) == 122, 231 '*a_ptr = 122') 232 233 ret = line_number("main.cpp", "Done initializing") 234 self.runCmd("thread until " + str(ret)) 235 236 self.expect("frame variable numbers", 237 substrs=['1', '2', '3', '4', '5']) 238 239 self.expect("expression numbers", 240 substrs=['1', '2', '3', '4', '5']) 241 242 frozen = frame.EvaluateExpression("&numbers") 243 244 a_data = frozen.GetPointeeData(0, 1) 245 246 self.assertTrue( 247 a_data.GetUnsignedInt32( 248 error, 249 0) == 1, 250 'numbers[0] == 1') 251 self.assertTrue( 252 a_data.GetUnsignedInt32( 253 error, 254 4) == 2, 255 'numbers[1] == 2') 256 self.assertTrue( 257 a_data.GetUnsignedInt32( 258 error, 259 8) == 3, 260 'numbers[2] == 3') 261 self.assertTrue( 262 a_data.GetUnsignedInt32( 263 error, 264 12) == 4, 265 'numbers[3] == 4') 266 self.assertTrue( 267 a_data.GetUnsignedInt32( 268 error, 269 16) == 5, 270 'numbers[4] == 5') 271 272 frozen = frame.EvaluateExpression("numbers") 273 274 a_data = frozen.GetData() 275 276 self.assertTrue( 277 a_data.GetUnsignedInt32( 278 error, 279 0) == 1, 280 'numbers[0] == 1') 281 self.assertTrue( 282 a_data.GetUnsignedInt32( 283 error, 284 4) == 2, 285 'numbers[1] == 2') 286 self.assertTrue( 287 a_data.GetUnsignedInt32( 288 error, 289 8) == 3, 290 'numbers[2] == 3') 291 self.assertTrue( 292 a_data.GetUnsignedInt32( 293 error, 294 12) == 4, 295 'numbers[3] == 4') 296 self.assertTrue( 297 a_data.GetUnsignedInt32( 298 error, 299 16) == 5, 300 'numbers[4] == 5') 301