1""" 2Test lldb data formatter subsystem. 3""" 4 5 6import lldb 7from lldbsuite.test.lldbtest import * 8from lldbsuite.test.decorators import * 9from lldbsuite.test.lldbtest import * 10from lldbsuite.test import lldbutil 11 12USE_LIBSTDCPP = "USE_LIBSTDCPP" 13USE_LIBCPP = "USE_LIBCPP" 14 15 16class GenericMultiMapDataFormatterTestCase(TestBase): 17 def setUp(self): 18 TestBase.setUp(self) 19 self.namespace = "std" 20 21 def findVariable(self, name): 22 var = self.frame().FindVariable(name) 23 self.assertTrue(var.IsValid()) 24 return var 25 26 def getVariableType(self, name): 27 var = self.findVariable(name) 28 return var.GetType().GetDisplayTypeName() 29 30 def check(self, var_name, size): 31 var = self.findVariable(var_name) 32 self.assertEqual(var.GetNumChildren(), size) 33 children = [] 34 for i in range(size): 35 child = var.GetChildAtIndex(i) 36 children.append(ValueCheck(value=child.GetValue())) 37 self.expect_var_path( 38 var_name, type=self.getVariableType(var_name), children=children 39 ) 40 41 def do_test_with_run_command(self, stdlib_type): 42 """Test that that file and class static variables display correctly.""" 43 self.build(dictionary={stdlib_type: "1"}) 44 self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) 45 46 bkpt = self.target().FindBreakpointByID( 47 lldbutil.run_break_set_by_source_regexp( 48 self, "Set break point at this line." 49 ) 50 ) 51 52 self.runCmd("run", RUN_SUCCEEDED) 53 54 # The stop reason of the thread should be breakpoint. 55 self.expect( 56 "thread list", 57 STOPPED_DUE_TO_BREAKPOINT, 58 substrs=["stopped", "stop reason = breakpoint"], 59 ) 60 61 # This is the function to remove the custom formats in order to have a 62 # clean slate for the next test case. 63 def cleanup(): 64 self.runCmd("type format clear", check=False) 65 self.runCmd("type summary clear", check=False) 66 self.runCmd("type filter clear", check=False) 67 self.runCmd("type synth clear", check=False) 68 self.runCmd("settings set target.max-children-count 256", check=False) 69 70 # Execute the cleanup function during test case tear down. 71 self.addTearDownHook(cleanup) 72 73 multimap = self.namespace + "::multimap" 74 75 # We expect that in some malformed cases the map shows size 0 76 self.expect("frame variable corrupt_map", substrs=[multimap, "size=0", "{}"]) 77 78 lldbutil.continue_to_breakpoint(self.process(), bkpt) 79 80 self.expect("frame variable ii", substrs=[multimap, "size=0", "{}"]) 81 82 lldbutil.continue_to_breakpoint(self.process(), bkpt) 83 84 self.expect( 85 "frame variable ii", 86 substrs=[ 87 multimap, 88 "size=2", 89 "[0] = (first = 0, second = 0)", 90 "[1] = (first = 1, second = 1)", 91 ], 92 ) 93 94 self.check("ii", 2) 95 96 lldbutil.continue_to_breakpoint(self.process(), bkpt) 97 98 self.expect( 99 "frame variable ii", 100 substrs=[ 101 multimap, 102 "size=4", 103 "[2] = ", 104 "first = 2", 105 "second = 0", 106 "[3] = ", 107 "first = 3", 108 "second = 1", 109 ], 110 ) 111 112 self.check("ii", 4) 113 114 lldbutil.continue_to_breakpoint(self.process(), bkpt) 115 116 self.expect( 117 "frame variable ii", 118 substrs=[ 119 multimap, 120 "size=8", 121 "[5] = ", 122 "first = 5", 123 "second = 0", 124 "[7] = ", 125 "first = 7", 126 "second = 1", 127 ], 128 ) 129 130 self.check("ii", 8) 131 132 self.expect( 133 "expression ii", 134 substrs=[ 135 multimap, 136 "size=8", 137 "[5] = ", 138 "first = 5", 139 "second = 0", 140 "[7] = ", 141 "first = 7", 142 "second = 1", 143 ], 144 ) 145 146 # check access-by-index 147 self.expect("frame variable ii[0]", substrs=["first = 0", "second = 0"]) 148 self.expect("frame variable ii[3]", substrs=["first =", "second ="]) 149 150 # check that MightHaveChildren() gets it right 151 self.assertTrue( 152 self.frame().FindVariable("ii").MightHaveChildren(), 153 "ii.MightHaveChildren() says False for non empty!", 154 ) 155 156 # check that the expression parser does not make use of 157 # synthetic children instead of running code 158 # TOT clang has a fix for this, which makes the expression command here succeed 159 # since this would make the test fail or succeed depending on clang version in use 160 # this is safer commented for the time being 161 # self.expect("expression ii[8]", matching=False, error=True, 162 # substrs = ['1234567']) 163 164 lldbutil.continue_to_breakpoint(self.process(), bkpt) 165 166 self.expect("frame variable ii", substrs=[multimap, "size=0", "{}"]) 167 168 self.expect("frame variable si", substrs=[multimap, "size=0", "{}"]) 169 170 lldbutil.continue_to_breakpoint(self.process(), bkpt) 171 172 self.expect( 173 "frame variable si", 174 substrs=[multimap, "size=1", "[0] = ", 'first = "zero"', "second = 0"], 175 ) 176 177 lldbutil.continue_to_breakpoint(self.process(), bkpt) 178 179 self.expect( 180 "frame variable si", 181 substrs=[ 182 multimap, 183 "size=4", 184 '[0] = (first = "one", second = 1)', 185 '[1] = (first = "three", second = 3)', 186 '[2] = (first = "two", second = 2)', 187 '[3] = (first = "zero", second = 0)', 188 ], 189 ) 190 191 self.expect( 192 "expression si", 193 substrs=[ 194 multimap, 195 "size=4", 196 '[0] = (first = "one", second = 1)', 197 '[1] = (first = "three", second = 3)', 198 '[2] = (first = "two", second = 2)', 199 '[3] = (first = "zero", second = 0)', 200 ], 201 ) 202 203 # check that MightHaveChildren() gets it right 204 self.assertTrue( 205 self.frame().FindVariable("si").MightHaveChildren(), 206 "si.MightHaveChildren() says False for non empty!", 207 ) 208 209 # check access-by-index 210 self.expect("frame variable si[0]", substrs=["first = ", "one", "second = 1"]) 211 212 # check that the expression parser does not make use of 213 # synthetic children instead of running code 214 # TOT clang has a fix for this, which makes the expression command here succeed 215 # since this would make the test fail or succeed depending on clang version in use 216 # this is safer commented for the time being 217 # self.expect("expression si[0]", matching=False, error=True, 218 # substrs = ['first = ', 'zero']) 219 220 lldbutil.continue_to_breakpoint(self.process(), bkpt) 221 222 self.expect("frame variable si", substrs=[multimap, "size=0", "{}"]) 223 224 lldbutil.continue_to_breakpoint(self.process(), bkpt) 225 226 self.expect("frame variable is", substrs=[multimap, "size=0", "{}"]) 227 228 lldbutil.continue_to_breakpoint(self.process(), bkpt) 229 230 self.expect( 231 "frame variable is", 232 substrs=[ 233 multimap, 234 "size=4", 235 '[0] = (first = 1, second = "is")', 236 '[1] = (first = 2, second = "smart")', 237 '[2] = (first = 3, second = "!!!")', 238 '[3] = (first = 85, second = "goofy")', 239 ], 240 ) 241 242 self.expect( 243 "expression is", 244 substrs=[ 245 multimap, 246 "size=4", 247 '[0] = (first = 1, second = "is")', 248 '[1] = (first = 2, second = "smart")', 249 '[2] = (first = 3, second = "!!!")', 250 '[3] = (first = 85, second = "goofy")', 251 ], 252 ) 253 254 # check that MightHaveChildren() gets it right 255 self.assertTrue( 256 self.frame().FindVariable("is").MightHaveChildren(), 257 "is.MightHaveChildren() says False for non empty!", 258 ) 259 260 # check access-by-index 261 self.expect("frame variable is[0]", substrs=["first = ", "second ="]) 262 263 # check that the expression parser does not make use of 264 # synthetic children instead of running code 265 # TOT clang has a fix for this, which makes the expression command here succeed 266 # since this would make the test fail or succeed depending on clang version in use 267 # this is safer commented for the time being 268 # self.expect("expression is[0]", matching=False, error=True, 269 # substrs = ['first = ', 'goofy']) 270 271 lldbutil.continue_to_breakpoint(self.process(), bkpt) 272 273 self.expect("frame variable is", substrs=[multimap, "size=0", "{}"]) 274 275 self.check("is", 0) 276 277 lldbutil.continue_to_breakpoint(self.process(), bkpt) 278 279 self.expect("frame variable ss", substrs=[multimap, "size=0", "{}"]) 280 281 self.check("ss", 0) 282 283 lldbutil.continue_to_breakpoint(self.process(), bkpt) 284 285 self.expect( 286 "frame variable ss", 287 substrs=[ 288 multimap, 289 "size=3", 290 '[0] = (first = "casa", second = "house")', 291 '[1] = (first = "ciao", second = "hello")', 292 '[2] = (first = "gatto", second = "cat")', 293 ], 294 ) 295 296 self.check("ss", 3) 297 298 self.expect( 299 "expression ss", 300 substrs=[ 301 multimap, 302 "size=3", 303 '[0] = (first = "casa", second = "house")', 304 '[1] = (first = "ciao", second = "hello")', 305 '[2] = (first = "gatto", second = "cat")', 306 ], 307 ) 308 309 # check that MightHaveChildren() gets it right 310 self.assertTrue( 311 self.frame().FindVariable("ss").MightHaveChildren(), 312 "ss.MightHaveChildren() says False for non empty!", 313 ) 314 315 # check access-by-index 316 self.expect("frame variable ss[2]", substrs=["gatto", "cat"]) 317 318 # check that the expression parser does not make use of 319 # synthetic children instead of running code 320 # TOT clang has a fix for this, which makes the expression command here succeed 321 # since this would make the test fail or succeed depending on clang version in use 322 # this is safer commented for the time being 323 # self.expect("expression ss[3]", matching=False, error=True, 324 # substrs = ['gatto']) 325 326 lldbutil.continue_to_breakpoint(self.process(), bkpt) 327 328 self.expect("frame variable ss", substrs=[multimap, "size=0", "{}"]) 329 330 self.check("ss", 0) 331 332 @add_test_categories(["libstdcxx"]) 333 @skipIf(compiler="clang", compiler_version=["<", "9.0"]) 334 def test_with_run_command_libstdcpp(self): 335 self.do_test_with_run_command(USE_LIBSTDCPP) 336 337 @skipIf(compiler="clang", compiler_version=["<", "9.0"]) 338 @add_test_categories(["libc++"]) 339 def test_with_run_command_libcpp(self): 340 self.do_test_with_run_command(USE_LIBCPP) 341