xref: /llvm-project/lldb/test/API/python_api/frame/get-variables/TestGetVariables.py (revision 9c2468821ec51defd09c246fea4a47886fff8c01)
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    def setUp(self):
21        # Call super's setUp().
22        TestBase.setUp(self)
23        self.source = "main.c"
24
25    def verify_variable_names(self, description, value_list, names):
26        copy_names = list(names)
27        actual_names = get_names_from_value_list(value_list)
28        for name in actual_names:
29            if name in copy_names:
30                copy_names.remove(name)
31            else:
32                self.assertTrue(False, "didn't find '%s' in %s" % (name, copy_names))
33        self.assertEqual(
34            len(copy_names),
35            0,
36            "%s: we didn't find variables: %s in value list (%s)"
37            % (description, copy_names, actual_names),
38        )
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.assertGreaterEqual(breakpoint1.GetNumLocations(), 1, PROCESS_IS_VALID)
60        self.assertGreaterEqual(breakpoint2.GetNumLocations(), 1, PROCESS_IS_VALID)
61        self.assertGreaterEqual(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        )
72        self.assertTrue(process, PROCESS_IS_VALID)
73
74        threads = lldbutil.get_threads_stopped_at_breakpoint(process, breakpoint1)
75        self.assertEqual(
76            len(threads), 1, "There should be a thread stopped at breakpoint 1"
77        )
78
79        thread = threads[0]
80        self.assertTrue(thread.IsValid(), "Thread must be valid")
81        frame = thread.GetFrameAtIndex(0)
82        self.assertTrue(frame.IsValid(), "Frame must be valid")
83
84        arg_names = ["argc", "argv"]
85        local_names = ["i", "j", "k"]
86        static_names = ["static_var", "g_global_var", "g_static_var"]
87        breakpoint1_locals = ["i"]
88        breakpoint1_statics = ["static_var"]
89        num_args = len(arg_names)
90        num_locals = len(local_names)
91        num_statics = len(static_names)
92        args_yes = True
93        args_no = False
94        locals_yes = True
95        locals_no = False
96        statics_yes = True
97        statics_no = False
98        in_scopy_only = True
99        ignore_scope = False
100
101        # Verify if we ask for only arguments that we got what we expect
102        vars = frame.GetVariables(args_yes, locals_no, statics_no, ignore_scope)
103        self.assertEqual(
104            vars.GetSize(),
105            num_args,
106            "There should be %i arguments, but we are reporting %i"
107            % (num_args, vars.GetSize()),
108        )
109        self.verify_variable_names("check names of arguments", vars, arg_names)
110        self.assertEqual(
111            len(arg_names),
112            num_args,
113            "make sure verify_variable_names() didn't mutate list",
114        )
115
116        # Verify if we ask for only locals that we got what we expect
117        vars = frame.GetVariables(args_no, locals_yes, statics_no, ignore_scope)
118        self.assertEqual(
119            vars.GetSize(),
120            num_locals,
121            "There should be %i local variables, but we are reporting %i"
122            % (num_locals, vars.GetSize()),
123        )
124        self.verify_variable_names("check names of locals", vars, local_names)
125
126        # Verify if we ask for only statics that we got what we expect
127        vars = frame.GetVariables(args_no, locals_no, statics_yes, ignore_scope)
128        print("statics: ", str(vars))
129        self.assertEqual(
130            vars.GetSize(),
131            num_statics,
132            "There should be %i static variables, but we are reporting %i"
133            % (num_statics, vars.GetSize()),
134        )
135        self.verify_variable_names("check names of statics", vars, static_names)
136
137        # Verify if we ask for arguments and locals that we got what we expect
138        vars = frame.GetVariables(args_yes, locals_yes, statics_no, ignore_scope)
139        desc = "arguments + locals"
140        names = arg_names + local_names
141        count = len(names)
142        self.assertEqual(
143            vars.GetSize(),
144            count,
145            "There should be %i %s (%s) but we are reporting %i (%s)"
146            % (count, desc, names, vars.GetSize(), get_names_from_value_list(vars)),
147        )
148        self.verify_variable_names("check names of %s" % (desc), vars, names)
149
150        # Verify if we ask for arguments and statics that we got what we expect
151        vars = frame.GetVariables(args_yes, locals_no, statics_yes, ignore_scope)
152        desc = "arguments + statics"
153        names = arg_names + static_names
154        count = len(names)
155        self.assertEqual(
156            vars.GetSize(),
157            count,
158            "There should be %i %s (%s) but we are reporting %i (%s)"
159            % (count, desc, names, vars.GetSize(), get_names_from_value_list(vars)),
160        )
161        self.verify_variable_names("check names of %s" % (desc), vars, names)
162
163        # Verify if we ask for locals and statics that we got what we expect
164        vars = frame.GetVariables(args_no, locals_yes, statics_yes, ignore_scope)
165        desc = "locals + statics"
166        names = local_names + static_names
167        count = len(names)
168        self.assertEqual(
169            vars.GetSize(),
170            count,
171            "There should be %i %s (%s) but we are reporting %i (%s)"
172            % (count, desc, names, vars.GetSize(), get_names_from_value_list(vars)),
173        )
174        self.verify_variable_names("check names of %s" % (desc), vars, names)
175
176        # Verify if we ask for arguments, locals and statics that we got what
177        # we expect
178        vars = frame.GetVariables(args_yes, locals_yes, statics_yes, ignore_scope)
179        desc = "arguments + locals + statics"
180        names = arg_names + local_names + static_names
181        count = len(names)
182        self.assertEqual(
183            vars.GetSize(),
184            count,
185            "There should be %i %s (%s) but we are reporting %i (%s)"
186            % (count, desc, names, vars.GetSize(), get_names_from_value_list(vars)),
187        )
188        self.verify_variable_names("check names of %s" % (desc), vars, names)
189
190        # Verify if we ask for in scope locals that we got what we expect
191        vars = frame.GetVariables(args_no, locals_yes, statics_no, in_scopy_only)
192        desc = "in scope locals at breakpoint 1"
193        names = ["i"]
194        count = len(names)
195        self.assertEqual(
196            vars.GetSize(),
197            count,
198            "There should be %i %s (%s) but we are reporting %i (%s)"
199            % (count, desc, names, vars.GetSize(), get_names_from_value_list(vars)),
200        )
201        self.verify_variable_names("check names of %s" % (desc), vars, names)
202
203        # Continue to breakpoint 2
204        process.Continue()
205
206        threads = lldbutil.get_threads_stopped_at_breakpoint(process, breakpoint2)
207        self.assertEqual(
208            len(threads), 1, "There should be a thread stopped at breakpoint 2"
209        )
210
211        thread = threads[0]
212        self.assertTrue(thread.IsValid(), "Thread must be valid")
213        frame = thread.GetFrameAtIndex(0)
214        self.assertTrue(frame.IsValid(), "Frame must be valid")
215
216        # Verify if we ask for in scope locals that we got what we expect
217        vars = frame.GetVariables(args_no, locals_yes, statics_no, in_scopy_only)
218        desc = "in scope locals at breakpoint 2"
219        names = ["i", "j"]
220        count = len(names)
221        self.assertEqual(
222            vars.GetSize(),
223            count,
224            "There should be %i %s (%s) but we are reporting %i (%s)"
225            % (count, desc, names, vars.GetSize(), get_names_from_value_list(vars)),
226        )
227        self.verify_variable_names("check names of %s" % (desc), vars, names)
228
229        # Continue to breakpoint 3
230        process.Continue()
231
232        threads = lldbutil.get_threads_stopped_at_breakpoint(process, breakpoint3)
233        self.assertEqual(
234            len(threads), 1, "There should be a thread stopped at breakpoint 3"
235        )
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(args_no, locals_yes, statics_no, in_scopy_only)
244        desc = "in scope locals at breakpoint 3"
245        names = ["i", "j", "k"]
246        count = len(names)
247        self.assertEqual(
248            vars.GetSize(),
249            count,
250            "There should be %i %s (%s) but we are reporting %i (%s)"
251            % (count, desc, names, vars.GetSize(), get_names_from_value_list(vars)),
252        )
253        self.verify_variable_names("check names of %s" % (desc), vars, names)
254