xref: /llvm-project/lldb/test/API/python_api/frame/get-variables/TestGetVariables.py (revision 193259cbcec77add8e189c4dedeefb15fef50d5e)
1"""
2Test that SBFrame::GetVariables() calls work correctly.
3"""
4
5import lldb
6from lldbsuite.test.decorators import *
7from lldbsuite.test.lldbtest import *
8from lldbsuite.test import lldbplatform
9from lldbsuite.test import lldbutil
10
11
12def get_names_from_value_list(value_list):
13    names = list()
14    for value in value_list:
15        names.append(value.GetName())
16    return names
17
18
19class TestGetVariables(TestBase):
20
21    def setUp(self):
22        # Call super's setUp().
23        TestBase.setUp(self)
24        self.source = 'main.c'
25
26    def verify_variable_names(self, description, value_list, names):
27        copy_names = list(names)
28        actual_names = get_names_from_value_list(value_list)
29        for name in actual_names:
30            if name in copy_names:
31                copy_names.remove(name)
32            else:
33                self.assertTrue(
34                    False, "didn't find '%s' in %s" %
35                    (name, copy_names))
36        self.assertEqual(
37            len(copy_names), 0, "%s: we didn't find variables: %s in value list (%s)" %
38            (description, copy_names, actual_names))
39
40    def test(self):
41        self.build()
42
43        # Set debugger into synchronous mode
44        self.dbg.SetAsync(False)
45
46        # Create a target by the debugger.
47        exe = self.getBuildArtifact("a.out")
48        target = self.dbg.CreateTarget(exe)
49        self.assertTrue(target, VALID_TARGET)
50
51        line1 = line_number(self.source, '// breakpoint 1')
52        line2 = line_number(self.source, '// breakpoint 2')
53        line3 = line_number(self.source, '// breakpoint 3')
54
55        breakpoint1 = target.BreakpointCreateByLocation(self.source, line1)
56        breakpoint2 = target.BreakpointCreateByLocation(self.source, line2)
57        breakpoint3 = target.BreakpointCreateByLocation(self.source, line3)
58
59        self.assertTrue(breakpoint1.GetNumLocations() >= 1, PROCESS_IS_VALID)
60        self.assertTrue(breakpoint2.GetNumLocations() >= 1, PROCESS_IS_VALID)
61        self.assertTrue(breakpoint3.GetNumLocations() >= 1, PROCESS_IS_VALID)
62
63        # Register our shared libraries for remote targets so they get
64        # automatically uploaded
65        arguments = None
66        environment = None
67
68        # Now launch the process, and do not stop at entry point.
69        process = target.LaunchSimple(
70            arguments, environment, self.get_process_working_directory())
71        self.assertTrue(process, PROCESS_IS_VALID)
72
73        threads = lldbutil.get_threads_stopped_at_breakpoint(
74            process, breakpoint1)
75        self.assertEqual(
76            len(threads),
77            1,
78            "There should be a thread stopped at breakpoint 1")
79
80        thread = threads[0]
81        self.assertTrue(thread.IsValid(), "Thread must be valid")
82        frame = thread.GetFrameAtIndex(0)
83        self.assertTrue(frame.IsValid(), "Frame must be valid")
84
85        arg_names = ['argc', 'argv']
86        local_names = ['i', 'j', 'k']
87        static_names = ['static_var', 'g_global_var', 'g_static_var']
88        breakpoint1_locals = ['i']
89        breakpoint1_statics = ['static_var']
90        num_args = len(arg_names)
91        num_locals = len(local_names)
92        num_statics = len(static_names)
93        args_yes = True
94        args_no = False
95        locals_yes = True
96        locals_no = False
97        statics_yes = True
98        statics_no = False
99        in_scopy_only = True
100        ignore_scope = False
101
102        # Verify if we ask for only arguments that we got what we expect
103        vars = frame.GetVariables(
104            args_yes, locals_no, statics_no, ignore_scope)
105        self.assertEqual(
106            vars.GetSize(),
107            num_args,
108            "There should be %i arguments, but we are reporting %i" %
109            (num_args,
110             vars.GetSize()))
111        self.verify_variable_names("check names of arguments", vars, arg_names)
112        self.assertEqual(
113            len(arg_names),
114            num_args,
115            "make sure verify_variable_names() didn't mutate list")
116
117        # Verify if we ask for only locals that we got what we expect
118        vars = frame.GetVariables(
119            args_no, locals_yes, statics_no, ignore_scope)
120        self.assertEqual(
121            vars.GetSize(),
122            num_locals,
123            "There should be %i local variables, but we are reporting %i" %
124            (num_locals,
125             vars.GetSize()))
126        self.verify_variable_names("check names of locals", vars, local_names)
127
128        # Verify if we ask for only statics that we got what we expect
129        vars = frame.GetVariables(
130            args_no, locals_no, statics_yes, ignore_scope)
131        print('statics: ', str(vars))
132        self.assertEqual(
133            vars.GetSize(),
134            num_statics,
135            "There should be %i static variables, but we are reporting %i" %
136            (num_statics,
137             vars.GetSize()))
138        self.verify_variable_names(
139            "check names of statics", vars, static_names)
140
141        # Verify if we ask for arguments and locals that we got what we expect
142        vars = frame.GetVariables(
143            args_yes, locals_yes, statics_no, ignore_scope)
144        desc = 'arguments + locals'
145        names = arg_names + local_names
146        count = len(names)
147        self.assertEqual(
148            vars.GetSize(),
149            count,
150            "There should be %i %s (%s) but we are reporting %i (%s)" %
151            (count,
152             desc,
153             names,
154             vars.GetSize(),
155             get_names_from_value_list(vars)))
156        self.verify_variable_names("check names of %s" % (desc), vars, names)
157
158        # Verify if we ask for arguments and statics that we got what we expect
159        vars = frame.GetVariables(
160            args_yes, locals_no, statics_yes, ignore_scope)
161        desc = 'arguments + statics'
162        names = arg_names + static_names
163        count = len(names)
164        self.assertEqual(
165            vars.GetSize(),
166            count,
167            "There should be %i %s (%s) but we are reporting %i (%s)" %
168            (count,
169             desc,
170             names,
171             vars.GetSize(),
172             get_names_from_value_list(vars)))
173        self.verify_variable_names("check names of %s" % (desc), vars, names)
174
175        # Verify if we ask for locals and statics that we got what we expect
176        vars = frame.GetVariables(
177            args_no, locals_yes, statics_yes, ignore_scope)
178        desc = 'locals + statics'
179        names = local_names + static_names
180        count = len(names)
181        self.assertEqual(
182            vars.GetSize(),
183            count,
184            "There should be %i %s (%s) but we are reporting %i (%s)" %
185            (count,
186             desc,
187             names,
188             vars.GetSize(),
189             get_names_from_value_list(vars)))
190        self.verify_variable_names("check names of %s" % (desc), vars, names)
191
192        # Verify if we ask for arguments, locals and statics that we got what
193        # we expect
194        vars = frame.GetVariables(
195            args_yes, locals_yes, statics_yes, ignore_scope)
196        desc = 'arguments + locals + statics'
197        names = arg_names + local_names + static_names
198        count = len(names)
199        self.assertEqual(
200            vars.GetSize(),
201            count,
202            "There should be %i %s (%s) but we are reporting %i (%s)" %
203            (count,
204             desc,
205             names,
206             vars.GetSize(),
207             get_names_from_value_list(vars)))
208        self.verify_variable_names("check names of %s" % (desc), vars, names)
209
210        # Verify if we ask for in scope locals that we got what we expect
211        vars = frame.GetVariables(
212            args_no, locals_yes, statics_no, in_scopy_only)
213        desc = 'in scope locals at breakpoint 1'
214        names = ['i']
215        count = len(names)
216        self.assertEqual(
217            vars.GetSize(),
218            count,
219            "There should be %i %s (%s) but we are reporting %i (%s)" %
220            (count,
221             desc,
222             names,
223             vars.GetSize(),
224             get_names_from_value_list(vars)))
225        self.verify_variable_names("check names of %s" % (desc), vars, names)
226
227        # Continue to breakpoint 2
228        process.Continue()
229
230        threads = lldbutil.get_threads_stopped_at_breakpoint(
231            process, breakpoint2)
232        self.assertEqual(
233            len(threads),
234            1,
235            "There should be a thread stopped at breakpoint 2")
236
237        thread = threads[0]
238        self.assertTrue(thread.IsValid(), "Thread must be valid")
239        frame = thread.GetFrameAtIndex(0)
240        self.assertTrue(frame.IsValid(), "Frame must be valid")
241
242        # Verify if we ask for in scope locals that we got what we expect
243        vars = frame.GetVariables(
244            args_no, locals_yes, statics_no, in_scopy_only)
245        desc = 'in scope locals at breakpoint 2'
246        names = ['i', 'j']
247        count = len(names)
248        self.assertEqual(
249            vars.GetSize(),
250            count,
251            "There should be %i %s (%s) but we are reporting %i (%s)" %
252            (count,
253             desc,
254             names,
255             vars.GetSize(),
256             get_names_from_value_list(vars)))
257        self.verify_variable_names("check names of %s" % (desc), vars, names)
258
259        # Continue to breakpoint 3
260        process.Continue()
261
262        threads = lldbutil.get_threads_stopped_at_breakpoint(
263            process, breakpoint3)
264        self.assertEqual(
265            len(threads),
266            1,
267            "There should be a thread stopped at breakpoint 3")
268
269        thread = threads[0]
270        self.assertTrue(thread.IsValid(), "Thread must be valid")
271        frame = thread.GetFrameAtIndex(0)
272        self.assertTrue(frame.IsValid(), "Frame must be valid")
273
274        # Verify if we ask for in scope locals that we got what we expect
275        vars = frame.GetVariables(
276            args_no, locals_yes, statics_no, in_scopy_only)
277        desc = 'in scope locals at breakpoint 3'
278        names = ['i', 'j', 'k']
279        count = len(names)
280        self.assertEqual(
281            vars.GetSize(),
282            count,
283            "There should be %i %s (%s) but we are reporting %i (%s)" %
284            (count,
285             desc,
286             names,
287             vars.GetSize(),
288             get_names_from_value_list(vars)))
289        self.verify_variable_names("check names of %s" % (desc), vars, names)
290