255 lines · python
1"""2Test using LLDB data formatters with frozen objects coming from the expression parser.3"""4 5 6import lldb7from lldbsuite.test.decorators import *8from lldbsuite.test.lldbtest import *9from lldbsuite.test import lldbutil10 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 runner20 @expectedFailureAndroid("llvm.org/pr24691") # we hit an assertion in clang21 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 a26 # 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=True39 )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 = 4757 # EXPR-TYPES-NEW-FOO-NEXT: (int *) a_ptr = 0x58 # EXPR-TYPES-NEW-FOO-NEXT: (bar) b = {59 # EXPR-TYPES-NEW-FOO-NEXT: (int) i = 9460 # EXPR-TYPES-NEW-FOO-NEXT: (int *) i_ptr = 0x61 # EXPR-TYPES-NEW-FOO-NEXT: (baz) b = {62 # EXPR-TYPES-NEW-FOO-NEXT: (int) h = 9763 # EXPR-TYPES-NEW-FOO-NEXT: (int) k = 9964 # EXPR-TYPES-NEW-FOO-NEXT: }65 # EXPR-TYPES-NEW-FOO-NEXT: (baz &) b_ref = 0x66 # 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 = 1273 # EXPR-FOO1opts-SAME: a_ptr = {{[0-9]+}} -> 1374 # EXPR-FOO1opts-SAME: i = 2475 # EXPR-FOO1opts-SAME: i_ptr = {{[0-9]+}} -> 2576 # EXPR-FOO1opts-SAME: b_ref = {{[0-9]+}}77 # EXPR-FOO1opts-SAME: h = 2778 # EXPR-FOO1opts-SAME: k = 2979 # EXPR-FOO1opts-SAME: WITH_OPTS80 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 = 1296 # EXPR-FOO1-SAME: a_ptr = {{[0-9]+}} -> 1397 # EXPR-FOO1-SAME: i = 2498 # EXPR-FOO1-SAME: i_ptr = {{[0-9]+}} -> 2599 # EXPR-FOO1-SAME: b_ref = {{[0-9]+}}100 # EXPR-FOO1-SAME: h = 27101 # EXPR-FOO1-SAME: k = 29102 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 = 47110 # EXPR-PTR-DEPTH1-SAME: a_ptr = {{[0-9]+}} -> 48111 # EXPR-PTR-DEPTH1-SAME: i = 94112 # EXPR-PTR-DEPTH1-SAME: i_ptr = {{[0-9]+}} -> 95113 114 self.filecheck("expression foo2", __file__, "-check-prefix=EXPR-FOO2")115 # EXPR-FOO2: (foo) $116 # EXPR-FOO2-SAME: a = 121117 # EXPR-FOO2-SAME: a_ptr = {{[0-9]+}} -> 122118 # EXPR-FOO2-SAME: i = 242119 # EXPR-FOO2-SAME: i_ptr = {{[0-9]+}} -> 243120 # EXPR-FOO2-SAME: h = 245121 # EXPR-FOO2-SAME: k = 247122 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) foo2129 # VAR-FOO2-SAME: a = 121130 # VAR-FOO2-SAME: a_ptr = {{[0-9]+}} -> 122131 # VAR-FOO2-SAME: i = 242132 # VAR-FOO2-SAME: i_ptr = {{[0-9]+}} -> 243133 # VAR-FOO2-SAME: h = 245134 # VAR-FOO2-SAME: k = 247135 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