51d42fc5e7bbae8a5478375dfd4b4a45decb8d9a
[openbsd] /
1 """
2 Test lldb data formatter subsystem.
3 """
4
5
6
7 import lldb
8 from lldbsuite.test.lldbtest import *
9 import lldbsuite.test.lldbutil as lldbutil
10
11
12 class SynthDataFormatterTestCase(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('type filter clear', check=False)
43
44         # Execute the cleanup function during test case tear down.
45         self.addTearDownHook(cleanup)
46
47         # Pick some values and check that the basics work
48         self.runCmd("type filter add BagOfInts --child x --child z")
49         self.expect("frame variable int_bag",
50                     substrs=['x = 6',
51                              'z = 8'])
52
53         # Check we can still access the missing child by summary
54         self.runCmd(
55             "type summary add BagOfInts --summary-string \"y=${var.y}\"")
56         self.expect('frame variable int_bag',
57                     substrs=['y=7'])
58
59         # Even if we have synth children, the summary prevails
60         self.expect("frame variable int_bag", matching=False,
61                     substrs=['x = 6',
62                              'z = 8'])
63
64         # if we skip synth and summary show y
65         self.expect(
66             "frame variable int_bag --synthetic-type false --no-summary-depth=1",
67             substrs=[
68                 'x = 6',
69                 'y = 7',
70                 'z = 8'])
71
72         # if we ask for raw output same happens
73         self.expect("frame variable int_bag --raw-output",
74                     substrs=['x = 6',
75                              'y = 7',
76                              'z = 8'])
77
78         # Summary+Synth must work together
79         self.runCmd(
80             "type summary add BagOfInts --summary-string \"x=${var.x}\" -e")
81         self.expect('frame variable int_bag',
82                     substrs=['x=6',
83                              'x = 6',
84                              'z = 8'])
85
86         # Same output, but using Python
87         self.runCmd(
88             "type summary add BagOfInts --python-script \"return 'x=%s' % valobj.GetChildMemberWithName('x').GetValue()\" -e")
89         self.expect('frame variable int_bag',
90                     substrs=['x=6',
91                              'x = 6',
92                              'z = 8'])
93
94         # If I skip summaries, still give me the artificial children
95         self.expect("frame variable int_bag --no-summary-depth=1",
96                     substrs=['x = 6',
97                              'z = 8'])
98
99         # Delete synth and check that the view reflects it immediately
100         self.runCmd("type filter delete BagOfInts")
101         self.expect("frame variable int_bag",
102                     substrs=['x = 6',
103                              'y = 7',
104                              'z = 8'])
105
106         # Add the synth again and check that it's honored deeper in the
107         # hierarchy
108         self.runCmd("type filter add BagOfInts --child x --child z")
109         self.expect('frame variable bag_bag',
110                     substrs=['x = x=69 {',
111                              'x = 69',
112                              'z = 71',
113                              'y = x=66 {',
114                              'x = 66',
115                              'z = 68'])
116         self.expect('frame variable bag_bag', matching=False,
117                     substrs=['y = 70',
118                              'y = 67'])
119
120         # Check that a synth can expand nested stuff
121         self.runCmd("type filter add BagOfBags --child x.y --child y.z")
122         self.expect('frame variable bag_bag',
123                     substrs=['x.y = 70',
124                              'y.z = 68'])
125
126         # ...even if we get -> and . wrong
127         self.runCmd("type filter add BagOfBags --child x.y --child \"y->z\"")
128         self.expect('frame variable bag_bag',
129                     substrs=['x.y = 70',
130                              'y->z = 68'])
131
132         # ...even bitfields
133         self.runCmd(
134             "type filter add BagOfBags --child x.y --child \"y->z[1-2]\"")
135         self.expect('frame variable bag_bag --show-types',
136                     substrs=['x.y = 70',
137                              '(int:2) y->z[1-2] = 2'])
138
139         # ...even if we format the bitfields
140         self.runCmd(
141             "type filter add BagOfBags --child x.y --child \"y->y[0-0]\"")
142         self.runCmd("type format add \"int:1\" -f bool")
143         self.expect('frame variable bag_bag --show-types',
144                     substrs=['x.y = 70',
145                              '(int:1) y->y[0-0] = true'])
146
147         # ...even if we use one-liner summaries
148         self.runCmd("type summary add -c BagOfBags")
149         self.expect('frame variable bag_bag', substrs=[
150                     '(BagOfBags) bag_bag = (x.y = 70, y->y[0-0] = true)'])
151
152         self.runCmd("type summary delete BagOfBags")
153
154         # now check we are dynamic (and arrays work)
155         self.runCmd(
156             "type filter add Plenty --child bitfield --child array[0] --child array[2]")
157         self.expect('frame variable plenty_of_stuff',
158                     substrs=['bitfield = 1',
159                              'array[0] = 5',
160                              'array[2] = 3'])
161
162         self.runCmd("n")
163         self.expect('frame variable plenty_of_stuff',
164                     substrs=['bitfield = 17',
165                              'array[0] = 5',
166                              'array[2] = 3'])
167
168         # skip synthetic children
169         self.expect('frame variable plenty_of_stuff --synthetic-type no',
170                     substrs=['some_values = 0x',
171                              'array = 0x',
172                              'array_size = 5'])
173
174         # check flat printing with synthetic children
175         self.expect('frame variable plenty_of_stuff --flat',
176                     substrs=['plenty_of_stuff.bitfield = 17',
177                              '*(plenty_of_stuff.array) = 5',
178                              '*(plenty_of_stuff.array) = 3'])
179
180         # check that we do not lose location information for our children
181         self.expect('frame variable plenty_of_stuff --location',
182                     substrs=['0x',
183                              ':   bitfield = 17'])
184
185         # check we work across pointer boundaries
186         self.expect('frame variable plenty_of_stuff.some_values --ptr-depth=1',
187                     substrs=['(BagOfInts *) plenty_of_stuff.some_values',
188                              'x = 5',
189                              'z = 7'])
190
191         # but not if we don't want to
192         self.runCmd("type filter add BagOfInts --child x --child z -p")
193         self.expect('frame variable plenty_of_stuff.some_values --ptr-depth=1',
194                     substrs=['(BagOfInts *) plenty_of_stuff.some_values',
195                              'x = 5',
196                              'y = 6',
197                              'z = 7'])
198
199         # check we're dynamic even if nested
200         self.runCmd("type filter add BagOfBags --child x.z")
201         self.expect('frame variable bag_bag',
202                     substrs=['x.z = 71'])
203
204         self.runCmd("n")
205         self.expect('frame variable bag_bag',
206                     substrs=['x.z = 12'])
207
208         self.runCmd(
209             'type summary add -e -s "I am always empty but have" EmptyStruct')
210         self.expect('frame variable es', substrs=[
211                     "I am always empty but have {}"])
212         self.runCmd('type summary add -e -h -s "I am really empty" EmptyStruct')
213         self.expect('frame variable es', substrs=["I am really empty"])
214         self.expect(
215             'frame variable es',
216             substrs=["I am really empty {}"],
217             matching=False)