]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-python-synth/TestDataFormatterPythonSynth.py
Vendor import of lldb release_39 branch r276489:
[FreeBSD/FreeBSD.git] / packages / Python / lldbsuite / test / functionalities / data-formatter / data-formatter-python-synth / TestDataFormatterPythonSynth.py
1 """
2 Test lldb data formatter subsystem.
3 """
4
5 from __future__ import print_function
6
7
8
9 import os, time
10 import lldb
11 from lldbsuite.test.decorators import *
12 from lldbsuite.test.lldbtest import *
13 from lldbsuite.test import lldbutil
14
15 class PythonSynthDataFormatterTestCase(TestBase):
16
17     mydir = TestBase.compute_mydir(__file__)
18
19     @skipIfFreeBSD # llvm.org/pr20545 bogus output confuses buildbot parser
20     def test_with_run_command(self):
21         """Test data formatter commands."""
22         self.build()
23         self.data_formatter_commands()
24
25     def test_rdar10960550_with_run_command(self):
26         """Test data formatter commands."""
27         self.build()
28         self.rdar10960550_formatter_commands()
29
30
31     def setUp(self):
32         # Call super's setUp().
33         TestBase.setUp(self)
34         # Find the line number to break at.
35         self.line = line_number('main.cpp', '// Set break point at this line.')
36         self.line2 = line_number('main.cpp', '// Set cast break point at this line.')
37         self.line3 = line_number('main.cpp', '// Set second cast break point at this line.')
38
39     def data_formatter_commands(self):
40         """Test using Python synthetic children provider."""
41         self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
42
43         lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True)
44
45         self.runCmd("run", RUN_SUCCEEDED)
46
47         process = self.dbg.GetSelectedTarget().GetProcess()
48
49         # The stop reason of the thread should be breakpoint.
50         self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
51             substrs = ['stopped',
52                        'stop reason = breakpoint'])
53
54         # This is the function to remove the custom formats in order to have a
55         # clean slate for the next test case.
56         def cleanup():
57             self.runCmd('type format clear', check=False)
58             self.runCmd('type summary clear', check=False)
59             self.runCmd('type filter clear', check=False)
60             self.runCmd('type synth clear', check=False)
61
62         # Execute the cleanup function during test case tear down.
63         self.addTearDownHook(cleanup)
64
65         # print the f00_1 variable without a synth
66         self.expect("frame variable f00_1",
67             substrs = ['a = 1',
68                        'b = 2',
69                        'r = 34']);
70
71         # now set up the synth
72         self.runCmd("script from fooSynthProvider import *")
73         self.runCmd("type synth add -l fooSynthProvider foo")
74         self.expect("type synthetic list foo", substrs=['fooSynthProvider'])
75
76         # note that the value of fake_a depends on target byte order
77         if process.GetByteOrder() == lldb.eByteOrderLittle:
78             fake_a_val = 0x02000000
79         else:
80             fake_a_val = 0x00000100
81
82         # check that we get the two real vars and the fake_a variables
83         self.expect("frame variable f00_1",
84                     substrs = ['r = 34',
85                                'fake_a = %d' % fake_a_val,
86                                'a = 1']);
87
88         # check that we do not get the extra vars
89         self.expect("frame variable f00_1", matching=False,
90                     substrs = ['b = 2']);
91         
92         # check access to members by name
93         self.expect('frame variable f00_1.fake_a',
94                     substrs = ['%d' % fake_a_val])
95         
96         # check access to members by index
97         self.expect('frame variable f00_1[1]',
98                     substrs = ['%d' % fake_a_val])
99         
100         # put synthetic children in summary in several combinations
101         self.runCmd("type summary add --summary-string \"fake_a=${svar.fake_a}\" foo")
102         self.expect('frame variable f00_1',
103                     substrs = ['fake_a=%d' % fake_a_val])
104         self.runCmd("type summary add --summary-string \"fake_a=${svar[1]}\" foo")
105         self.expect('frame variable f00_1',
106                     substrs = ['fake_a=%d' % fake_a_val])
107         
108         # clear the summary
109         self.runCmd("type summary delete foo")
110
111         # check that the caching does not span beyond the stopoint
112         self.runCmd("n")
113
114         if process.GetByteOrder() == lldb.eByteOrderLittle:
115             fake_a_val = 0x02000000
116         else:
117             fake_a_val = 0x00000200
118
119         self.expect("frame variable f00_1",
120                     substrs = ['r = 34',
121                                'fake_a = %d' % fake_a_val,
122                                'a = 2']);
123
124         # check that altering the object also alters fake_a
125         self.runCmd("expr f00_1.a = 280")
126
127         if process.GetByteOrder() == lldb.eByteOrderLittle:
128             fake_a_val = 0x02000001
129         else:
130             fake_a_val = 0x00011800
131
132         self.expect("frame variable f00_1",
133                     substrs = ['r = 34',
134                                'fake_a = %d' % fake_a_val,
135                                'a = 280']);
136
137         # check that expanding a pointer does the right thing
138         if process.GetByteOrder() == lldb.eByteOrderLittle:
139             fake_a_val = 0x0d000000
140         else:
141             fake_a_val = 0x00000c00
142
143         self.expect("frame variable --ptr-depth 1 f00_ptr",
144                     substrs = ['r = 45',
145                                'fake_a = %d' % fake_a_val,
146                                'a = 12'])
147         
148         # now add a filter.. it should fail
149         self.expect("type filter add foo --child b --child j", error=True,
150                 substrs = ['cannot add'])
151         
152         # we get the synth again..
153         self.expect('frame variable f00_1', matching=False,
154             substrs = ['b = 1',
155                        'j = 17'])
156         self.expect("frame variable --ptr-depth 1 f00_ptr",
157                     substrs = ['r = 45',
158                                'fake_a = %d' % fake_a_val,
159                                'a = 12'])
160         
161         # now delete the synth and add the filter
162         self.runCmd("type synth delete foo")
163         self.runCmd("type filter add foo --child b --child j")
164         
165         self.expect('frame variable f00_1',
166                         substrs = ['b = 2',
167                                    'j = 18'])
168         self.expect("frame variable --ptr-depth 1 f00_ptr", matching=False,
169                     substrs = ['r = 45',
170                                'fake_a = %d' % fake_a_val,
171                                'a = 12'])
172         
173         # now add the synth and it should fail
174         self.expect("type synth add -l fooSynthProvider foo", error=True,
175                     substrs = ['cannot add'])
176         
177         # check the listing
178         self.expect('type synth list', matching=False,
179                     substrs = ['foo',
180                                'Python class fooSynthProvider'])
181         self.expect('type filter list', 
182                     substrs = ['foo',
183                                '.b',
184                                '.j'])
185         
186         # delete the filter, add the synth
187         self.runCmd("type filter delete foo")
188         self.runCmd("type synth add -l fooSynthProvider foo")
189         
190         self.expect('frame variable f00_1', matching=False,
191                     substrs = ['b = 2',
192                                'j = 18'])
193         self.expect("frame variable --ptr-depth 1 f00_ptr", 
194                     substrs = ['r = 45',
195                                'fake_a = %d' % fake_a_val,
196                                'a = 12'])
197
198         # check the listing
199         self.expect('type synth list',
200                     substrs = ['foo',
201                                'Python class fooSynthProvider'])
202         self.expect('type filter list', matching=False,
203                     substrs = ['foo',
204                                '.b',
205                                '.j'])
206         
207         # delete the synth and check that we get good output
208         self.runCmd("type synth delete foo")
209         
210         self.expect("frame variable f00_1",
211                     substrs = ['a = 280',
212                                'b = 2',
213                                'j = 18']);
214
215         self.expect("frame variable f00_1", matching=False,
216                 substrs = ['fake_a = '])
217
218     def rdar10960550_formatter_commands(self):
219         """Test that synthetic children persist stoppoints."""
220         self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
221
222         # The second breakpoint is on a multi-line expression, so the comment can't be on the right line...
223         lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line2, num_expected_locations=1, loc_exact=False)
224         lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line3, num_expected_locations=1, loc_exact=True)
225
226         self.runCmd("run", RUN_SUCCEEDED)
227
228         # The stop reason of the thread should be breakpoint.
229         self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
230             substrs = ['stopped',
231                        'stop reason = breakpoint'])
232
233         # This is the function to remove the custom formats in order to have a
234         # clean slate for the next test case.
235         def cleanup():
236             self.runCmd('type format clear', check=False)
237             self.runCmd('type summary clear', check=False)
238             self.runCmd('type filter clear', check=False)
239             self.runCmd('type synth clear', check=False)
240
241         # Execute the cleanup function during test case tear down.
242         self.addTearDownHook(cleanup)
243
244         self.runCmd("command script import ./ftsp.py --allow-reload")
245         self.runCmd("type synth add -l ftsp.ftsp wrapint")
246
247         # we need to check that the VO is properly updated so that the same synthetic children are reused
248         # but their values change correctly across stop-points - in order to do this, self.runCmd("next")
249         # does not work because it forces a wipe of the stack frame - this is why we are using this more contrived
250         # mechanism to achieve our goal of preserving test_cast as a VO
251         test_cast = self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame().FindVariable('test_cast')
252
253         str_cast = str(test_cast)
254
255         if self.TraceOn():
256              print(str_cast)
257
258         self.assertTrue(str_cast.find('A') != -1, 'could not find A in output')
259         self.assertTrue(str_cast.find('B') != -1, 'could not find B in output')
260         self.assertTrue(str_cast.find('C') != -1, 'could not find C in output')
261         self.assertTrue(str_cast.find('D') != -1, 'could not find D in output')
262         self.assertTrue(str_cast.find("4 = '\\0'") != -1, 'could not find item 4 == 0')
263
264         self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread().StepOver()
265
266         str_cast = str(test_cast)
267
268         if self.TraceOn():
269              print(str_cast)
270
271         # we detect that all the values of the child objects have changed - but the counter-generated item
272         # is still fixed at 0 because it is cached - this would fail if update(self): in ftsp returned False
273         # or if synthetic children were not being preserved
274         self.assertTrue(str_cast.find('Q') != -1, 'could not find Q in output')
275         self.assertTrue(str_cast.find('X') != -1, 'could not find X in output')
276         self.assertTrue(str_cast.find('T') != -1, 'could not find T in output')
277         self.assertTrue(str_cast.find('F') != -1, 'could not find F in output')
278         self.assertTrue(str_cast.find("4 = '\\0'") != -1, 'could not find item 4 == 0')