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