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