| """ |
| Test that SBFrame::GetVariables() calls work correctly. |
| """ |
| |
| from __future__ import print_function |
| |
| |
| import os |
| import time |
| import lldb |
| from lldbsuite.test.decorators import * |
| from lldbsuite.test.lldbtest import * |
| from lldbsuite.test import lldbplatform |
| from lldbsuite.test import lldbutil |
| |
| |
| def get_names_from_value_list(value_list): |
| names = list() |
| for value in value_list: |
| names.append(value.GetName()) |
| return names |
| |
| |
| class TestGetVariables(TestBase): |
| |
| mydir = TestBase.compute_mydir(__file__) |
| |
| def setUp(self): |
| # Call super's setUp(). |
| TestBase.setUp(self) |
| self.source = 'main.c' |
| |
| def verify_variable_names(self, description, value_list, names): |
| copy_names = list(names) |
| actual_names = get_names_from_value_list(value_list) |
| for name in actual_names: |
| if name in copy_names: |
| copy_names.remove(name) |
| else: |
| self.assertTrue( |
| False, "didn't find '%s' in %s" % |
| (name, copy_names)) |
| self.assertEqual( |
| len(copy_names), 0, "%s: we didn't find variables: %s in value list (%s)" % |
| (description, copy_names, actual_names)) |
| |
| def test(self): |
| self.build() |
| |
| # Set debugger into synchronous mode |
| self.dbg.SetAsync(False) |
| |
| # Create a target by the debugger. |
| exe = self.getBuildArtifact("a.out") |
| target = self.dbg.CreateTarget(exe) |
| self.assertTrue(target, VALID_TARGET) |
| |
| line1 = line_number(self.source, '// breakpoint 1') |
| line2 = line_number(self.source, '// breakpoint 2') |
| line3 = line_number(self.source, '// breakpoint 3') |
| |
| breakpoint1 = target.BreakpointCreateByLocation(self.source, line1) |
| breakpoint2 = target.BreakpointCreateByLocation(self.source, line2) |
| breakpoint3 = target.BreakpointCreateByLocation(self.source, line3) |
| |
| self.assertTrue(breakpoint1.GetNumLocations() >= 1, PROCESS_IS_VALID) |
| self.assertTrue(breakpoint2.GetNumLocations() >= 1, PROCESS_IS_VALID) |
| self.assertTrue(breakpoint3.GetNumLocations() >= 1, PROCESS_IS_VALID) |
| |
| # Register our shared libraries for remote targets so they get |
| # automatically uploaded |
| arguments = None |
| environment = None |
| |
| # Now launch the process, and do not stop at entry point. |
| process = target.LaunchSimple( |
| arguments, environment, self.get_process_working_directory()) |
| self.assertTrue(process, PROCESS_IS_VALID) |
| |
| threads = lldbutil.get_threads_stopped_at_breakpoint( |
| process, breakpoint1) |
| self.assertEqual( |
| len(threads), |
| 1, |
| "There should be a thread stopped at breakpoint 1") |
| |
| thread = threads[0] |
| self.assertTrue(thread.IsValid(), "Thread must be valid") |
| frame = thread.GetFrameAtIndex(0) |
| self.assertTrue(frame.IsValid(), "Frame must be valid") |
| |
| arg_names = ['argc', 'argv'] |
| local_names = ['i', 'j', 'k'] |
| static_names = ['static_var', 'g_global_var', 'g_static_var'] |
| breakpoint1_locals = ['i'] |
| breakpoint1_statics = ['static_var'] |
| num_args = len(arg_names) |
| num_locals = len(local_names) |
| num_statics = len(static_names) |
| args_yes = True |
| args_no = False |
| locals_yes = True |
| locals_no = False |
| statics_yes = True |
| statics_no = False |
| in_scopy_only = True |
| ignore_scope = False |
| |
| # Verify if we ask for only arguments that we got what we expect |
| vars = frame.GetVariables( |
| args_yes, locals_no, statics_no, ignore_scope) |
| self.assertEqual( |
| vars.GetSize(), |
| num_args, |
| "There should be %i arguments, but we are reporting %i" % |
| (num_args, |
| vars.GetSize())) |
| self.verify_variable_names("check names of arguments", vars, arg_names) |
| self.assertEqual( |
| len(arg_names), |
| num_args, |
| "make sure verify_variable_names() didn't mutate list") |
| |
| # Verify if we ask for only locals that we got what we expect |
| vars = frame.GetVariables( |
| args_no, locals_yes, statics_no, ignore_scope) |
| self.assertEqual( |
| vars.GetSize(), |
| num_locals, |
| "There should be %i local variables, but we are reporting %i" % |
| (num_locals, |
| vars.GetSize())) |
| self.verify_variable_names("check names of locals", vars, local_names) |
| |
| # Verify if we ask for only statics that we got what we expect |
| vars = frame.GetVariables( |
| args_no, locals_no, statics_yes, ignore_scope) |
| print('statics: ', str(vars)) |
| self.assertEqual( |
| vars.GetSize(), |
| num_statics, |
| "There should be %i static variables, but we are reporting %i" % |
| (num_statics, |
| vars.GetSize())) |
| self.verify_variable_names( |
| "check names of statics", vars, static_names) |
| |
| # Verify if we ask for arguments and locals that we got what we expect |
| vars = frame.GetVariables( |
| args_yes, locals_yes, statics_no, ignore_scope) |
| desc = 'arguments + locals' |
| names = arg_names + local_names |
| count = len(names) |
| self.assertEqual( |
| vars.GetSize(), |
| count, |
| "There should be %i %s (%s) but we are reporting %i (%s)" % |
| (count, |
| desc, |
| names, |
| vars.GetSize(), |
| get_names_from_value_list(vars))) |
| self.verify_variable_names("check names of %s" % (desc), vars, names) |
| |
| # Verify if we ask for arguments and statics that we got what we expect |
| vars = frame.GetVariables( |
| args_yes, locals_no, statics_yes, ignore_scope) |
| desc = 'arguments + statics' |
| names = arg_names + static_names |
| count = len(names) |
| self.assertEqual( |
| vars.GetSize(), |
| count, |
| "There should be %i %s (%s) but we are reporting %i (%s)" % |
| (count, |
| desc, |
| names, |
| vars.GetSize(), |
| get_names_from_value_list(vars))) |
| self.verify_variable_names("check names of %s" % (desc), vars, names) |
| |
| # Verify if we ask for locals and statics that we got what we expect |
| vars = frame.GetVariables( |
| args_no, locals_yes, statics_yes, ignore_scope) |
| desc = 'locals + statics' |
| names = local_names + static_names |
| count = len(names) |
| self.assertEqual( |
| vars.GetSize(), |
| count, |
| "There should be %i %s (%s) but we are reporting %i (%s)" % |
| (count, |
| desc, |
| names, |
| vars.GetSize(), |
| get_names_from_value_list(vars))) |
| self.verify_variable_names("check names of %s" % (desc), vars, names) |
| |
| # Verify if we ask for arguments, locals and statics that we got what |
| # we expect |
| vars = frame.GetVariables( |
| args_yes, locals_yes, statics_yes, ignore_scope) |
| desc = 'arguments + locals + statics' |
| names = arg_names + local_names + static_names |
| count = len(names) |
| self.assertEqual( |
| vars.GetSize(), |
| count, |
| "There should be %i %s (%s) but we are reporting %i (%s)" % |
| (count, |
| desc, |
| names, |
| vars.GetSize(), |
| get_names_from_value_list(vars))) |
| self.verify_variable_names("check names of %s" % (desc), vars, names) |
| |
| # Verify if we ask for in scope locals that we got what we expect |
| vars = frame.GetVariables( |
| args_no, locals_yes, statics_no, in_scopy_only) |
| desc = 'in scope locals at breakpoint 1' |
| names = ['i'] |
| count = len(names) |
| self.assertEqual( |
| vars.GetSize(), |
| count, |
| "There should be %i %s (%s) but we are reporting %i (%s)" % |
| (count, |
| desc, |
| names, |
| vars.GetSize(), |
| get_names_from_value_list(vars))) |
| self.verify_variable_names("check names of %s" % (desc), vars, names) |
| |
| # Continue to breakpoint 2 |
| process.Continue() |
| |
| threads = lldbutil.get_threads_stopped_at_breakpoint( |
| process, breakpoint2) |
| self.assertEqual( |
| len(threads), |
| 1, |
| "There should be a thread stopped at breakpoint 2") |
| |
| thread = threads[0] |
| self.assertTrue(thread.IsValid(), "Thread must be valid") |
| frame = thread.GetFrameAtIndex(0) |
| self.assertTrue(frame.IsValid(), "Frame must be valid") |
| |
| # Verify if we ask for in scope locals that we got what we expect |
| vars = frame.GetVariables( |
| args_no, locals_yes, statics_no, in_scopy_only) |
| desc = 'in scope locals at breakpoint 2' |
| names = ['i', 'j'] |
| count = len(names) |
| self.assertEqual( |
| vars.GetSize(), |
| count, |
| "There should be %i %s (%s) but we are reporting %i (%s)" % |
| (count, |
| desc, |
| names, |
| vars.GetSize(), |
| get_names_from_value_list(vars))) |
| self.verify_variable_names("check names of %s" % (desc), vars, names) |
| |
| # Continue to breakpoint 3 |
| process.Continue() |
| |
| threads = lldbutil.get_threads_stopped_at_breakpoint( |
| process, breakpoint3) |
| self.assertEqual( |
| len(threads), |
| 1, |
| "There should be a thread stopped at breakpoint 3") |
| |
| thread = threads[0] |
| self.assertTrue(thread.IsValid(), "Thread must be valid") |
| frame = thread.GetFrameAtIndex(0) |
| self.assertTrue(frame.IsValid(), "Frame must be valid") |
| |
| # Verify if we ask for in scope locals that we got what we expect |
| vars = frame.GetVariables( |
| args_no, locals_yes, statics_no, in_scopy_only) |
| desc = 'in scope locals at breakpoint 3' |
| names = ['i', 'j', 'k'] |
| count = len(names) |
| self.assertEqual( |
| vars.GetSize(), |
| count, |
| "There should be %i %s (%s) but we are reporting %i (%s)" % |
| (count, |
| desc, |
| names, |
| vars.GetSize(), |
| get_names_from_value_list(vars))) |
| self.verify_variable_names("check names of %s" % (desc), vars, names) |