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