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