1""" 2Test lldb data formatter callback-based matching. 3""" 4 5import lldb 6from lldbsuite.test.decorators import * 7from lldbsuite.test.lldbtest import * 8from lldbsuite.test import lldbutil 9 10 11class PythonSynthDataFormatterTestCase(TestBase): 12 def setUp(self): 13 # Call super's setUp(). 14 TestBase.setUp(self) 15 # Find the line number to break at. 16 self.line = line_number("main.cpp", "// Set break point at this line.") 17 18 def test_callback_matchers_api_registration(self): 19 """Test data formatter commands.""" 20 self.build() 21 22 _, process, thread, _ = lldbutil.run_to_line_breakpoint( 23 self, lldb.SBFileSpec("main.cpp"), self.line 24 ) 25 26 # Print derived without a formatter. 27 self.expect("frame variable derived", substrs=["x = 2222", "y = 3333"]) 28 29 # now set up a summary function that uses a python callback to match 30 # classes that derive from `Base`. 31 self.runCmd( 32 "command script import --allow-reload ./formatters_with_callback.py" 33 ) 34 self.runCmd( 35 "script formatters_with_callback.register_formatters(lldb.debugger)" 36 ) 37 38 # Now `derived` should use our callback summary + synthetic children. 39 self.expect( 40 "frame variable derived", 41 substrs=["hello from callback summary", "synthetic_child = 9999"], 42 ) 43 44 # But not other classes. 45 self.expect( 46 "frame variable base", 47 matching=False, 48 substrs=["hello from callback summary"], 49 ) 50 self.expect("frame variable base", substrs=["x = 1111"]) 51 52 self.expect( 53 "frame variable nd", matching=False, substrs=["hello from callback summary"] 54 ) 55 self.expect("frame variable nd", substrs=["z = 4444"]) 56 57 def test_callback_matchers_cli_registration(self): 58 """Test data formatter commands.""" 59 self.build() 60 61 _, process, thread, _ = lldbutil.run_to_line_breakpoint( 62 self, lldb.SBFileSpec("main.cpp"), self.line 63 ) 64 65 # Print derived without a formatter. 66 self.expect("frame variable derived", substrs=["x = 2222", "y = 3333"]) 67 68 # now set up a summary function that uses a python callback to match 69 # classes that derive from `Base`. 70 self.runCmd( 71 "command script import --allow-reload ./formatters_with_callback.py" 72 ) 73 self.runCmd( 74 "type summary add -e -s 'hello from callback summary' " 75 "--recognizer-function formatters_with_callback.derives_from_base" 76 ) 77 self.runCmd( 78 "type synth add -l formatters_with_callback.SynthProvider " 79 "--recognizer-function formatters_with_callback.derives_from_base" 80 ) 81 82 # Now `derived` should use our callback summary + synthetic children. 83 self.expect( 84 "frame variable derived", 85 substrs=["hello from callback summary", "synthetic_child = 9999"], 86 ) 87 88 # But not other classes. 89 self.expect( 90 "frame variable base", 91 matching=False, 92 substrs=["hello from callback summary"], 93 ) 94 self.expect("frame variable base", substrs=["x = 1111"]) 95 96 self.expect( 97 "frame variable nd", matching=False, substrs=["hello from callback summary"] 98 ) 99 self.expect("frame variable nd", substrs=["z = 4444"]) 100