1 """ 2 Test lldb data formatter subsystem. 3 """ 4 5 import os, time 6 import unittest2 7 import lldb 8 from lldbtest import * 9 import lldbutil 10 11 class CategoriesDataFormatterTestCase(TestBase): 12 13 mydir = os.path.join("functionalities", "data-formatter", "data-formatter-categories") 14 15 @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") 16 @dsym_test 17 def test_with_dsym_and_run_command(self): 18 """Test data formatter commands.""" 19 self.buildDsym() 20 self.data_formatter_commands() 21 22 @dwarf_test 23 def test_with_dwarf_and_run_command(self): 24 """Test data formatter commands.""" 25 self.buildDwarf() 26 self.data_formatter_commands() 27 28 def setUp(self): 29 # Call super's setUp(). 30 TestBase.setUp(self) 31 # Find the line number to break at. 32 self.line = line_number('main.cpp', '// Set break point at this line.') 33 34 def data_formatter_commands(self): 35 """Test that that file and class static variables display correctly.""" 36 self.runCmd("file a.out", CURRENT_EXECUTABLE_SET) 37 38 lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True) 39 40 self.runCmd("run", RUN_SUCCEEDED) 41 42 # The stop reason of the thread should be breakpoint. 43 self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, 44 substrs = ['stopped', 45 'stop reason = breakpoint']) 46 47 # This is the function to remove the custom formats in order to have a 48 # clean slate for the next test case (most of these categories do not 49 # exist anymore, but we just make sure we delete all of them) 50 def cleanup(): 51 self.runCmd('type format clear', check=False) 52 self.runCmd('type summary clear', check=False) 53 self.runCmd('type category delete Category1', check=False) 54 self.runCmd('type category delete Category2', check=False) 55 self.runCmd('type category delete NewCategory', check=False) 56 self.runCmd("type category delete CircleCategory", check=False) 57 self.runCmd("type category delete RectangleStarCategory", check=False) 58 self.runCmd("type category delete BaseCategory", check=False) 59 60 61 # Execute the cleanup function during test case tear down. 62 self.addTearDownHook(cleanup) 63 64 # Add a summary to a new category and check that it works 65 self.runCmd("type summary add Rectangle --summary-string \"ARectangle\" -w NewCategory") 66 67 self.expect("frame variable r1 r2 r3", matching=False, 68 substrs = ['r1 = ARectangle', 69 'r2 = ARectangle', 70 'r3 = ARectangle']) 71 72 self.runCmd("type category enable NewCategory") 73 74 self.expect("frame variable r1 r2 r3", matching=True, 75 substrs = ['r1 = ARectangle', 76 'r2 = ARectangle', 77 'r3 = ARectangle']) 78 79 # Disable the category and check that the old stuff is there 80 self.runCmd("type category disable NewCategory") 81 82 self.expect("frame variable r1 r2 r3", 83 substrs = ['r1 = {', 84 'r2 = {', 85 'r3 = {']) 86 87 # Re-enable the category and check that it works 88 self.runCmd("type category enable NewCategory") 89 90 self.expect("frame variable r1 r2 r3", 91 substrs = ['r1 = ARectangle', 92 'r2 = ARectangle', 93 'r3 = ARectangle']) 94 95 # Delete the category and the old stuff should be there 96 self.runCmd("type category delete NewCategory") 97 98 self.expect("frame variable r1 r2 r3", 99 substrs = ['r1 = {', 100 'r2 = {', 101 'r3 = {']) 102 103 # Add summaries to two different categories and check that we can switch 104 self.runCmd("type summary add --summary-string \"Width = ${var.w}, Height = ${var.h}\" Rectangle -w Category1") 105 self.runCmd("type summary add --python-script \"return 'Area = ' + str( int(valobj.GetChildMemberWithName('w').GetValue()) * int(valobj.GetChildMemberWithName('h').GetValue()) );\" Rectangle -w Category2") 106 107 # check that enable A B is the same as enable B enable A 108 self.runCmd("type category enable Category1 Category2") 109 110 self.expect("frame variable r1 r2 r3", 111 substrs = ['r1 = Width = ', 112 'r2 = Width = ', 113 'r3 = Width = ']) 114 115 self.runCmd("type category disable Category1") 116 117 self.expect("frame variable r1 r2 r3", 118 substrs = ['r1 = Area = ', 119 'r2 = Area = ', 120 'r3 = Area = ']) 121 122 # switch again 123 124 self.runCmd("type category enable Category1") 125 126 self.expect("frame variable r1 r2 r3", 127 substrs = ['r1 = Width = ', 128 'r2 = Width = ', 129 'r3 = Width = ']) 130 131 # Re-enable the category and show that the preference is persisted 132 self.runCmd("type category disable Category2") 133 self.runCmd("type category enable Category2") 134 135 self.expect("frame variable r1 r2 r3", 136 substrs = ['r1 = Area = ', 137 'r2 = Area = ', 138 'r3 = Area = ']) 139 140 # Now delete the favorite summary 141 self.runCmd("type summary delete Rectangle -w Category2") 142 143 self.expect("frame variable r1 r2 r3", 144 substrs = ['r1 = Width = ', 145 'r2 = Width = ', 146 'r3 = Width = ']) 147 148 # Delete the summary from the default category (that does not have it) 149 self.runCmd("type summary delete Rectangle", check=False) 150 151 self.expect("frame variable r1 r2 r3", 152 substrs = ['r1 = Width = ', 153 'r2 = Width = ', 154 'r3 = Width = ']) 155 156 # Now add another summary to another category and switch back and forth 157 self.runCmd("type category delete Category1 Category2") 158 159 self.runCmd("type summary add Rectangle --summary-string \"Category1\" -w Category1") 160 self.runCmd("type summary add Rectangle --summary-string \"Category2\" -w Category2") 161 162 self.runCmd("type category enable Category2") 163 self.runCmd("type category enable Category1") 164 165 self.expect("frame variable r1 r2 r3", 166 substrs = ['r1 = Category1', 167 'r2 = Category1', 168 'r3 = Category1']) 169 170 self.runCmd("type category disable Category1") 171 172 self.expect("frame variable r1 r2 r3", 173 substrs = ['r1 = Category2', 174 'r2 = Category2', 175 'r3 = Category2']) 176 177 # Check that re-enabling an enabled category works 178 self.runCmd("type category enable Category1") 179 180 self.expect("frame variable r1 r2 r3", 181 substrs = ['r1 = Category1', 182 'r2 = Category1', 183 'r3 = Category1']) 184 185 self.runCmd("type category delete Category1") 186 self.runCmd("type category delete Category2") 187 188 self.expect("frame variable r1 r2 r3", 189 substrs = ['r1 = {', 190 'r2 = {', 191 'r3 = {']) 192 193 # Check that multiple summaries can go into one category 194 self.runCmd("type summary add --summary-string \"Width = ${var.w}, Height = ${var.h}\" Rectangle -w Category1") 195 self.runCmd("type summary add --summary-string \"Radius = ${var.r}\" Circle -w Category1") 196 197 self.runCmd("type category enable Category1") 198 199 self.expect("frame variable r1 r2 r3", 200 substrs = ['r1 = Width = ', 201 'r2 = Width = ', 202 'r3 = Width = ']) 203 204 self.expect("frame variable c1 c2 c3", 205 substrs = ['c1 = Radius = ', 206 'c2 = Radius = ', 207 'c3 = Radius = ']) 208 209 self.runCmd("type summary delete Circle -w Category1") 210 211 self.expect("frame variable c1 c2 c3", 212 substrs = ['c1 = {', 213 'c2 = {', 214 'c3 = {']) 215 216 # Add a regex based summary to a category 217 self.runCmd("type summary add --summary-string \"Radius = ${var.r}\" -x Circle -w Category1") 218 219 self.expect("frame variable r1 r2 r3", 220 substrs = ['r1 = Width = ', 221 'r2 = Width = ', 222 'r3 = Width = ']) 223 224 self.expect("frame variable c1 c2 c3", 225 substrs = ['c1 = Radius = ', 226 'c2 = Radius = ', 227 'c3 = Radius = ']) 228 229 # Delete it 230 self.runCmd("type summary delete Circle -w Category1") 231 232 self.expect("frame variable c1 c2 c3", 233 substrs = ['c1 = {', 234 'c2 = {', 235 'c3 = {']) 236 237 # Change a summary inside a category and check that the change is reflected 238 self.runCmd("type summary add Circle -w Category1 --summary-string \"summary1\"") 239 240 self.expect("frame variable c1 c2 c3", 241 substrs = ['c1 = summary1', 242 'c2 = summary1', 243 'c3 = summary1']) 244 245 self.runCmd("type summary add Circle -w Category1 --summary-string \"summary2\"") 246 247 self.expect("frame variable c1 c2 c3", 248 substrs = ['c1 = summary2', 249 'c2 = summary2', 250 'c3 = summary2']) 251 252 # Check that our order of priority works. Start by clearing categories 253 self.runCmd("type category delete Category1") 254 255 self.runCmd("type summary add Shape -w BaseCategory --summary-string \"AShape\"") 256 self.runCmd("type category enable BaseCategory") 257 258 self.expect("print (Shape*)&c1", 259 substrs = ['AShape']) 260 self.expect("print (Shape*)&r1", 261 substrs = ['AShape']) 262 self.expect("print (Shape*)c_ptr", 263 substrs = ['AShape']) 264 self.expect("print (Shape*)r_ptr", 265 substrs = ['AShape']) 266 267 self.runCmd("type summary add Circle -w CircleCategory --summary-string \"ACircle\"") 268 self.runCmd("type summary add Rectangle -w RectangleCategory --summary-string \"ARectangle\"") 269 self.runCmd("type category enable CircleCategory") 270 271 self.expect("frame variable c1", 272 substrs = ['ACircle']) 273 self.expect("frame variable c_ptr", 274 substrs = ['ACircle']) 275 276 self.runCmd("type summary add \"Rectangle *\" -w RectangleStarCategory --summary-string \"ARectangleStar\"") 277 self.runCmd("type category enable RectangleStarCategory") 278 279 self.expect("frame variable c1 r1 c_ptr r_ptr", 280 substrs = ['ACircle', 281 'ARectangleStar']) 282 283 self.runCmd("type category enable RectangleCategory") 284 285 self.expect("frame variable c1 r1 c_ptr r_ptr", 286 substrs = ['ACircle', 287 'ACircle', 288 'ARectangle']) 289 290 # Check that abruptly deleting an enabled category does not crash us 291 self.runCmd("type category delete RectangleCategory") 292 293 self.expect("frame variable c1 r1 c_ptr r_ptr", 294 substrs = ['ACircle', 295 '(Rectangle) r1 = {', 'w = 5', 'h = 6', 296 'ACircle', 297 'ARectangleStar']) 298 299 # check that list commands work 300 self.expect("type category list", 301 substrs = ['RectangleStarCategory is enabled']) 302 303 self.expect("type summary list", 304 substrs = ['ARectangleStar']) 305 306 # Disable a category and check that it fallsback 307 self.runCmd("type category disable CircleCategory") 308 309 # check that list commands work 310 self.expect("type category list", 311 substrs = ['CircleCategory is not enabled']) 312 313 self.expect("frame variable c1 r_ptr", 314 substrs = ['AShape', 315 'ARectangleStar']) 316 317 # check that filters work into categories 318 self.runCmd("type filter add Rectangle --child w --category RectangleCategory") 319 self.runCmd("type category enable RectangleCategory") 320 self.runCmd("type summary add Rectangle --summary-string \" \" -e --category RectangleCategory") 321 self.expect('frame variable r2', 322 substrs = ['w = 9']) 323 self.runCmd("type summary add Rectangle --summary-string \" \" -e") 324 self.expect('frame variable r2', matching=False, 325 substrs = ['h = 16']) 326 327 # Now delete all categories 328 self.runCmd("type category delete CircleCategory RectangleStarCategory BaseCategory RectangleCategory") 329 330 # last of all, check that a deleted category with filter does not blow us up 331 self.expect('frame variable r2', 332 substrs = ['w = 9', 333 'h = 16']) 334 335 if __name__ == '__main__': 336 import atexit 337 lldb.SBDebugger.Initialize() 338 atexit.register(lambda: lldb.SBDebugger.Terminate()) 339 unittest2.main() 340