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