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