1"""
2Test lldb data formatter subsystem.
3"""
4
5
6import lldb
7from lldbsuite.test.decorators import *
8from lldbsuite.test.lldbtest import *
9from lldbsuite.test import lldbutil
10
11
12class SmartArrayDataFormatterTestCase(TestBase):
13    def test_with_run_command(self):
14        """Test data formatter commands."""
15        self.build()
16        self.data_formatter_commands()
17
18    def setUp(self):
19        # Call super's setUp().
20        TestBase.setUp(self)
21        # Find the line number to break at.
22        self.line = line_number("main.cpp", "// Set break point at this line.")
23
24    def data_formatter_commands(self):
25        """Test that that file and class static variables display correctly."""
26        self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET)
27
28        lldbutil.run_break_set_by_file_and_line(
29            self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True
30        )
31
32        self.runCmd("run", RUN_SUCCEEDED)
33
34        process = self.dbg.GetSelectedTarget().GetProcess()
35
36        # The stop reason of the thread should be breakpoint.
37        self.expect(
38            "thread list",
39            STOPPED_DUE_TO_BREAKPOINT,
40            substrs=["stopped", "stop reason = breakpoint"],
41        )
42
43        # This is the function to remove the custom formats in order to have a
44        # clean slate for the next test case.
45        def cleanup():
46            self.runCmd("type format clear", check=False)
47            self.runCmd("type summary clear", check=False)
48
49        # Execute the cleanup function during test case tear down.
50        self.addTearDownHook(cleanup)
51
52        # check that we are not looping here
53        self.runCmd('type summary add --summary-string "${var%V}" SomeData')
54
55        self.expect("frame variable data", substrs=["SomeData @ 0x"])
56        # ${var%s}
57        self.runCmd('type summary add --summary-string "ptr = ${var%s}" "char *"')
58
59        self.expect("frame variable strptr", substrs=['ptr = "', "Hello world!"])
60
61        self.expect(
62            "frame variable other.strptr", substrs=['ptr = "', "Nested Hello world!"]
63        )
64
65        self.runCmd(
66            'type summary add --summary-string "arr = ${var%s}" -x "char\\[[0-9]+\\]"'
67        )
68
69        self.expect("frame variable strarr", substrs=['arr = "', "Hello world!"])
70
71        self.expect(
72            "frame variable other.strarr", substrs=['arr = "', "Nested Hello world!"]
73        )
74
75        self.expect("expression strarr", substrs=['arr = "', "Hello world!"])
76
77        self.expect(
78            "expression other.strarr", substrs=['arr = "', "Nested Hello world!"]
79        )
80
81        # ${var%c}
82        self.runCmd('type summary add --summary-string "ptr = ${var%c}" "char *"')
83
84        self.expect("frame variable strptr", substrs=['ptr = "', "Hello world!"])
85
86        self.expect(
87            "frame variable other.strptr", substrs=['ptr = "', "Nested Hello world!"]
88        )
89
90        self.expect("expression strptr", substrs=['ptr = "', "Hello world!"])
91
92        self.expect(
93            "expression other.strptr", substrs=['ptr = "', "Nested Hello world!"]
94        )
95
96        self.runCmd(
97            'type summary add --summary-string "arr = ${var%c}" -x "char\\[[0-9]+\\]"'
98        )
99
100        self.expect("frame variable strarr", substrs=['arr = "', "Hello world!"])
101
102        self.expect(
103            "frame variable other.strarr", substrs=['arr = "', "Nested Hello world!"]
104        )
105
106        self.expect("expression strarr", substrs=['arr = "', "Hello world!"])
107
108        self.expect(
109            "expression other.strarr", substrs=['arr = "', "Nested Hello world!"]
110        )
111
112        # ${var%char[]}
113        self.runCmd(
114            'type summary add --summary-string "arr = ${var%char[]}" -x "char\\[[0-9]+\\]"'
115        )
116
117        self.expect("frame variable strarr", substrs=['arr = "', "Hello world!"])
118
119        self.expect(
120            "frame variable other.strarr", substrs=["arr = ", "Nested Hello world!"]
121        )
122
123        self.expect("expression strarr", substrs=['arr = "', "Hello world!"])
124
125        self.expect(
126            "expression other.strarr", substrs=["arr = ", "Nested Hello world!"]
127        )
128
129        self.runCmd('type summary add --summary-string "ptr = ${var%char[]}" "char *"')
130
131        self.expect("frame variable strptr", substrs=['ptr = "', "Hello world!"])
132
133        self.expect(
134            "frame variable other.strptr", substrs=['ptr = "', "Nested Hello world!"]
135        )
136
137        self.expect("expression strptr", substrs=['ptr = "', "Hello world!"])
138
139        self.expect(
140            "expression other.strptr", substrs=['ptr = "', "Nested Hello world!"]
141        )
142
143        # ${var%a}
144        self.runCmd(
145            'type summary add --summary-string "arr = ${var%a}" -x "char\\[[0-9]+\\]"'
146        )
147
148        self.expect("frame variable strarr", substrs=['arr = "', "Hello world!"])
149
150        self.expect(
151            "frame variable other.strarr", substrs=["arr = ", "Nested Hello world!"]
152        )
153
154        self.expect("expression strarr", substrs=['arr = "', "Hello world!"])
155
156        self.expect(
157            "expression other.strarr", substrs=["arr = ", "Nested Hello world!"]
158        )
159
160        self.runCmd('type summary add --summary-string "ptr = ${var%a}" "char *"')
161
162        self.expect("frame variable strptr", substrs=['ptr = "', "Hello world!"])
163
164        self.expect(
165            "frame variable other.strptr", substrs=['ptr = "', "Nested Hello world!"]
166        )
167
168        self.expect("expression strptr", substrs=['ptr = "', "Hello world!"])
169
170        self.expect(
171            "expression other.strptr", substrs=['ptr = "', "Nested Hello world!"]
172        )
173
174        self.runCmd(
175            'type summary add --summary-string "ptr = ${var[]%char[]}" "char *"'
176        )
177
178        # I do not know the size of the data, but you are asking for a full array slice..
179        # use the ${var%char[]} to obtain a string as result
180        self.expect(
181            "frame variable strptr", matching=False, substrs=['ptr = "', "Hello world!"]
182        )
183
184        self.expect(
185            "frame variable other.strptr",
186            matching=False,
187            substrs=['ptr = "', "Nested Hello world!"],
188        )
189
190        self.expect(
191            "expression strptr", matching=False, substrs=['ptr = "', "Hello world!"]
192        )
193
194        self.expect(
195            "expression other.strptr",
196            matching=False,
197            substrs=['ptr = "', "Nested Hello world!"],
198        )
199
200        # You asked an array-style printout...
201        self.runCmd(
202            'type summary add --summary-string "ptr = ${var[0-1]%char[]}" "char *"'
203        )
204
205        self.expect("frame variable strptr", substrs=["ptr = ", "[{H},{e}]"])
206
207        self.expect("frame variable other.strptr", substrs=["ptr = ", "[{N},{e}]"])
208
209        self.expect("expression strptr", substrs=["ptr = ", "[{H},{e}]"])
210
211        self.expect("expression other.strptr", substrs=["ptr = ", "[{N},{e}]"])
212
213        # using [] is required here
214        self.runCmd('type summary add --summary-string "arr = ${var%x}" "int [5]"')
215
216        self.expect(
217            "frame variable intarr",
218            matching=False,
219            substrs=["0x00000001,0x00000001,0x00000002,0x00000003,0x00000005"],
220        )
221
222        self.expect(
223            "frame variable other.intarr",
224            matching=False,
225            substrs=["0x00000009,0x00000008,0x00000007,0x00000006,0x00000005"],
226        )
227
228        self.runCmd('type summary add --summary-string "arr = ${var[]%x}" "int[5]"')
229
230        self.expect(
231            "frame variable intarr",
232            substrs=[
233                "intarr = arr =",
234                "0x00000001,0x00000001,0x00000002,0x00000003,0x00000005",
235            ],
236        )
237
238        self.expect(
239            "frame variable other.intarr",
240            substrs=[
241                "intarr = arr =",
242                "0x00000009,0x00000008,0x00000007,0x00000006,0x00000005",
243            ],
244        )
245
246        # printing each array item as an array
247        self.runCmd(
248            'type summary add --summary-string "arr = ${var[]%uint32_t[]}" "int[5]"'
249        )
250
251        self.expect(
252            "frame variable intarr",
253            substrs=[
254                "intarr = arr =",
255                "{0x00000001},{0x00000001},{0x00000002},{0x00000003},{0x00000005}",
256            ],
257        )
258
259        self.expect(
260            "frame variable other.intarr",
261            substrs=[
262                "intarr = arr = ",
263                "{0x00000009},{0x00000008},{0x00000007},{0x00000006},{0x00000005}",
264            ],
265        )
266
267        # printing full array as an array
268        self.runCmd(
269            'type summary add --summary-string "arr = ${var%uint32_t[]}" "int[5]"'
270        )
271
272        self.expect(
273            "frame variable intarr",
274            substrs=[
275                "intarr = arr =",
276                "0x00000001,0x00000001,0x00000002,0x00000003,0x00000005",
277            ],
278        )
279
280        self.expect(
281            "frame variable other.intarr",
282            substrs=[
283                "intarr = arr =",
284                "0x00000009,0x00000008,0x00000007,0x00000006,0x00000005",
285            ],
286        )
287
288        # printing each array item as an array
289        self.runCmd(
290            'type summary add --summary-string "arr = ${var[]%float32[]}" "float[7]"'
291        )
292
293        self.expect(
294            "frame variable flarr",
295            substrs=[
296                "flarr = arr =",
297                "{78.5},{77.25},{78},{76.125},{76.75},{76.875},{77}",
298            ],
299        )
300
301        self.expect(
302            "frame variable other.flarr",
303            substrs=[
304                "flarr = arr = ",
305                "{25.5},{25.25},{25.125},{26.75},{27.375},{27.5},{26.125}",
306            ],
307        )
308
309        # printing full array as an array
310        self.runCmd(
311            'type summary add --summary-string "arr = ${var%float32[]}" "float[7]"'
312        )
313
314        self.expect(
315            "frame variable flarr",
316            substrs=["flarr = arr =", "78.5,77.25,78,76.125,76.75,76.875,77"],
317        )
318
319        self.expect(
320            "frame variable other.flarr",
321            substrs=["flarr = arr =", "25.5,25.25,25.125,26.75,27.375,27.5,26.125"],
322        )
323
324        # using array smart summary strings for pointers should make no sense
325        self.runCmd(
326            'type summary add --summary-string "arr = ${var%float32[]}" "float *"'
327        )
328        self.runCmd(
329            'type summary add --summary-string "arr = ${var%int32_t[]}" "int *"'
330        )
331
332        self.expect(
333            "frame variable flptr",
334            matching=False,
335            substrs=["78.5,77.25,78,76.125,76.75,76.875,77"],
336        )
337
338        self.expect("frame variable intptr", matching=False, substrs=["1,1,2,3,5"])
339
340        # use y and Y
341        self.runCmd('type summary add --summary-string "arr = ${var%y}" "float[7]"')
342        self.runCmd('type summary add --summary-string "arr = ${var%y}" "int[5]"')
343
344        if process.GetByteOrder() == lldb.eByteOrderLittle:
345            self.expect(
346                "frame variable flarr",
347                substrs=[
348                    "flarr = arr =",
349                    "00 00 9d 42,00 80 9a 42,00 00 9c 42,00 40 98 42,00 80 99 42,00 c0 99 42,00 00 9a 42",
350                ],
351            )
352        else:
353            self.expect(
354                "frame variable flarr",
355                substrs=[
356                    "flarr = arr =",
357                    "42 9d 00 00,42 9a 80 00,42 9c 00 00,42 98 40 00,42 99 80 00,42 99 c0 00,42 9a 00 00",
358                ],
359            )
360
361        if process.GetByteOrder() == lldb.eByteOrderLittle:
362            self.expect(
363                "frame variable other.flarr",
364                substrs=[
365                    "flarr = arr =",
366                    "00 00 cc 41,00 00 ca 41,00 00 c9 41,00 00 d6 41,00 00 db 41,00 00 dc 41,00 00 d1 41",
367                ],
368            )
369        else:
370            self.expect(
371                "frame variable other.flarr",
372                substrs=[
373                    "flarr = arr =",
374                    "41 cc 00 00,41 ca 00 00,41 c9 00 00,41 d6 00 00,41 db 00 00,41 dc 00 00,41 d1 00 00",
375                ],
376            )
377
378        if process.GetByteOrder() == lldb.eByteOrderLittle:
379            self.expect(
380                "frame variable intarr",
381                substrs=[
382                    "intarr = arr =",
383                    "01 00 00 00,01 00 00 00,02 00 00 00,03 00 00 00,05 00 00 00",
384                ],
385            )
386        else:
387            self.expect(
388                "frame variable intarr",
389                substrs=[
390                    "intarr = arr =",
391                    "00 00 00 01,00 00 00 01,00 00 00 02,00 00 00 03,00 00 00 05",
392                ],
393            )
394
395        if process.GetByteOrder() == lldb.eByteOrderLittle:
396            self.expect(
397                "frame variable other.intarr",
398                substrs=[
399                    "intarr = arr = ",
400                    "09 00 00 00,08 00 00 00,07 00 00 00,06 00 00 00,05 00 00 00",
401                ],
402            )
403        else:
404            self.expect(
405                "frame variable other.intarr",
406                substrs=[
407                    "intarr = arr = ",
408                    "00 00 00 09,00 00 00 08,00 00 00 07,00 00 00 06,00 00 00 05",
409                ],
410            )
411
412        self.runCmd('type summary add --summary-string "arr = ${var%Y}" "float[7]"')
413        self.runCmd('type summary add --summary-string "arr = ${var%Y}" "int[5]"')
414
415        if process.GetByteOrder() == lldb.eByteOrderLittle:
416            self.expect(
417                "frame variable flarr",
418                substrs=[
419                    "flarr = arr =",
420                    "00 00 9d 42",
421                    "00 80 9a 42",
422                    "00 00 9c 42",
423                    "00 40 98 42",
424                    "00 80 99 42",
425                    "00 c0 99 42",
426                    "00 00 9a 42",
427                ],
428            )
429        else:
430            self.expect(
431                "frame variable flarr",
432                substrs=[
433                    "flarr = arr =",
434                    "42 9d 00 00",
435                    "42 9a 80 00",
436                    "42 9c 00 00",
437                    "42 98 40 00",
438                    "42 99 80 00",
439                    "42 99 c0 00",
440                    "42 9a 00 00",
441                ],
442            )
443
444        if process.GetByteOrder() == lldb.eByteOrderLittle:
445            self.expect(
446                "frame variable other.flarr",
447                substrs=[
448                    "flarr = arr =",
449                    "00 00 cc 41",
450                    "00 00 ca 41",
451                    "00 00 c9 41",
452                    "00 00 d6 41",
453                    "00 00 db 41",
454                    "00 00 dc 41",
455                    "00 00 d1 41",
456                ],
457            )
458        else:
459            self.expect(
460                "frame variable other.flarr",
461                substrs=[
462                    "flarr = arr =",
463                    "41 cc 00 00",
464                    "41 ca 00 00",
465                    "41 c9 00 00",
466                    "41 d6 00 00",
467                    "41 db 00 00",
468                    "41 dc 00 00",
469                    "41 d1 00 00",
470                ],
471            )
472
473        if process.GetByteOrder() == lldb.eByteOrderLittle:
474            self.expect(
475                "frame variable intarr",
476                substrs=["intarr = arr =", "....,01 00 00 00", "....,05 00 00 00"],
477            )
478        else:
479            self.expect(
480                "frame variable intarr",
481                substrs=["intarr = arr =", "....,00 00 00 01", "....,00 00 00 05"],
482            )
483
484        if process.GetByteOrder() == lldb.eByteOrderLittle:
485            self.expect(
486                "frame variable other.intarr",
487                substrs=["intarr = arr = ", "09 00 00 00", "....,07 00 00 00"],
488            )
489        else:
490            self.expect(
491                "frame variable other.intarr",
492                substrs=["intarr = arr = ", "00 00 00 09", "....,00 00 00 07"],
493            )
494