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
73        # this will fail if we don't do [] as regex correctly
74        self.runCmd(
75            'type summary add --summary-string "${var[].integer}" "i_am_cool[]')
76
77        self.expect("frame variable cool_array",
78                    substrs=['1,1,1,1,6'])
79
80        self.runCmd("type summary clear")
81
82        self.runCmd(
83            "type summary add --summary-string \"${var[1-0]%x}\" \"int\"")
84
85        self.expect("frame variable iAmInt",
86                    substrs=['01'])
87
88        self.runCmd(
89            "type summary add --summary-string \"${var[0-1]%x}\" \"int\"")
90
91        self.expect("frame variable iAmInt",
92                    substrs=['01'])
93
94        self.runCmd("type summary clear")
95
96        self.runCmd("type summary add --summary-string \"${var[0-1]%x}\" int")
97        self.runCmd(
98            "type summary add --summary-string \"${var[0-31]%x}\" float")
99
100        self.expect("frame variable *pointer",
101                    substrs=['0x',
102                             '2'])
103
104        # check fix for <rdar://problem/11338654> LLDB crashes when using a
105        # "type summary" that uses bitfields with no format
106        self.runCmd("type summary add --summary-string \"${var[0-1]}\" int")
107        self.expect("frame variable iAmInt",
108                    substrs=['9 1'])
109
110        self.expect("frame variable cool_array[3].floating",
111                    substrs=['0x'])
112
113        self.runCmd(
114            "type summary add --summary-string \"low bits are ${*var[0-1]} tgt is ${*var}\" \"int *\"")
115
116        self.expect("frame variable pointer",
117                    substrs=['low bits are',
118                             'tgt is 6'])
119
120        self.expect(
121            "frame variable int_array --summary-string \"${*var[0-1]}\"",
122            substrs=['3'])
123
124        self.runCmd("type summary clear")
125
126        self.runCmd(
127            'type summary add --summary-string \"${var[0-1]}\" -x \"int \[[0-9]\]\"')
128
129        self.expect("frame variable int_array",
130                    substrs=['1,2'])
131
132        self.runCmd(
133            'type summary add --summary-string \"${var[0-1]}\" "int []"')
134
135        self.expect("frame variable int_array",
136                    substrs=['1,2'])
137
138        # Test the patterns are matched in reverse-chronological order.
139        self.runCmd(
140            'type summary add --summary-string \"${var[2-3]}\" "int []"')
141
142        self.expect("frame variable int_array",
143                    substrs=['3,4'])
144
145        self.runCmd("type summary clear")
146
147        self.runCmd("type summary add -c -x \"i_am_cool \[[0-9]\]\"")
148        self.runCmd("type summary add -c i_am_cool")
149
150        self.expect(
151            "frame variable cool_array",
152            substrs=[
153                '[0]',
154                'integer',
155                'floating',
156                'character',
157                '[1]',
158                'integer',
159                'floating',
160                'character',
161                '[2]',
162                'integer',
163                'floating',
164                'character',
165                '[3]',
166                'integer',
167                'floating',
168                'character',
169                '[4]',
170                'integer',
171                'floating',
172                'character',
173            ])
174
175        self.runCmd(
176            "type summary add --summary-string \"int = ${*var.int_pointer}, float = ${*var.float_pointer}\" IWrapPointers")
177
178        self.expect("frame variable wrapper",
179                    substrs=['int = 4',
180                             'float = 1.1'])
181
182        self.runCmd(
183            "type summary add --summary-string \"low bits = ${*var.int_pointer[2]}\" IWrapPointers -p")
184
185        self.expect("frame variable wrapper",
186                    substrs=['low bits = 1'])
187
188        self.expect("frame variable *wrap_pointer",
189                    substrs=['low bits = 1'])
190
191        self.runCmd("type summary clear")
192
193        self.expect(
194            "frame variable int_array --summary-string \"${var[0][0-2]%hex}\"",
195            substrs=[
196                '0x',
197                '7'])
198
199        self.runCmd("type summary clear")
200
201        self.runCmd(
202            "type summary add --summary-string \"${*var[].x[0-3]%hex} is a bitfield on a set of integers\" -x \"SimpleWithPointers \[[0-9]\]\"")
203
204        self.expect(
205            "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]}\"",
206            substrs=[
207                '1 are low bits of integer 9.',
208                'If I pretend it is an array I get [9,'])
209
210        # if the summary has an error, we still display the value
211        self.expect(
212            "frame variable couple --summary-string \"${*var.sp.foo[0-2]\"",
213            substrs=[
214                '(Couple) couple = {',
215                'x = 0x',
216                'y = 0x',
217                'z = 0x',
218                's = 0x'])
219
220        self.runCmd(
221            "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")
222
223        self.expect("frame variable sparray",
224                    substrs=['[0x0000000f,0x0000000c,0x00000009]'])
225
226        # check that we can format a variable in a summary even if a format is
227        # defined for its datatype
228        self.runCmd("type format add -f hex int")
229        self.runCmd(
230            "type summary add --summary-string \"x=${var.x%d}\" Simple")
231
232        self.expect("frame variable a_simple_object",
233                    substrs=['x=3'])
234
235        self.expect("frame variable a_simple_object", matching=False,
236                    substrs=['0x0'])
237
238        # now check that the default is applied if we do not hand out a format
239        self.runCmd("type summary add --summary-string \"x=${var.x}\" Simple")
240
241        self.expect("frame variable a_simple_object", matching=False,
242                    substrs=['x=3'])
243
244        self.expect("frame variable a_simple_object", matching=True,
245                    substrs=['x=0x00000003'])
246
247        # check that we can correctly cap the number of children shown
248        self.runCmd("settings set target.max-children-count 5")
249
250        self.expect('frame variable a_long_guy', matching=True,
251                    substrs=['a_1',
252                             'b_1',
253                             'c_1',
254                             'd_1',
255                             'e_1',
256                             '...'])
257
258        # check that no further stuff is printed (not ALL values are checked!)
259        self.expect('frame variable a_long_guy', matching=False,
260                    substrs=['f_1',
261                             'g_1',
262                             'h_1',
263                             'i_1',
264                             'j_1',
265                             'q_1',
266                             'a_2',
267                             'f_2',
268                             't_2',
269                             'w_2'])
270
271        self.runCmd("settings set target.max-children-count 1")
272        self.expect('frame variable a_long_guy', matching=True,
273                    substrs=['a_1',
274                             '...'])
275        self.expect('frame variable a_long_guy', matching=False,
276                    substrs=['b_1',
277                             'c_1',
278                             'd_1',
279                             'e_1'])
280        self.expect('frame variable a_long_guy', matching=False,
281                    substrs=['f_1',
282                             'g_1',
283                             'h_1',
284                             'i_1',
285                             'j_1',
286                             'q_1',
287                             'a_2',
288                             'f_2',
289                             't_2',
290                             'w_2'])
291
292        self.runCmd("settings set target.max-children-count 30")
293        self.expect('frame variable a_long_guy', matching=True,
294                    substrs=['a_1',
295                             'b_1',
296                             'c_1',
297                             'd_1',
298                             'e_1',
299                             'z_1',
300                             'a_2',
301                             'b_2',
302                             'c_2',
303                             'd_2',
304                             '...'])
305        self.expect('frame variable a_long_guy', matching=False,
306                    substrs=['e_2',
307                             'n_2',
308                             'r_2',
309                             'i_2',
310                             'k_2',
311                             'o_2'])
312
313        # override the cap
314        self.expect(
315            'frame variable a_long_guy --show-all-children',
316            matching=True,
317            substrs=[
318                'a_1',
319                'b_1',
320                'c_1',
321                'd_1',
322                'e_1',
323                'z_1',
324                'a_2',
325                'b_2',
326                'c_2',
327                'd_2'])
328        self.expect(
329            'frame variable a_long_guy --show-all-children',
330            matching=True,
331            substrs=[
332                'e_2',
333                'i_2',
334                'k_2',
335                'n_2',
336                'o_2',
337                'r_2',
338            ])
339        self.expect(
340            'frame variable a_long_guy --show-all-children',
341            matching=False,
342            substrs=['...'])
343