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