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