1""" 2Test lldb data formatter subsystem. 3""" 4 5 6import lldb 7from lldbsuite.test.lldbtest import * 8import lldbsuite.test.lldbutil as lldbutil 9 10 11class ScriptDataFormatterTestCase(TestBase): 12 def test_with_run_command(self): 13 """Test data formatter commands.""" 14 self.build() 15 self.data_formatter_commands() 16 17 def setUp(self): 18 # Call super's setUp(). 19 TestBase.setUp(self) 20 # Find the line number to break at. 21 self.line = line_number("main.cpp", "// Set break point at this line.") 22 23 def data_formatter_commands(self): 24 """Test that that file and class static variables display correctly.""" 25 self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) 26 27 lldbutil.run_break_set_by_file_and_line( 28 self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True 29 ) 30 31 self.runCmd("run", RUN_SUCCEEDED) 32 33 # The stop reason of the thread should be breakpoint. 34 self.expect( 35 "thread list", 36 STOPPED_DUE_TO_BREAKPOINT, 37 substrs=["stopped", "stop reason = breakpoint"], 38 ) 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 46 # Execute the cleanup function during test case tear down. 47 self.addTearDownHook(cleanup) 48 49 # Set the script here to ease the formatting 50 script = "a = valobj.GetChildMemberWithName('integer'); a_val = a.GetValue(); str = 'Hello from Python, ' + a_val + ' time'; return str + ('!' if a_val == '1' else 's!');" 51 52 self.runCmd('type summary add i_am_cool --python-script "%s"' % script) 53 self.expect("type summary list i_am_cool", substrs=[script]) 54 55 self.expect("frame variable one", substrs=["Hello from Python", "1 time!"]) 56 57 self.expect("frame variable two", substrs=["Hello from Python", "4 times!"]) 58 59 self.runCmd("n") # skip ahead to make values change 60 61 self.expect( 62 "frame variable three", 63 substrs=["Hello from Python, 10 times!", "Hello from Python, 4 times!"], 64 ) 65 66 self.runCmd("n") # skip ahead to make values change 67 68 self.expect("frame variable two", substrs=["Hello from Python", "1 time!"]) 69 70 script = "a = valobj.GetChildMemberWithName('integer'); a_val = a.GetValue(); str = 'int says ' + a_val; return str;" 71 72 # Check that changes in the script are immediately reflected 73 self.runCmd('type summary add i_am_cool --python-script "%s"' % script) 74 75 self.expect("frame variable two", substrs=["int says 1"]) 76 77 self.expect("frame variable twoptr", substrs=["int says 1"]) 78 79 # Change the summary 80 self.runCmd( 81 'type summary add --summary-string "int says ${var.integer}, and float says ${var.floating}" i_am_cool' 82 ) 83 84 self.expect("frame variable two", substrs=["int says 1", "and float says 2.71"]) 85 # Try it for pointers 86 self.expect( 87 "frame variable twoptr", substrs=["int says 1", "and float says 2.71"] 88 ) 89 90 # Force a failure for pointers 91 self.runCmd('type summary add i_am_cool -p --python-script "%s"' % script) 92 93 self.expect( 94 "frame variable twoptr", matching=False, substrs=["and float says 2.71"] 95 ) 96 97 script = "return 'Python summary'" 98 99 self.runCmd( 100 'type summary add --name test_summary --python-script "%s"' % script 101 ) 102 103 # attach the Python named summary to someone 104 self.expect( 105 "frame variable one --summary test_summary", substrs=["Python summary"] 106 ) 107 108 # should not bind to the type 109 self.expect("frame variable two", matching=False, substrs=["Python summary"]) 110 111 # and should not stick to the variable 112 self.expect("frame variable one", matching=False, substrs=["Python summary"]) 113 114 self.runCmd('type summary add i_am_cool --summary-string "Text summary"') 115 116 # should be temporary only 117 self.expect("frame variable one", matching=False, substrs=["Python summary"]) 118 119 # use the type summary 120 self.expect("frame variable two", substrs=["Text summary"]) 121 122 self.runCmd("n") # skip ahead to make values change 123 124 # both should use the type summary now 125 self.expect("frame variable one", substrs=["Text summary"]) 126 127 self.expect("frame variable two", substrs=["Text summary"]) 128 129 # disable type summary for pointers, and make a Python regex summary 130 self.runCmd('type summary add i_am_cool -p --summary-string "Text summary"') 131 self.runCmd('type summary add -x cool --python-script "%s"' % script) 132 133 # variables should stick to the type summary 134 self.expect("frame variable one", substrs=["Text summary"]) 135 136 self.expect("frame variable two", substrs=["Text summary"]) 137 138 # array and pointer should match the Python one 139 self.expect("frame variable twoptr", substrs=["Python summary"]) 140 141 self.expect("frame variable array", substrs=["Python summary"]) 142 143 # return pointers to the type summary 144 self.runCmd('type summary add i_am_cool --summary-string "Text summary"') 145 146 self.expect("frame variable one", substrs=["Text summary"]) 147 148 self.expect("frame variable two", substrs=["Text summary"]) 149 150 self.expect("frame variable twoptr", substrs=["Text summary"]) 151 152 self.expect("frame variable array", substrs=["Python summary"]) 153