1"""
2Test lldb data formatter subsystem.
3"""
4
5
6
7import lldb
8from lldbsuite.test.lldbtest import *
9import lldbsuite.test.lldbutil as lldbutil
10
11
12class AdvDataFormatterTestCase(TestBase):
13
14    mydir = TestBase.compute_mydir(__file__)
15
16    def setUp(self):
17        # Call super's setUp().
18        TestBase.setUp(self)
19        # Find the line number to break at.
20        self.line = line_number('main.cpp', '// Set break point at this line.')
21
22    def test_with_run_command(self):
23        """Test that that file and class static variables display correctly."""
24        self.build()
25        self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET)
26
27        lldbutil.run_break_set_by_file_and_line(
28            self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True)
29
30        self.runCmd("run", RUN_SUCCEEDED)
31
32        # The stop reason of the thread should be breakpoint.
33        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
34                    substrs=['stopped',
35                             'stop reason = breakpoint'])
36
37        # This is the function to remove the custom formats in order to have a
38        # clean slate for the next test case.
39        def cleanup():
40            self.runCmd('type format clear', check=False)
41            self.runCmd('type summary clear', check=False)
42            self.runCmd(
43                "settings set target.max-children-count 256",
44                check=False)
45
46        # Execute the cleanup function during test case tear down.
47        self.addTearDownHook(cleanup)
48
49        self.runCmd("type summary add --summary-string \"pippo\" \"i_am_cool\"")
50
51        self.runCmd(
52            "type summary add --summary-string \"pluto\" -x \"i_am_cool[a-z]*\"")
53
54        self.expect("frame variable cool_boy",
55                    substrs=['pippo'])
56
57        self.expect("frame variable cooler_boy",
58                    substrs=['pluto'])
59
60        self.runCmd("type summary delete i_am_cool")
61
62        self.expect("frame variable cool_boy",
63                    substrs=['pluto'])
64
65        self.runCmd("type summary clear")
66
67        self.runCmd(
68            "type summary add --summary-string \"${var[]}\" -x \"^int\\[[0-9]\\]")
69
70        self.expect("frame variable int_array",
71                    substrs=['1,2,3,4,5'])
72        self.expect("frame variable const_int_array",
73                    substrs=['11,12,13,14,15'])
74
75        # this will fail if we don't do [] as regex correctly
76        self.runCmd(
77            'type summary add --summary-string "${var[].integer}" "i_am_cool[]')
78
79        self.expect("frame variable cool_array",
80                    substrs=['1,1,1,1,6'])
81
82        self.runCmd("type summary clear")
83
84        self.runCmd(
85            "type summary add --summary-string \"${var[1-0]%x}\" \"int\"")
86
87        self.expect("frame variable iAmInt",
88                    substrs=['01'])
89
90        self.runCmd(
91            "type summary add --summary-string \"${var[0-1]%x}\" \"int\"")
92
93        self.expect("frame variable iAmInt",
94                    substrs=['01'])
95
96        self.runCmd("type summary clear")
97
98        self.runCmd("type summary add --summary-string \"${var[0-1]%x}\" int")
99        self.runCmd(
100            "type summary add --summary-string \"${var[0-31]%x}\" float")
101
102        self.expect("frame variable *pointer",
103                    substrs=['0x',
104                             '2'])
105
106        # check fix for <rdar://problem/11338654> LLDB crashes when using a
107        # "type summary" that uses bitfields with no format
108        self.runCmd("type summary add --summary-string \"${var[0-1]}\" int")
109        self.expect("frame variable iAmInt",
110                    substrs=['9 1'])
111
112        self.expect("frame variable cool_array[3].floating",
113                    substrs=['0x'])
114
115        self.runCmd(
116            "type summary add --summary-string \"low bits are ${*var[0-1]} tgt is ${*var}\" \"int *\"")
117
118        self.expect("frame variable pointer",
119                    substrs=['low bits are',
120                             'tgt is 6'])
121
122        self.expect(
123            "frame variable int_array --summary-string \"${*var[0-1]}\"",
124            substrs=['3'])
125
126        self.runCmd("type summary clear")
127
128        self.runCmd(
129            'type summary add --summary-string \"${var[0-1]}\" -x \"int\[[0-9]\]\"')
130
131        self.expect("frame variable int_array",
132                    substrs=['1,2'])
133
134        self.runCmd(
135            'type summary add --summary-string \"${var[0-1]}\" "int[]"')
136
137        self.expect("frame variable int_array",
138                    substrs=['1,2'])
139
140        # Test the patterns are matched in reverse-chronological order.
141        self.runCmd(
142            'type summary add --summary-string \"${var[2-3]}\" "int[]"')
143
144        self.expect("frame variable int_array",
145                    substrs=['3,4'])
146
147        self.runCmd("type summary clear")
148
149        self.runCmd("type summary add -c -x \"i_am_cool\[[0-9]\]\"")
150        self.runCmd("type summary add -c i_am_cool")
151
152        self.expect(
153            "frame variable cool_array",
154            substrs=[
155                '[0]',
156                'integer',
157                'floating',
158                'character',
159                '[1]',
160                'integer',
161                'floating',
162                'character',
163                '[2]',
164                'integer',
165                'floating',
166                'character',
167                '[3]',
168                'integer',
169                'floating',
170                'character',
171                '[4]',
172                'integer',
173                'floating',
174                'character',
175            ])
176
177        self.runCmd(
178            "type summary add --summary-string \"int = ${*var.int_pointer}, float = ${*var.float_pointer}\" IWrapPointers")
179
180        self.expect("frame variable wrapper",
181                    substrs=['int = 4',
182                             'float = 1.1'])
183
184        self.runCmd(
185            "type summary add --summary-string \"low bits = ${*var.int_pointer[2]}\" IWrapPointers -p")
186
187        self.expect("frame variable wrapper",
188                    substrs=['low bits = 1'])
189
190        self.expect("frame variable *wrap_pointer",
191                    substrs=['low bits = 1'])
192
193        self.runCmd("type summary clear")
194
195        self.expect(
196            "frame variable int_array --summary-string \"${var[0][0-2]%hex}\"",
197            substrs=[
198                '0x',
199                '7'])
200
201        self.runCmd("type summary clear")
202
203        self.runCmd(
204            "type summary add --summary-string \"${*var[].x[0-3]%hex} is a bitfield on a set of integers\" -x \"SimpleWithPointers\[[0-9]\]\"")
205
206        self.expect(
207            "frame variable couple --summary-string \"${*var.sp.x[0-2]} are low bits of integer ${*var.sp.x}. If I pretend it is an array I get ${var.sp.x[0-5]}\"",
208            substrs=[
209                '1 are low bits of integer 9.',
210                'If I pretend it is an array I get [9,'])
211
212        # if the summary has an error, we still display the value
213        self.expect(
214            "frame variable couple --summary-string \"${*var.sp.foo[0-2]\"",
215            substrs=[
216                '(Couple) couple = {',
217                'x = 0x',
218                'y = 0x',
219                'z = 0x',
220                's = 0x'])
221
222        self.runCmd(
223            "type summary add --summary-string \"${*var.sp.x[0-2]} are low bits of integer ${*var.sp.x}. If I pretend it is an array I get ${var.sp.x[0-5]}\" Couple")
224
225        self.expect("frame variable sparray",
226                    substrs=['[0x0000000f,0x0000000c,0x00000009]'])
227
228        # check that we can format a variable in a summary even if a format is
229        # defined for its datatype
230        self.runCmd("type format add -f hex int")
231        self.runCmd(
232            "type summary add --summary-string \"x=${var.x%d}\" Simple")
233
234        self.expect("frame variable a_simple_object",
235                    substrs=['x=3'])
236
237        self.expect("frame variable a_simple_object", matching=False,
238                    substrs=['0x0'])
239
240        # now check that the default is applied if we do not hand out a format
241        self.runCmd("type summary add --summary-string \"x=${var.x}\" Simple")
242
243        self.expect("frame variable a_simple_object", matching=False,
244                    substrs=['x=3'])
245
246        self.expect("frame variable a_simple_object", matching=True,
247                    substrs=['x=0x00000003'])
248
249        self.expect_var_path("constInt", value='0x0000002a')
250
251        self.expect_var_path("volatileInt", value='0x0000002b')
252
253        self.expect_var_path("constVolatileInt", value='0x0000002c')
254
255        # check that we can correctly cap the number of children shown
256        self.runCmd("settings set target.max-children-count 5")
257
258        self.expect('frame variable a_long_guy', matching=True,
259                    substrs=['a_1',
260                             'b_1',
261                             'c_1',
262                             'd_1',
263                             'e_1',
264                             '...'])
265
266        # check that no further stuff is printed (not ALL values are checked!)
267        self.expect('frame variable a_long_guy', matching=False,
268                    substrs=['f_1',
269                             'g_1',
270                             'h_1',
271                             'i_1',
272                             'j_1',
273                             'q_1',
274                             'a_2',
275                             'f_2',
276                             't_2',
277                             'w_2'])
278
279        self.runCmd("settings set target.max-children-count 1")
280        self.expect('frame variable a_long_guy', matching=True,
281                    substrs=['a_1',
282                             '...'])
283        self.expect('frame variable a_long_guy', matching=False,
284                    substrs=['b_1',
285                             'c_1',
286                             'd_1',
287                             'e_1'])
288        self.expect('frame variable a_long_guy', matching=False,
289                    substrs=['f_1',
290                             'g_1',
291                             'h_1',
292                             'i_1',
293                             'j_1',
294                             'q_1',
295                             'a_2',
296                             'f_2',
297                             't_2',
298                             'w_2'])
299
300        self.runCmd("settings set target.max-children-count 30")
301        self.expect('frame variable a_long_guy', matching=True,
302                    substrs=['a_1',
303                             'b_1',
304                             'c_1',
305                             'd_1',
306                             'e_1',
307                             'z_1',
308                             'a_2',
309                             'b_2',
310                             'c_2',
311                             'd_2',
312                             '...'])
313        self.expect('frame variable a_long_guy', matching=False,
314                    substrs=['e_2',
315                             'n_2',
316                             'r_2',
317                             'i_2',
318                             'k_2',
319                             'o_2'])
320
321        # override the cap
322        self.expect(
323            'frame variable a_long_guy --show-all-children',
324            matching=True,
325            substrs=[
326                'a_1',
327                'b_1',
328                'c_1',
329                'd_1',
330                'e_1',
331                'z_1',
332                'a_2',
333                'b_2',
334                'c_2',
335                'd_2'])
336        self.expect(
337            'frame variable a_long_guy --show-all-children',
338            matching=True,
339            substrs=[
340                'e_2',
341                'i_2',
342                'k_2',
343                'n_2',
344                'o_2',
345                'r_2',
346            ])
347        self.expect(
348            'frame variable a_long_guy --show-all-children',
349            matching=False,
350            substrs=['...'])
351