1""" 2Test using LLDB data formatters with frozen objects coming from the expression parser. 3""" 4 5 6import lldb 7from lldbsuite.test.decorators import * 8from lldbsuite.test.lldbtest import * 9from lldbsuite.test import lldbutil 10 11 12class ExprFormattersTestCase(TestBase): 13 def setUp(self): 14 # Call super's setUp(). 15 TestBase.setUp(self) 16 # Find the line number to break for main.cpp. 17 self.line = line_number("main.cpp", "// Stop here") 18 19 @skipIfTargetAndroid() # skipping to avoid crashing the test runner 20 @expectedFailureAndroid("llvm.org/pr24691") # we hit an assertion in clang 21 def test(self): 22 """Test expr + formatters for good interoperability.""" 23 self.build() 24 25 # This is the function to remove the custom formats in order to have a 26 # clean slate for the next test case. 27 def cleanup(): 28 self.runCmd("type summary clear", check=False) 29 self.runCmd("type synthetic clear", check=False) 30 31 # Execute the cleanup function during test case tear down. 32 self.addTearDownHook(cleanup) 33 34 """Test expr + formatters for good interoperability.""" 35 self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) 36 37 lldbutil.run_break_set_by_file_and_line( 38 self, "main.cpp", self.line, loc_exact=True 39 ) 40 41 self.runCmd("run", RUN_SUCCEEDED) 42 self.runCmd("command script import formatters.py") 43 self.runCmd("command script import foosynth.py") 44 45 if self.TraceOn(): 46 self.runCmd("frame variable foo1 --show-types") 47 self.runCmd("frame variable foo1.b --show-types") 48 self.runCmd("frame variable foo1.b.b_ref --show-types") 49 50 self.filecheck( 51 "expression --show-types -- *(new_foo(47))", 52 __file__, 53 "-check-prefix=EXPR-TYPES-NEW-FOO", 54 ) 55 # EXPR-TYPES-NEW-FOO: (foo) ${{.*}} = { 56 # EXPR-TYPES-NEW-FOO-NEXT: (int) a = 47 57 # EXPR-TYPES-NEW-FOO-NEXT: (int *) a_ptr = 0x 58 # EXPR-TYPES-NEW-FOO-NEXT: (bar) b = { 59 # EXPR-TYPES-NEW-FOO-NEXT: (int) i = 94 60 # EXPR-TYPES-NEW-FOO-NEXT: (int *) i_ptr = 0x 61 # EXPR-TYPES-NEW-FOO-NEXT: (baz) b = { 62 # EXPR-TYPES-NEW-FOO-NEXT: (int) h = 97 63 # EXPR-TYPES-NEW-FOO-NEXT: (int) k = 99 64 # EXPR-TYPES-NEW-FOO-NEXT: } 65 # EXPR-TYPES-NEW-FOO-NEXT: (baz &) b_ref = 0x 66 # EXPR-TYPES-NEW-FOO-NEXT: } 67 # EXPR-TYPES-NEW-FOO-NEXT: } 68 69 self.runCmd("type summary add -F formatters.foo_SummaryProvider3 foo") 70 self.filecheck("expression foo1", __file__, "-check-prefix=EXPR-FOO1opts") 71 # EXPR-FOO1opts: (foo) $ 72 # EXPR-FOO1opts-SAME: a = 12 73 # EXPR-FOO1opts-SAME: a_ptr = {{[0-9]+}} -> 13 74 # EXPR-FOO1opts-SAME: i = 24 75 # EXPR-FOO1opts-SAME: i_ptr = {{[0-9]+}} -> 25 76 # EXPR-FOO1opts-SAME: b_ref = {{[0-9]+}} 77 # EXPR-FOO1opts-SAME: h = 27 78 # EXPR-FOO1opts-SAME: k = 29 79 # EXPR-FOO1opts-SAME: WITH_OPTS 80 81 self.runCmd("type summary delete foo") 82 83 self.runCmd("type summary add -F formatters.foo_SummaryProvider foo") 84 85 self.expect("expression new_int(12)", substrs=["(int *) $", " = 0x"]) 86 87 self.runCmd('type summary add -s "${var%pointer} -> ${*var%decimal}" "int *"') 88 89 self.expect("expression new_int(12)", substrs=["(int *) $", "= 0x", " -> 12"]) 90 91 self.expect("expression foo1.a_ptr", substrs=["(int *) $", "= 0x", " -> 13"]) 92 93 self.filecheck("expression foo1", __file__, "-check-prefix=EXPR-FOO1") 94 # EXPR-FOO1: (foo) $ 95 # EXPR-FOO1-SAME: a = 12 96 # EXPR-FOO1-SAME: a_ptr = {{[0-9]+}} -> 13 97 # EXPR-FOO1-SAME: i = 24 98 # EXPR-FOO1-SAME: i_ptr = {{[0-9]+}} -> 25 99 # EXPR-FOO1-SAME: b_ref = {{[0-9]+}} 100 # EXPR-FOO1-SAME: h = 27 101 # EXPR-FOO1-SAME: k = 29 102 103 self.filecheck( 104 "expression --ptr-depth=1 -- new_foo(47)", 105 __file__, 106 "-check-prefix=EXPR-PTR-DEPTH1", 107 ) 108 # EXPR-PTR-DEPTH1: (foo *) $ 109 # EXPR-PTR-DEPTH1-SAME: a = 47 110 # EXPR-PTR-DEPTH1-SAME: a_ptr = {{[0-9]+}} -> 48 111 # EXPR-PTR-DEPTH1-SAME: i = 94 112 # EXPR-PTR-DEPTH1-SAME: i_ptr = {{[0-9]+}} -> 95 113 114 self.filecheck("expression foo2", __file__, "-check-prefix=EXPR-FOO2") 115 # EXPR-FOO2: (foo) $ 116 # EXPR-FOO2-SAME: a = 121 117 # EXPR-FOO2-SAME: a_ptr = {{[0-9]+}} -> 122 118 # EXPR-FOO2-SAME: i = 242 119 # EXPR-FOO2-SAME: i_ptr = {{[0-9]+}} -> 243 120 # EXPR-FOO2-SAME: h = 245 121 # EXPR-FOO2-SAME: k = 247 122 123 object_name = self.res.GetOutput() 124 object_name = object_name[7:] 125 object_name = object_name[0 : object_name.find(" =")] 126 127 self.filecheck("frame variable foo2", __file__, "-check-prefix=VAR-FOO2") 128 # VAR-FOO2: (foo) foo2 129 # VAR-FOO2-SAME: a = 121 130 # VAR-FOO2-SAME: a_ptr = {{[0-9]+}} -> 122 131 # VAR-FOO2-SAME: i = 242 132 # VAR-FOO2-SAME: i_ptr = {{[0-9]+}} -> 243 133 # VAR-FOO2-SAME: h = 245 134 # VAR-FOO2-SAME: k = 247 135 136 # The object is the same as foo2, so use the EXPR-FOO2 checks. 137 self.filecheck( 138 "expression $" + object_name, __file__, "-check-prefix=EXPR-FOO2" 139 ) 140 141 self.runCmd("type summary delete foo") 142 self.runCmd( 143 "type synthetic add --python-class foosynth.FooSyntheticProvider foo" 144 ) 145 146 self.expect( 147 "expression --show-types -- $" + object_name, 148 substrs=["(foo) $", " = {", "(int) *i_ptr = 243"], 149 ) 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 ) 169 170 self.expect("expression $" + object_name + ".a", substrs=["7777"]) 171 172 self.expect("expression *$" + object_name + ".b.i_ptr", substrs=["8888"]) 173 174 self.expect( 175 "expression $" + 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 ) 188 189 self.runCmd("type summary delete foo") 190 self.runCmd( 191 "type synthetic add --python-class foosynth.FooSyntheticProvider foo" 192 ) 193 194 self.expect( 195 "expression --show-types -- $" + object_name, 196 substrs=["(foo) $", " = {", "(int) *i_ptr = 8888"], 197 ) 198 199 self.runCmd("n") 200 201 self.runCmd("type synthetic delete foo") 202 self.runCmd("type summary add -F formatters.foo_SummaryProvider foo") 203 204 self.expect( 205 "expression $" + object_name, 206 substrs=[ 207 "(foo) $", 208 "a = 121", 209 "a_ptr = ", 210 " -> 122", 211 "i = 242", 212 "i_ptr = ", 213 " -> 8888", 214 "k = 247", 215 ], 216 ) 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.assertEqual(a_data.GetUnsignedInt32(error, 0), 122, "*a_ptr = 122") 228 229 ret = line_number("main.cpp", "Done initializing") 230 self.runCmd("thread until " + str(ret)) 231 232 self.expect("frame variable numbers", substrs=["1", "2", "3", "4", "5"]) 233 234 self.expect("expression numbers", substrs=["1", "2", "3", "4", "5"]) 235 236 frozen = frame.EvaluateExpression("&numbers") 237 238 a_data = frozen.GetPointeeData(0, 1) 239 240 self.assertEqual(a_data.GetUnsignedInt32(error, 0), 1, "numbers[0] == 1") 241 self.assertEqual(a_data.GetUnsignedInt32(error, 4), 2, "numbers[1] == 2") 242 self.assertEqual(a_data.GetUnsignedInt32(error, 8), 3, "numbers[2] == 3") 243 self.assertEqual(a_data.GetUnsignedInt32(error, 12), 4, "numbers[3] == 4") 244 self.assertEqual(a_data.GetUnsignedInt32(error, 16), 5, "numbers[4] == 5") 245 246 frozen = frame.EvaluateExpression("numbers") 247 248 a_data = frozen.GetData() 249 250 self.assertEqual(a_data.GetUnsignedInt32(error, 0), 1, "numbers[0] == 1") 251 self.assertEqual(a_data.GetUnsignedInt32(error, 4), 2, "numbers[1] == 2") 252 self.assertEqual(a_data.GetUnsignedInt32(error, 8), 3, "numbers[2] == 3") 253 self.assertEqual(a_data.GetUnsignedInt32(error, 12), 4, "numbers[3] == 4") 254 self.assertEqual(a_data.GetUnsignedInt32(error, 16), 5, "numbers[4] == 5") 255