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