1"""Test Python APIs for working with formatters""" 2 3from __future__ import print_function 4 5 6import lldb 7from lldbsuite.test.decorators import * 8from lldbsuite.test.lldbtest import * 9from lldbsuite.test import lldbutil 10 11 12class SBFormattersAPITestCase(TestBase): 13 NO_DEBUG_INFO_TESTCASE = True 14 15 def setUp(self): 16 # Call super's setUp(). 17 TestBase.setUp(self) 18 self.line = line_number('main.cpp', '// Set break point at this line.') 19 20 def test_formatters_api(self): 21 """Test Python APIs for working with formatters""" 22 self.build() 23 self.setTearDownCleanup() 24 25 """Test Python APIs for working with formatters""" 26 self.runCmd("file " + self.getBuildArtifact("a.out"), 27 CURRENT_EXECUTABLE_SET) 28 29 lldbutil.run_break_set_by_file_and_line( 30 self, "main.cpp", self.line, num_expected_locations=1, 31 loc_exact=True) 32 33 self.runCmd("run", RUN_SUCCEEDED) 34 35 # The stop reason of the thread should be breakpoint. 36 self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, 37 substrs=['stopped', 38 'stop reason = breakpoint']) 39 40 # This is the function to remove the custom formats in order to have a 41 # clean slate for the next test case. 42 def cleanup(): 43 self.runCmd('type format clear', check=False) 44 self.runCmd('type summary clear', check=False) 45 self.runCmd('type filter clear', check=False) 46 self.runCmd('type synthetic clear', check=False) 47 self.runCmd('type category delete foobar', check=False) 48 self.runCmd('type category delete JASSynth', check=False) 49 self.runCmd('type category delete newbar', check=False) 50 51 # Execute the cleanup function during test case tear down. 52 self.addTearDownHook(cleanup) 53 54 format = lldb.SBTypeFormat(lldb.eFormatHex) 55 category = self.dbg.GetDefaultCategory() 56 category.AddTypeFormat(lldb.SBTypeNameSpecifier("int"), format) 57 58 self.expect("frame variable foo.A", 59 substrs=['0x00000001']) 60 self.expect("frame variable foo.E", matching=False, 61 substrs=['b8cca70a']) 62 63 category.AddTypeFormat(lldb.SBTypeNameSpecifier("long"), format) 64 self.expect("frame variable foo.A", 65 substrs=['0x00000001']) 66 self.expect("frame variable foo.E", 67 substrs=['b8cca70a']) 68 69 format.SetFormat(lldb.eFormatOctal) 70 category.AddTypeFormat(lldb.SBTypeNameSpecifier("int"), format) 71 self.expect("frame variable foo.A", 72 substrs=[' 01']) 73 self.expect("frame variable foo.E", 74 substrs=['b8cca70a']) 75 76 category.DeleteTypeFormat(lldb.SBTypeNameSpecifier("int")) 77 category.DeleteTypeFormat(lldb.SBTypeNameSpecifier("long")) 78 self.expect("frame variable foo.A", matching=False, 79 substrs=[' 01']) 80 self.expect("frame variable foo.E", matching=False, 81 substrs=['b8cca70a']) 82 83 summary = lldb.SBTypeSummary.CreateWithSummaryString( 84 "the hello world you'll never see") 85 summary.SetSummaryString('hello world') 86 new_category = self.dbg.GetCategory("foobar") 87 self.assertFalse( 88 new_category.IsValid(), 89 "getting a non-existing category worked") 90 new_category = self.dbg.CreateCategory("foobar") 91 new_category.SetEnabled(True) 92 new_category.AddTypeSummary( 93 lldb.SBTypeNameSpecifier( 94 "^.*t$", 95 True, # is_regexp 96 ), summary) 97 98 self.expect("frame variable foo.A", 99 substrs=['hello world']) 100 self.expect("frame variable foo.E", matching=False, 101 substrs=['hello world']) 102 self.expect("frame variable foo.B", 103 substrs=['hello world']) 104 self.expect("frame variable foo.F", 105 substrs=['hello world']) 106 new_category.SetEnabled(False) 107 self.expect("frame variable foo.A", matching=False, 108 substrs=['hello world']) 109 self.expect("frame variable foo.E", matching=False, 110 substrs=['hello world']) 111 self.expect("frame variable foo.B", matching=False, 112 substrs=['hello world']) 113 self.expect("frame variable foo.F", matching=False, 114 substrs=['hello world']) 115 self.dbg.DeleteCategory(new_category.GetName()) 116 self.expect("frame variable foo.A", matching=False, 117 substrs=['hello world']) 118 self.expect("frame variable foo.E", matching=False, 119 substrs=['hello world']) 120 self.expect("frame variable foo.B", matching=False, 121 substrs=['hello world']) 122 self.expect("frame variable foo.F", matching=False, 123 substrs=['hello world']) 124 125 filter = lldb.SBTypeFilter(0) 126 filter.AppendExpressionPath("A") 127 filter.AppendExpressionPath("D") 128 self.assertEqual( 129 filter.GetNumberOfExpressionPaths(), 2, 130 "filter with two items does not have two items") 131 132 category.AddTypeFilter(lldb.SBTypeNameSpecifier("JustAStruct"), filter) 133 self.expect("frame variable foo", 134 substrs=['A = 1', 'D = 6.28']) 135 self.expect("frame variable foo", matching=False, 136 substrs=['B = ', 'C = ', 'E = ', 'F = ']) 137 138 category.DeleteTypeFilter( 139 lldb.SBTypeNameSpecifier( 140 "JustAStruct", True)) 141 self.expect("frame variable foo", 142 substrs=['A = 1', 'D = 6.28']) 143 self.expect("frame variable foo", matching=False, 144 substrs=['B = ', 'C = ', 'E = ', 'F = ']) 145 146 category.DeleteTypeFilter( 147 lldb.SBTypeNameSpecifier( 148 "JustAStruct", False)) 149 self.expect("frame variable foo", 150 substrs=['A = 1', 'D = 6.28']) 151 self.expect("frame variable foo", matching=True, 152 substrs=['B = ', 'C = ', 'E = ', 'F = ']) 153 154 self.runCmd("command script import --allow-reload ./synth.py") 155 156 self.expect("frame variable foo", matching=False, 157 substrs=['X = 1']) 158 159 self.dbg.GetCategory("JASSynth").SetEnabled(True) 160 self.expect("frame variable foo", matching=True, 161 substrs=['X = 1']) 162 163 self.dbg.GetCategory("CCCSynth").SetEnabled(True) 164 self.expect( 165 "frame variable ccc", 166 matching=True, 167 substrs=[ 168 'CCC object with leading value (int) a = 111', 169 'a = 111', 170 'b = 222', 171 'c = 333']) 172 173 foo_var = self.dbg.GetSelectedTarget().GetProcess( 174 ).GetSelectedThread().GetSelectedFrame().FindVariable('foo') 175 self.assertTrue(foo_var.IsValid(), 'could not find foo') 176 self.assertTrue( 177 foo_var.GetDeclaration().IsValid(), 178 'foo declaration is invalid') 179 180 self.assertEqual( 181 foo_var.GetNumChildren(), 2, 182 'synthetic value has wrong number of child items (synth)') 183 self.assertEqual( 184 foo_var.GetChildMemberWithName('X').GetValueAsUnsigned(), 1, 185 'foo_synth.X has wrong value (synth)') 186 self.assertFalse( 187 foo_var.GetChildMemberWithName('B').IsValid(), 188 'foo_synth.B is valid but should not (synth)') 189 190 self.dbg.GetCategory("JASSynth").SetEnabled(False) 191 foo_var = self.dbg.GetSelectedTarget().GetProcess( 192 ).GetSelectedThread().GetSelectedFrame().FindVariable('foo') 193 self.assertTrue(foo_var.IsValid(), 'could not find foo') 194 195 self.assertFalse( 196 foo_var.GetNumChildren() == 2, 197 'still seeing synthetic value') 198 199 filter = lldb.SBTypeFilter(0) 200 filter.AppendExpressionPath("A") 201 filter.AppendExpressionPath("D") 202 category.AddTypeFilter(lldb.SBTypeNameSpecifier("JustAStruct"), filter) 203 self.expect("frame variable foo", 204 substrs=['A = 1', 'D = 6.28']) 205 206 foo_var = self.dbg.GetSelectedTarget().GetProcess( 207 ).GetSelectedThread().GetSelectedFrame().FindVariable('foo') 208 self.assertTrue(foo_var.IsValid(), 'could not find foo') 209 210 self.assertEqual( 211 foo_var.GetNumChildren(), 2, 212 'synthetic value has wrong number of child items (filter)') 213 self.assertEqual( 214 foo_var.GetChildMemberWithName('X').GetValueAsUnsigned(), 0, 215 'foo_synth.X has wrong value (filter)') 216 self.assertEqual( 217 foo_var.GetChildMemberWithName('A').GetValueAsUnsigned(), 1, 218 'foo_synth.A has wrong value (filter)') 219 220 self.assertTrue(filter.ReplaceExpressionPathAtIndex( 221 0, "C"), "failed to replace an expression path in filter") 222 self.expect("frame variable foo", 223 substrs=['A = 1', 'D = 6.28']) 224 category.AddTypeFilter(lldb.SBTypeNameSpecifier("JustAStruct"), filter) 225 self.expect("frame variable foo", 226 substrs=["C = 'e'", 'D = 6.28']) 227 category.AddTypeFilter(lldb.SBTypeNameSpecifier("FooType"), filter) 228 filter.ReplaceExpressionPathAtIndex(1, "F") 229 self.expect("frame variable foo", 230 substrs=["C = 'e'", 'D = 6.28']) 231 category.AddTypeFilter(lldb.SBTypeNameSpecifier("JustAStruct"), filter) 232 self.expect("frame variable foo", 233 substrs=["C = 'e'", 'F = 0']) 234 self.expect("frame variable bar", 235 substrs=["C = 'e'", 'D = 6.28']) 236 237 foo_var = self.dbg.GetSelectedTarget().GetProcess( 238 ).GetSelectedThread().GetSelectedFrame().FindVariable('foo') 239 self.assertTrue(foo_var.IsValid(), 'could not find foo') 240 self.assertEqual( 241 foo_var.GetChildMemberWithName('C').GetValueAsUnsigned(), ord('e'), 242 'foo_synth.C has wrong value (filter)') 243 244 chosen = self.dbg.GetFilterForType( 245 lldb.SBTypeNameSpecifier("JustAStruct")) 246 self.assertEqual( 247 chosen.count, 2, 248 "wrong filter found for JustAStruct") 249 self.assertEqual( 250 chosen.GetExpressionPathAtIndex(0), 'C', 251 "wrong item at index 0 for JustAStruct") 252 self.assertEqual( 253 chosen.GetExpressionPathAtIndex(1), 'F', 254 "wrong item at index 1 for JustAStruct") 255 256 self.assertFalse( 257 category.DeleteTypeFilter( 258 lldb.SBTypeNameSpecifier("NoSuchType")), 259 "deleting a non-existing filter worked") 260 self.assertFalse( 261 category.DeleteTypeSummary( 262 lldb.SBTypeNameSpecifier("NoSuchType")), 263 "deleting a non-existing summary worked") 264 self.assertFalse( 265 category.DeleteTypeFormat( 266 lldb.SBTypeNameSpecifier("NoSuchType")), 267 "deleting a non-existing format worked") 268 self.assertFalse( 269 category.DeleteTypeSynthetic( 270 lldb.SBTypeNameSpecifier("NoSuchType")), 271 "deleting a non-existing synthetic worked") 272 273 self.assertFalse( 274 category.DeleteTypeFilter( 275 lldb.SBTypeNameSpecifier("")), 276 "deleting a filter for '' worked") 277 self.assertFalse( 278 category.DeleteTypeSummary( 279 lldb.SBTypeNameSpecifier("")), 280 "deleting a summary for '' worked") 281 self.assertFalse( 282 category.DeleteTypeFormat( 283 lldb.SBTypeNameSpecifier("")), 284 "deleting a format for '' worked") 285 self.assertFalse( 286 category.DeleteTypeSynthetic( 287 lldb.SBTypeNameSpecifier("")), 288 "deleting a synthetic for '' worked") 289 290 try: 291 self.assertFalse( 292 category.AddTypeSummary( 293 lldb.SBTypeNameSpecifier("NoneSuchType"), 294 None), 295 "adding a summary valued None worked") 296 except: 297 pass 298 else: 299 self.assertFalse(True, "adding a summary valued None worked") 300 301 try: 302 self.assertFalse( 303 category.AddTypeFilter( 304 lldb.SBTypeNameSpecifier("NoneSuchType"), 305 None), 306 "adding a filter valued None worked") 307 except: 308 pass 309 else: 310 self.assertFalse(True, "adding a filter valued None worked") 311 312 try: 313 self.assertFalse( 314 category.AddTypeSynthetic( 315 lldb.SBTypeNameSpecifier("NoneSuchType"), 316 None), 317 "adding a synthetic valued None worked") 318 except: 319 pass 320 else: 321 self.assertFalse(True, "adding a synthetic valued None worked") 322 323 try: 324 self.assertFalse( 325 category.AddTypeFormat( 326 lldb.SBTypeNameSpecifier("NoneSuchType"), 327 None), 328 "adding a format valued None worked") 329 except: 330 pass 331 else: 332 self.assertFalse(True, "adding a format valued None worked") 333 334 self.assertFalse( 335 category.AddTypeSummary( 336 lldb.SBTypeNameSpecifier("EmptySuchType"), 337 lldb.SBTypeSummary()), 338 "adding a summary without value worked") 339 self.assertFalse( 340 category.AddTypeFilter( 341 lldb.SBTypeNameSpecifier("EmptySuchType"), 342 lldb.SBTypeFilter()), 343 "adding a filter without value worked") 344 self.assertFalse( 345 category.AddTypeSynthetic( 346 lldb.SBTypeNameSpecifier("EmptySuchType"), 347 lldb.SBTypeSynthetic()), 348 "adding a synthetic without value worked") 349 self.assertFalse( 350 category.AddTypeFormat( 351 lldb.SBTypeNameSpecifier("EmptySuchType"), 352 lldb.SBTypeFormat()), 353 "adding a format without value worked") 354 355 self.assertFalse( 356 category.AddTypeSummary( 357 lldb.SBTypeNameSpecifier(""), 358 lldb.SBTypeSummary.CreateWithSummaryString("")), 359 "adding a summary for an invalid type worked") 360 self.assertFalse( 361 category.AddTypeFilter( 362 lldb.SBTypeNameSpecifier(""), 363 lldb.SBTypeFilter(0)), 364 "adding a filter for an invalid type worked") 365 self.assertFalse( 366 category.AddTypeSynthetic( 367 lldb.SBTypeNameSpecifier(""), 368 lldb.SBTypeSynthetic.CreateWithClassName("")), 369 "adding a synthetic for an invalid type worked") 370 self.assertFalse( 371 category.AddTypeFormat( 372 lldb.SBTypeNameSpecifier(""), 373 lldb.SBTypeFormat( 374 lldb.eFormatHex)), 375 "adding a format for an invalid type worked") 376 377 new_category = self.dbg.CreateCategory("newbar") 378 new_category.AddTypeSummary( 379 lldb.SBTypeNameSpecifier("JustAStruct"), 380 lldb.SBTypeSummary.CreateWithScriptCode("return 'hello scripted world';")) 381 self.expect("frame variable foo", matching=False, 382 substrs=['hello scripted world']) 383 new_category.SetEnabled(True) 384 self.expect("frame variable foo", matching=True, 385 substrs=['hello scripted world']) 386 387 self.expect("frame variable foo_ptr", matching=True, 388 substrs=['hello scripted world']) 389 new_category.AddTypeSummary( 390 lldb.SBTypeNameSpecifier("JustAStruct"), 391 lldb.SBTypeSummary.CreateWithScriptCode( 392 "return 'hello scripted world';", 393 lldb.eTypeOptionSkipPointers)) 394 self.expect("frame variable foo", matching=True, 395 substrs=['hello scripted world']) 396 397 frame = self.dbg.GetSelectedTarget().GetProcess( 398 ).GetSelectedThread().GetSelectedFrame() 399 foo_ptr = frame.FindVariable("foo_ptr") 400 summary = foo_ptr.GetTypeSummary() 401 402 self.assertFalse( 403 summary.IsValid(), 404 "summary found for foo* when none was planned") 405 406 self.expect("frame variable foo_ptr", matching=False, 407 substrs=['hello scripted world']) 408 409 new_category.AddTypeSummary( 410 lldb.SBTypeNameSpecifier("JustAStruct"), 411 lldb.SBTypeSummary.CreateWithSummaryString( 412 "hello static world", 413 lldb.eTypeOptionNone)) 414 415 summary = foo_ptr.GetTypeSummary() 416 417 self.assertTrue( 418 summary.IsValid(), 419 "no summary found for foo* when one was in place") 420 self.assertEqual( 421 summary.GetData(), "hello static world", 422 "wrong summary found for foo*") 423 424 self.expect("frame variable e1", substrs=["I am an empty Empty1 {}"]) 425 self.expect("frame variable e2", substrs=["I am an empty Empty2"]) 426 self.expect( 427 "frame variable e2", 428 substrs=["I am an empty Empty2 {}"], 429 matching=False) 430 431 self.assertTrue( 432 self.dbg.GetCategory( 433 lldb.eLanguageTypeObjC) is not None, 434 "ObjC category is None") 435 436 def test_force_synth_off(self): 437 """Test that one can have the public API return non-synthetic SBValues if desired""" 438 self.build(dictionary={'EXE': 'no_synth'}) 439 self.setTearDownCleanup() 440 441 self.runCmd("file " + self.getBuildArtifact("no_synth"), 442 CURRENT_EXECUTABLE_SET) 443 444 lldbutil.run_break_set_by_file_and_line( 445 self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True) 446 447 self.runCmd("run", RUN_SUCCEEDED) 448 449 # The stop reason of the thread should be breakpoint. 450 self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, 451 substrs=['stopped', 452 'stop reason = breakpoint']) 453 454 # This is the function to remove the custom formats in order to have a 455 # clean slate for the next test case. 456 def cleanup(): 457 self.runCmd('type format clear', check=False) 458 self.runCmd('type summary clear', check=False) 459 self.runCmd('type filter clear', check=False) 460 self.runCmd('type synthetic clear', check=False) 461 self.runCmd('type category delete foobar', check=False) 462 self.runCmd('type category delete JASSynth', check=False) 463 self.runCmd('type category delete newbar', check=False) 464 self.runCmd('settings set target.enable-synthetic-value true') 465 466 # Execute the cleanup function during test case tear down. 467 self.addTearDownHook(cleanup) 468 469 frame = self.dbg.GetSelectedTarget().GetProcess( 470 ).GetSelectedThread().GetSelectedFrame() 471 int_vector = frame.FindVariable("int_vector") 472 if self.TraceOn(): 473 print(int_vector) 474 self.assertEqual( 475 int_vector.GetNumChildren(), 0, 476 'synthetic vector is empty') 477 478 self.runCmd('settings set target.enable-synthetic-value false') 479 frame = self.dbg.GetSelectedTarget().GetProcess( 480 ).GetSelectedThread().GetSelectedFrame() 481 int_vector = frame.FindVariable("int_vector") 482 if self.TraceOn(): 483 print(int_vector) 484 self.assertFalse( 485 int_vector.GetNumChildren() == 0, 486 '"physical" vector is not empty') 487 488 self.runCmd('settings set target.enable-synthetic-value true') 489 frame = self.dbg.GetSelectedTarget().GetProcess( 490 ).GetSelectedThread().GetSelectedFrame() 491 int_vector = frame.FindVariable("int_vector") 492 if self.TraceOn(): 493 print(int_vector) 494 self.assertEqual( 495 int_vector.GetNumChildren(), 0, 496 'synthetic vector is still empty') 497