Home | History | Annotate | Download | only in data-formatter-cpp
      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 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 
    275 if __name__ == '__main__':
    276     import atexit
    277     lldb.SBDebugger.Initialize()
    278     atexit.register(lambda: lldb.SBDebugger.Terminate())
    279     unittest2.main()
    280