• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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