1""" 2Test lldb data formatter subsystem. 3""" 4 5import os, time 6import unittest2 7import lldb 8from lldbtest import * 9import lldbutil 10 11class CppDataFormatterTestCase(TestBase): 12 13 mydir = os.path.join("functionalities", "data-formatter", "data-formatter-cpp") 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 self.expect("frame variable", 48 substrs = ['(Speed) SPILookHex = 5.55' # Speed by default is 5.55. 49 ]); 50 51 # This is the function to remove the custom formats in order to have a 52 # clean slate for the next test case. 53 def cleanup(): 54 self.runCmd('type format clear', check=False) 55 self.runCmd('type summary clear', check=False) 56 57 # Execute the cleanup function during test case tear down. 58 self.addTearDownHook(cleanup) 59 60 self.runCmd("type format add -C yes -f x Speed BitField") 61 self.runCmd("type format add -C no -f c RealNumber") 62 self.runCmd("type format add -C no -f x Type2") 63 self.runCmd("type format add -C yes -f c Type1") 64 65 # The type format list should show our custom formats. 66 self.expect("type format list", 67 substrs = ['RealNumber', 68 'Speed', 69 'BitField', 70 'Type1', 71 'Type2']) 72 73 self.expect("frame variable", 74 patterns = ['\(Speed\) SPILookHex = 0x[0-9a-f]+' # Speed should look hex-ish now. 75 ]); 76 77 # gcc4.2 on Mac OS X skips typedef chains in the DWARF output 78 if self.getCompiler() in ['clang', 'llvm-gcc']: 79 self.expect("frame variable", 80 patterns = ['\(SignalMask\) SMILookHex = 0x[0-9a-f]+' # SignalMask should look hex-ish now. 81 ]); 82 self.expect("frame variable", matching=False, 83 patterns = ['\(Type4\) T4ILookChar = 0x[0-9a-f]+' # Type4 should NOT look hex-ish now. 84 ]); 85 86 # Now let's delete the 'Speed' custom format. 87 self.runCmd("type format delete Speed") 88 89 # The type format list should not show 'Speed' at this point. 90 self.expect("type format list", matching=False, 91 substrs = ['Speed']) 92 93 # Delete type format for 'Speed', we should expect an error message. 94 self.expect("type format delete Speed", error=True, 95 substrs = ['no custom format for Speed']) 96 97 self.runCmd("type summary add --summary-string \"arr = ${var%s}\" -x \"char \\[[0-9]+\\]\" -v") 98 99 self.expect("frame variable strarr", 100 substrs = ['arr = "Hello world!"']) 101 102 self.runCmd("type summary clear") 103 104 self.runCmd("type summary add --summary-string \"ptr = ${var%s}\" \"char *\" -v") 105 106 self.expect("frame variable strptr", 107 substrs = ['ptr = "Hello world!"']) 108 109 self.runCmd("type summary add --summary-string \"arr = ${var%s}\" -x \"char \\[[0-9]+\\]\" -v") 110 111 self.expect("frame variable strarr", 112 substrs = ['arr = "Hello world!']) 113 114 # check that rdar://problem/10011145 (Standard summary format for char[] doesn't work as the result of "expr".) is solved 115 self.expect("p strarr", 116 substrs = ['arr = "Hello world!']) 117 118 self.expect("frame variable strptr", 119 substrs = ['ptr = "Hello world!"']) 120 121 self.expect("p strptr", 122 substrs = ['ptr = "Hello world!"']) 123 124 self.expect("p (char*)\"1234567890123456789012345678901234567890123456789012345678901234ABC\"", 125 substrs = ['(char *) $', ' = ptr = ', ' "1234567890123456789012345678901234567890123456789012345678901234ABC"']) 126 127 self.runCmd("type summary add -c Point") 128 129 self.expect("frame variable iAmSomewhere", 130 substrs = ['x = 4', 131 'y = 6']) 132 133 self.expect("type summary list", 134 substrs = ['Point', 135 'one-line']) 136 137 self.runCmd("type summary add --summary-string \"y=${var.y%x}\" Point") 138 139 self.expect("frame variable iAmSomewhere", 140 substrs = ['y=0x']) 141 142 self.runCmd("type summary add --summary-string \"y=${var.y},x=${var.x}\" Point") 143 144 self.expect("frame variable iAmSomewhere", 145 substrs = ['y=6', 146 'x=4']) 147 148 self.runCmd("type summary add --summary-string \"hello\" Point -e") 149 150 self.expect("type summary list", 151 substrs = ['Point', 152 'show children']) 153 154 self.expect("frame variable iAmSomewhere", 155 substrs = ['hello', 156 'x = 4', 157 '}']) 158 159 self.runCmd("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("type summary add --summary-string \"a test\" i_am_cool --skip-pointers") 172 173 self.expect("frame variable cool_pointer", 174 substrs = ['a test'], 175 matching = False) 176 177 self.runCmd("type summary add --summary-string \"${var[1-3]}\" \"int [5]\"") 178 179 self.expect("frame variable int_array", 180 substrs = ['2', 181 '3', 182 '4']) 183 184 self.runCmd("type summary clear") 185 186 self.runCmd("type summary add --summary-string \"${var[0-2].integer}\" \"i_am_cool *\"") 187 self.runCmd("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("type summary add --summary-string \"cool object @ ${var%L}\" i_am_cool") 197 self.runCmd("type summary delete \"i_am_cool [5]\"") 198 199 # this test might fail if the compiler tries to store 200 # these values into registers.. hopefully this is not 201 # going to be the case 202 self.expect("frame variable cool_array", 203 substrs = ['[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 # test getting similar output by exploiting ${var} = 'type @ location' for aggregates 210 self.runCmd("type summary add --summary-string \"${var}\" i_am_cool") 211 212 # this test might fail if the compiler tries to store 213 # these values into registers.. hopefully this is not 214 # going to be the case 215 self.expect("frame variable cool_array", 216 substrs = ['[0] = i_am_cool @ 0x', 217 '[1] = i_am_cool @ 0x', 218 '[2] = i_am_cool @ 0x', 219 '[3] = i_am_cool @ 0x', 220 '[4] = i_am_cool @ 0x']) 221 222 223 # test getting same output by exploiting %T and %L together for aggregates 224 self.runCmd("type summary add --summary-string \"${var%T} @ ${var%L}\" i_am_cool") 225 226 # this test might fail if the compiler tries to store 227 # these values into registers.. hopefully this is not 228 # going to be the case 229 self.expect("frame variable cool_array", 230 substrs = ['[0] = i_am_cool @ 0x', 231 '[1] = i_am_cool @ 0x', 232 '[2] = i_am_cool @ 0x', 233 '[3] = i_am_cool @ 0x', 234 '[4] = i_am_cool @ 0x']) 235 236 self.runCmd("type summary add --summary-string \"goofy\" i_am_cool") 237 self.runCmd("type summary add --summary-string \"${var.second_cool%S}\" i_am_cooler") 238 239 self.expect("frame variable the_coolest_guy", 240 substrs = ['(i_am_cooler) the_coolest_guy = goofy']) 241 242 # check that unwanted type specifiers are removed 243 self.runCmd("type summary delete i_am_cool") 244 self.runCmd("type summary add --summary-string \"goofy\" \"class i_am_cool\"") 245 self.expect("frame variable the_coolest_guy", 246 substrs = ['(i_am_cooler) the_coolest_guy = goofy']) 247 248 self.runCmd("type summary delete i_am_cool") 249 self.runCmd("type summary add --summary-string \"goofy\" \"enum 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("type summary add --summary-string \"goofy\" \"struct i_am_cool\"") 255 self.expect("frame variable the_coolest_guy", 256 substrs = ['(i_am_cooler) the_coolest_guy = goofy']) 257 258 # many spaces, but we still do the right thing 259 self.runCmd("type summary delete i_am_cool") 260 self.runCmd("type summary add --summary-string \"goofy\" \"union i_am_cool\"") 261 self.expect("frame variable the_coolest_guy", 262 substrs = ['(i_am_cooler) the_coolest_guy = goofy']) 263 264 # but that not *every* specifier is removed 265 self.runCmd("type summary delete i_am_cool") 266 self.runCmd("type summary add --summary-string \"goofy\" \"wrong i_am_cool\"") 267 self.expect("frame variable the_coolest_guy", matching=False, 268 substrs = ['(i_am_cooler) the_coolest_guy = goofy']) 269 270 # check that formats are not sticking since that is the behavior we want 271 self.expect("frame variable iAmInt --format hex", substrs = ['(int) iAmInt = 0x00000001']) 272 self.expect("frame variable iAmInt", matching=False, substrs = ['(int) iAmInt = 0x00000001']) 273 self.expect("frame variable iAmInt", substrs = ['(int) iAmInt = 1']) 274 275if __name__ == '__main__': 276 import atexit 277 lldb.SBDebugger.Initialize() 278 atexit.register(lambda: lldb.SBDebugger.Terminate()) 279 unittest2.main() 280