1""" 2Test lldb data formatter subsystem. 3""" 4 5 6import lldb 7from lldbsuite.test.decorators import * 8from lldbsuite.test.lldbtest import * 9from lldbsuite.test import lldbutil 10 11 12class CppDataFormatterTestCase(TestBase): 13 def setUp(self): 14 # Call super's setUp(). 15 TestBase.setUp(self) 16 # Find the line number to break at. 17 self.line = line_number("main.cpp", "// Set break point at this line.") 18 19 def test_with_run_command(self): 20 """Test that that file and class static variables display correctly.""" 21 self.build() 22 self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) 23 24 lldbutil.run_break_set_by_file_and_line( 25 self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True 26 ) 27 28 self.runCmd("run", RUN_SUCCEEDED) 29 30 # The stop reason of the thread should be breakpoint. 31 self.expect( 32 "thread list", 33 STOPPED_DUE_TO_BREAKPOINT, 34 substrs=["stopped", "stop reason = breakpoint"], 35 ) 36 37 self.expect( 38 "frame variable", 39 substrs=["(Speed) SPILookHex = 5.55"], # Speed by default is 5.55. 40 ) 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 48 # Execute the cleanup function during test case tear down. 49 self.addTearDownHook(cleanup) 50 51 self.runCmd("type format add -C yes -f x Speed BitField") 52 self.runCmd("type format add -C no -f c RealNumber") 53 self.runCmd("type format add -C no -f x Type2") 54 self.runCmd("type format add -C yes -f c Type1") 55 56 # The type format list should show our custom formats. 57 self.expect( 58 "type format list", 59 substrs=["Speed", "BitField", "RealNumber", "Type2", "Type1"], 60 ) 61 62 self.expect( 63 "frame variable", 64 patterns=[ 65 "\(Speed\) SPILookHex = 0x[0-9a-f]+" # Speed should look hex-ish now. 66 ], 67 ) 68 69 # gcc4.2 on Mac OS X skips typedef chains in the DWARF output 70 if self.getCompiler() in ["clang"]: 71 self.expect( 72 "frame variable", 73 patterns=[ 74 "\(SignalMask\) SMILookHex = 0x[0-9a-f]+" # SignalMask should look hex-ish now. 75 ], 76 ) 77 self.expect( 78 "frame variable", 79 matching=False, 80 patterns=[ 81 "\(Type4\) T4ILookChar = 0x[0-9a-f]+" # Type4 should NOT look hex-ish now. 82 ], 83 ) 84 85 # Now let's delete the 'Speed' custom format. 86 self.runCmd("type format delete Speed") 87 88 # The type format list should not show 'Speed' at this point. 89 self.expect("type format list", matching=False, substrs=["Speed"]) 90 91 # Delete type format for 'Speed', we should expect an error message. 92 self.expect( 93 "type format delete Speed", 94 error=True, 95 substrs=["no custom formatter for Speed"], 96 ) 97 98 self.runCmd( 99 'type summary add --summary-string "arr = ${var%s}" -x "char\\[[0-9]+\\]" -v' 100 ) 101 102 self.expect("frame variable strarr", substrs=['arr = "Hello world!"']) 103 104 self.runCmd("type summary clear") 105 106 self.runCmd('type summary add --summary-string "ptr = ${var%s}" "char *" -v') 107 108 self.expect("frame variable strptr", substrs=['ptr = "Hello world!"']) 109 110 self.runCmd( 111 'type summary add --summary-string "arr = ${var%s}" -x "char\\[[0-9]+\\]" -v' 112 ) 113 114 self.expect("frame variable strarr", substrs=['arr = "Hello world!']) 115 116 # check that rdar://problem/10011145 (Standard summary format for 117 # char[] doesn't work as the result of "expr".) is solved 118 self.expect("expression strarr", substrs=['arr = "Hello world!']) 119 120 self.expect("frame variable strptr", substrs=['ptr = "Hello world!"']) 121 122 self.expect("expression strptr", substrs=['ptr = "Hello world!"']) 123 124 self.expect( 125 'expression (char*)"1234567890123456789012345678901234567890123456789012345678901234ABC"', 126 substrs=[ 127 "(char *) $", 128 " = ptr = ", 129 '"1234567890123456789012345678901234567890123456789012345678901234ABC"', 130 ], 131 ) 132 133 self.runCmd("type summary add -c TestPoint") 134 135 self.expect("frame variable iAmSomewhere", substrs=["x = 4", "y = 6"]) 136 137 self.expect("type summary list", substrs=["TestPoint", "one-line"]) 138 139 self.runCmd('type summary add --summary-string "y=${var.y%x}" TestPoint') 140 141 self.expect("frame variable iAmSomewhere", substrs=["y=0x"]) 142 143 self.runCmd( 144 'type summary add --summary-string "y=${var.y},x=${var.x}" TestPoint' 145 ) 146 147 self.expect("frame variable iAmSomewhere", substrs=["y=6", "x=4"]) 148 149 self.runCmd('type summary add --summary-string "hello" TestPoint -e') 150 151 self.expect("type summary list", substrs=["TestPoint", "show children"]) 152 153 self.expect("frame variable iAmSomewhere", substrs=["hello", "x = 4", "}"]) 154 155 self.runCmd( 156 'type summary add --summary-string "Sign: ${var[31]%B} Exponent: ${var[23-30]%x} Mantissa: ${var[0-22]%u}" ShowMyGuts' 157 ) 158 159 self.expect( 160 "frame variable cool_pointer->floating", 161 substrs=["Sign: true", "Exponent: 0x", "80"], 162 ) 163 164 self.runCmd('type summary add --summary-string "a test" i_am_cool') 165 166 self.expect("frame variable cool_pointer", substrs=["a test"]) 167 168 self.runCmd( 169 'type summary add --summary-string "a test" i_am_cool --skip-pointers' 170 ) 171 172 self.expect("frame variable cool_pointer", substrs=["a test"], matching=False) 173 174 self.runCmd('type summary add --summary-string "${var[1-3]}" "int[5]"') 175 176 self.expect("frame variable int_array", substrs=["2", "3", "4"]) 177 178 self.runCmd("type summary clear") 179 180 self.runCmd( 181 'type summary add --summary-string "${var[0-2].integer}" "i_am_cool *"' 182 ) 183 self.runCmd( 184 'type summary add --summary-string "${var[2-4].integer}" "i_am_cool[5]"' 185 ) 186 187 self.expect("frame variable cool_array", substrs=["1,1,6"]) 188 189 self.expect("frame variable cool_pointer", substrs=["3,0,0"]) 190 191 # test special symbols for formatting variables into summaries 192 self.runCmd( 193 'type summary add --summary-string "cool object @ ${var%L}" i_am_cool' 194 ) 195 self.runCmd('type summary delete "i_am_cool[5]"') 196 197 # this test might fail if the compiler tries to store 198 # these values into registers.. hopefully this is not 199 # going to be the case 200 self.expect( 201 "frame variable cool_array", 202 substrs=[ 203 "[0] = cool object @ 0x", 204 "[1] = cool object @ 0x", 205 "[2] = cool object @ 0x", 206 "[3] = cool object @ 0x", 207 "[4] = cool object @ 0x", 208 ], 209 ) 210 211 # test getting similar output by exploiting ${var} = 'type @ location' 212 # for aggregates 213 self.runCmd('type summary add --summary-string "${var}" i_am_cool') 214 215 # this test might fail if the compiler tries to store 216 # these values into registers.. hopefully this is not 217 # going to be the case 218 self.expect( 219 "frame variable cool_array", 220 substrs=[ 221 "[0] = i_am_cool @ 0x", 222 "[1] = i_am_cool @ 0x", 223 "[2] = i_am_cool @ 0x", 224 "[3] = i_am_cool @ 0x", 225 "[4] = i_am_cool @ 0x", 226 ], 227 ) 228 229 # test getting same output by exploiting %T and %L together for 230 # aggregates 231 self.runCmd('type summary add --summary-string "${var%T} @ ${var%L}" i_am_cool') 232 233 # this test might fail if the compiler tries to store 234 # these values into registers.. hopefully this is not 235 # going to be the case 236 self.expect( 237 "frame variable cool_array", 238 substrs=[ 239 "[0] = i_am_cool @ 0x", 240 "[1] = i_am_cool @ 0x", 241 "[2] = i_am_cool @ 0x", 242 "[3] = i_am_cool @ 0x", 243 "[4] = i_am_cool @ 0x", 244 ], 245 ) 246 247 self.runCmd('type summary add --summary-string "goofy" i_am_cool') 248 self.runCmd( 249 'type summary add --summary-string "${var.second_cool%S}" i_am_cooler' 250 ) 251 252 self.expect( 253 "frame variable the_coolest_guy", 254 substrs=["(i_am_cooler) the_coolest_guy = goofy"], 255 ) 256 257 # check that unwanted type specifiers are removed 258 self.runCmd("type summary delete i_am_cool") 259 self.runCmd('type summary add --summary-string "goofy" "class i_am_cool"') 260 self.expect( 261 "frame variable the_coolest_guy", 262 substrs=["(i_am_cooler) the_coolest_guy = goofy"], 263 ) 264 265 self.runCmd("type summary delete i_am_cool") 266 self.runCmd('type summary add --summary-string "goofy" "enum i_am_cool"') 267 self.expect( 268 "frame variable the_coolest_guy", 269 substrs=["(i_am_cooler) the_coolest_guy = goofy"], 270 ) 271 272 self.runCmd("type summary delete i_am_cool") 273 self.runCmd('type summary add --summary-string "goofy" "struct i_am_cool"') 274 self.expect( 275 "frame variable the_coolest_guy", 276 substrs=["(i_am_cooler) the_coolest_guy = goofy"], 277 ) 278 279 # many spaces, but we still do the right thing 280 self.runCmd("type summary delete i_am_cool") 281 self.runCmd('type summary add --summary-string "goofy" "union i_am_cool"') 282 self.expect( 283 "frame variable the_coolest_guy", 284 substrs=["(i_am_cooler) the_coolest_guy = goofy"], 285 ) 286 287 # but that not *every* specifier is removed 288 self.runCmd("type summary delete i_am_cool") 289 self.runCmd('type summary add --summary-string "goofy" "wrong i_am_cool"') 290 self.expect( 291 "frame variable the_coolest_guy", 292 matching=False, 293 substrs=["(i_am_cooler) the_coolest_guy = goofy"], 294 ) 295 296 # check that formats are not sticking since that is the behavior we 297 # want 298 self.expect( 299 "frame variable iAmInt --format hex", substrs=["(int) iAmInt = 0x00000001"] 300 ) 301 self.expect( 302 "frame variable iAmInt", 303 matching=False, 304 substrs=["(int) iAmInt = 0x00000001"], 305 ) 306 self.expect("frame variable iAmInt", substrs=["(int) iAmInt = 1"]) 307 308 @skipIfWindows 309 def test_mem_func_ptr_formats(self): 310 self.build() 311 312 lldbutil.run_to_source_breakpoint( 313 self, "Break in has_local_mem_func_pointers", lldb.SBFileSpec("main.cpp") 314 ) 315 316 self.expect("frame variable member_ptr", patterns=["member_ptr = 0x[0-9a-z]+"]) 317 self.expect( 318 "frame variable member_func_ptr", 319 patterns=["member_func_ptr = 0x[0-9a-z]+"], 320 substrs=["(a.out`IUseCharStar::member_func(int) at main.cpp:61)"], 321 ) 322 self.expect( 323 "frame variable ref_to_member_func_ptr", 324 patterns=["ref_to_member_func_ptr = 0x[0-9a-z]+"], 325 substrs=["(a.out`IUseCharStar::member_func(int) at main.cpp:61)"], 326 ) 327 self.expect( 328 "frame variable virt_member_func_ptr", 329 patterns=["virt_member_func_ptr = 0x[0-9a-z]+$"], 330 ) 331