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