• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1"""
2Test using LLDB data formatters with frozen objects coming from the expression parser.
3"""
4
5
6
7import lldb
8from lldbsuite.test.decorators import *
9from lldbsuite.test.lldbtest import *
10from lldbsuite.test import lldbutil
11
12
13class ExprFormattersTestCase(TestBase):
14
15    mydir = TestBase.compute_mydir(__file__)
16
17    def setUp(self):
18        # Call super's setUp().
19        TestBase.setUp(self)
20        # Find the line number to break for main.cpp.
21        self.line = line_number('main.cpp',
22                                '// Stop here')
23
24    @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr21765")
25    @skipIfTargetAndroid()  # skipping to avoid crashing the test runner
26    @expectedFailureAndroid('llvm.org/pr24691')  # we hit an assertion in clang
27    def test(self):
28        """Test expr + formatters for good interoperability."""
29        self.build()
30
31        # This is the function to remove the custom formats in order to have a
32        # clean slate for the next test case.
33        def cleanup():
34            self.runCmd('type summary clear', check=False)
35            self.runCmd('type synthetic clear', check=False)
36
37        # Execute the cleanup function during test case tear down.
38        self.addTearDownHook(cleanup)
39
40        """Test expr + formatters for good interoperability."""
41        self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET)
42
43        lldbutil.run_break_set_by_file_and_line(
44            self, "main.cpp", self.line, loc_exact=True)
45
46        self.runCmd("run", RUN_SUCCEEDED)
47        self.runCmd("command script import formatters.py")
48        self.runCmd("command script import foosynth.py")
49
50        if self.TraceOn():
51            self.runCmd("frame variable foo1 --show-types")
52            self.runCmd("frame variable foo1.b --show-types")
53            self.runCmd("frame variable foo1.b.b_ref --show-types")
54
55        self.filecheck("expression --show-types -- *(new_foo(47))", __file__,
56                '-check-prefix=EXPR-TYPES-NEW-FOO')
57        # EXPR-TYPES-NEW-FOO: (foo) ${{.*}} = {
58        # EXPR-TYPES-NEW-FOO-NEXT:   (int) a = 47
59        # EXPR-TYPES-NEW-FOO-NEXT:   (int *) a_ptr = 0x
60        # EXPR-TYPES-NEW-FOO-NEXT:   (bar) b = {
61        # EXPR-TYPES-NEW-FOO-NEXT:     (int) i = 94
62        # EXPR-TYPES-NEW-FOO-NEXT:     (int *) i_ptr = 0x
63        # EXPR-TYPES-NEW-FOO-NEXT:     (baz) b = {
64        # EXPR-TYPES-NEW-FOO-NEXT:       (int) h = 97
65        # EXPR-TYPES-NEW-FOO-NEXT:       (int) k = 99
66        # EXPR-TYPES-NEW-FOO-NEXT:     }
67        # EXPR-TYPES-NEW-FOO-NEXT:     (baz &) b_ref = 0x
68        # EXPR-TYPES-NEW-FOO-NEXT:   }
69        # EXPR-TYPES-NEW-FOO-NEXT: }
70
71
72        self.runCmd("type summary add -F formatters.foo_SummaryProvider3 foo")
73        self.filecheck("expression foo1", __file__, '-check-prefix=EXPR-FOO1opts')
74        # EXPR-FOO1opts: (foo) $
75        # EXPR-FOO1opts-SAME: a = 12
76        # EXPR-FOO1opts-SAME: a_ptr = {{[0-9]+}} -> 13
77        # EXPR-FOO1opts-SAME: i = 24
78        # EXPR-FOO1opts-SAME: i_ptr = {{[0-9]+}} -> 25
79        # EXPR-FOO1opts-SAME: b_ref = {{[0-9]+}}
80        # EXPR-FOO1opts-SAME: h = 27
81        # EXPR-FOO1opts-SAME: k = 29
82        # EXPR-FOO1opts-SAME: WITH_OPTS
83
84        self.runCmd("type summary delete foo")
85
86        self.runCmd("type summary add -F formatters.foo_SummaryProvider foo")
87
88        self.expect("expression new_int(12)",
89                    substrs=['(int *) $', ' = 0x'])
90
91        self.runCmd(
92            "type summary add -s \"${var%pointer} -> ${*var%decimal}\" \"int *\"")
93
94        self.expect("expression new_int(12)",
95                    substrs=['(int *) $', '= 0x', ' -> 12'])
96
97        self.expect("expression foo1.a_ptr",
98                    substrs=['(int *) $', '= 0x', ' -> 13'])
99
100        self.filecheck("expression foo1", __file__, '-check-prefix=EXPR-FOO1')
101        # EXPR-FOO1: (foo) $
102        # EXPR-FOO1-SAME: a = 12
103        # EXPR-FOO1-SAME: a_ptr = {{[0-9]+}} -> 13
104        # EXPR-FOO1-SAME: i = 24
105        # EXPR-FOO1-SAME: i_ptr = {{[0-9]+}} -> 25
106        # EXPR-FOO1-SAME: b_ref = {{[0-9]+}}
107        # EXPR-FOO1-SAME: h = 27
108        # EXPR-FOO1-SAME: k = 29
109
110        self.filecheck("expression --ptr-depth=1 -- new_foo(47)", __file__,
111                '-check-prefix=EXPR-PTR-DEPTH1')
112        # EXPR-PTR-DEPTH1: (foo *) $
113        # EXPR-PTR-DEPTH1-SAME: a = 47
114        # EXPR-PTR-DEPTH1-SAME: a_ptr = {{[0-9]+}} -> 48
115        # EXPR-PTR-DEPTH1-SAME: i = 94
116        # EXPR-PTR-DEPTH1-SAME: i_ptr = {{[0-9]+}} -> 95
117
118        self.filecheck("expression foo2", __file__, '-check-prefix=EXPR-FOO2')
119        # EXPR-FOO2: (foo) $
120        # EXPR-FOO2-SAME: a = 121
121        # EXPR-FOO2-SAME: a_ptr = {{[0-9]+}} -> 122
122        # EXPR-FOO2-SAME: i = 242
123        # EXPR-FOO2-SAME: i_ptr = {{[0-9]+}} -> 243
124        # EXPR-FOO2-SAME: h = 245
125        # EXPR-FOO2-SAME: k = 247
126
127        object_name = self.res.GetOutput()
128        object_name = object_name[7:]
129        object_name = object_name[0:object_name.find(' =')]
130
131        self.filecheck("frame variable foo2", __file__, '-check-prefix=VAR-FOO2')
132        # VAR-FOO2: (foo) foo2
133        # VAR-FOO2-SAME: a = 121
134        # VAR-FOO2-SAME: a_ptr = {{[0-9]+}} -> 122
135        # VAR-FOO2-SAME: i = 242
136        # VAR-FOO2-SAME: i_ptr = {{[0-9]+}} -> 243
137        # VAR-FOO2-SAME: h = 245
138        # VAR-FOO2-SAME: k = 247
139
140        # The object is the same as foo2, so use the EXPR-FOO2 checks.
141        self.filecheck("expression $" + object_name, __file__,
142                '-check-prefix=EXPR-FOO2')
143
144        self.runCmd("type summary delete foo")
145        self.runCmd(
146            "type synthetic add --python-class foosynth.FooSyntheticProvider foo")
147
148        self.expect("expression --show-types -- $" + object_name,
149                    substrs=['(foo) $', ' = {', '(int) *i_ptr = 243'])
150
151        self.runCmd("n")
152        self.runCmd("n")
153
154        self.runCmd("type synthetic delete foo")
155        self.runCmd("type summary add -F formatters.foo_SummaryProvider foo")
156
157        self.expect(
158            "expression foo2",
159            substrs=[
160                '(foo) $',
161                'a = 7777',
162                'a_ptr = ',
163                ' -> 122',
164                'i = 242',
165                'i_ptr = ',
166                ' -> 8888'])
167
168        self.expect("expression $" + object_name + '.a',
169                    substrs=['7777'])
170
171        self.expect("expression *$" + object_name + '.b.i_ptr',
172                    substrs=['8888'])
173
174        self.expect(
175            "expression $" +
176            object_name,
177            substrs=[
178                '(foo) $',
179                'a = 121',
180                'a_ptr = ',
181                ' -> 122',
182                'i = 242',
183                'i_ptr = ',
184                ' -> 8888',
185                'h = 245',
186                'k = 247'])
187
188        self.runCmd("type summary delete foo")
189        self.runCmd(
190            "type synthetic add --python-class foosynth.FooSyntheticProvider foo")
191
192        self.expect("expression --show-types -- $" + object_name,
193                    substrs=['(foo) $', ' = {', '(int) *i_ptr = 8888'])
194
195        self.runCmd("n")
196
197        self.runCmd("type synthetic delete foo")
198        self.runCmd("type summary add -F formatters.foo_SummaryProvider foo")
199
200        self.expect(
201            "expression $" +
202            object_name,
203            substrs=[
204                '(foo) $',
205                'a = 121',
206                'a_ptr = ',
207                ' -> 122',
208                'i = 242',
209                'i_ptr = ',
210                ' -> 8888',
211                'k = 247'])
212
213        process = self.dbg.GetSelectedTarget().GetProcess()
214        thread = process.GetThreadAtIndex(0)
215        frame = thread.GetSelectedFrame()
216
217        frozen = frame.EvaluateExpression("$" + object_name + ".a_ptr")
218
219        a_data = frozen.GetPointeeData()
220
221        error = lldb.SBError()
222        self.assertTrue(
223            a_data.GetUnsignedInt32(
224                error,
225                0) == 122,
226            '*a_ptr = 122')
227
228        ret = line_number("main.cpp", "Done initializing")
229        self.runCmd("thread until " + str(ret))
230
231        self.expect("frame variable numbers",
232                    substrs=['1', '2', '3', '4', '5'])
233
234        self.expect("expression numbers",
235                    substrs=['1', '2', '3', '4', '5'])
236
237        frozen = frame.EvaluateExpression("&numbers")
238
239        a_data = frozen.GetPointeeData(0, 1)
240
241        self.assertTrue(
242            a_data.GetUnsignedInt32(
243                error,
244                0) == 1,
245            'numbers[0] == 1')
246        self.assertTrue(
247            a_data.GetUnsignedInt32(
248                error,
249                4) == 2,
250            'numbers[1] == 2')
251        self.assertTrue(
252            a_data.GetUnsignedInt32(
253                error,
254                8) == 3,
255            'numbers[2] == 3')
256        self.assertTrue(
257            a_data.GetUnsignedInt32(
258                error,
259                12) == 4,
260            'numbers[3] == 4')
261        self.assertTrue(
262            a_data.GetUnsignedInt32(
263                error,
264                16) == 5,
265            'numbers[4] == 5')
266
267        frozen = frame.EvaluateExpression("numbers")
268
269        a_data = frozen.GetData()
270
271        self.assertTrue(
272            a_data.GetUnsignedInt32(
273                error,
274                0) == 1,
275            'numbers[0] == 1')
276        self.assertTrue(
277            a_data.GetUnsignedInt32(
278                error,
279                4) == 2,
280            'numbers[1] == 2')
281        self.assertTrue(
282            a_data.GetUnsignedInt32(
283                error,
284                8) == 3,
285            'numbers[2] == 3')
286        self.assertTrue(
287            a_data.GetUnsignedInt32(
288                error,
289                12) == 4,
290            'numbers[3] == 4')
291        self.assertTrue(
292            a_data.GetUnsignedInt32(
293                error,
294                16) == 5,
295            'numbers[4] == 5')
296