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