def test(self): """Test 'image lookup -t days' and check for correct display and enum value printing.""" self.build() exe = os.path.join(os.getcwd(), "a.out") self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) # Break inside the main. bkpt_id = lldbutil.run_break_set_by_file_and_line (self, "main.c", self.line, num_expected_locations=1, loc_exact=True) self.runCmd("run", RUN_SUCCEEDED) # The stop reason of the thread should be breakpoint. self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, substrs = ['stopped', 'stop reason = breakpoint']) # The breakpoint should have a hit count of 1. self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE, substrs = [' resolved, hit count = 1']) # Look up information about the 'days' enum type. # Check for correct display. self.expect("image lookup -t days", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ['enum days {', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday', 'kNumDays', '}']) enum_values = [ '-4', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday', 'kNumDays', '5']; bkpt = self.target().FindBreakpointByID(bkpt_id) for enum_value in enum_values: self.expect("frame variable day", 'check for valid enumeration value', substrs = [enum_value]) lldbutil.continue_to_breakpoint (self.process(), bkpt)
def image_lookup_for_enum_type(self): """Test C++11 enumeration class types.""" exe = os.path.join(os.getcwd(), "a.out") self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) # Break inside the main. bkpt_id = lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True) self.runCmd("run", RUN_SUCCEEDED) # The stop reason of the thread should be breakpoint. self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, substrs = ['stopped', 'stop reason = breakpoint']) # The breakpoint should have a hit count of 1. self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE, substrs = [' resolved, hit count = 1']) # Look up information about the 'DayType' enum type. # Check for correct display. self.expect("image lookup -t DayType", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ['enum DayType {', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday', 'kNumDays', '}']) enum_values = [ '-4', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday', 'kNumDays', '5']; bkpt = self.target().FindBreakpointByID(bkpt_id) for enum_value in enum_values: self.expect("frame variable day", 'check for valid enumeration value', substrs = [enum_value]) lldbutil.continue_to_breakpoint (self.process(), bkpt)
def step_in_template(self): """Use Python APIs to test stepping in to templated functions.""" exe = os.path.join(os.getcwd(), "a.out") target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) break_1_in_main = target.BreakpointCreateBySourceRegex ('// Call max_value template', self.main_source_spec) self.assertTrue(break_1_in_main, VALID_BREAKPOINT) break_2_in_main = target.BreakpointCreateBySourceRegex ('// Call max_value specialized', self.main_source_spec) self.assertTrue(break_2_in_main, VALID_BREAKPOINT) # Now launch the process, and do not stop at entry point. self.process = target.LaunchSimple (None, None, self.get_process_working_directory()) self.assertTrue(self.process, PROCESS_IS_VALID) # The stop reason of the thread should be breakpoint. threads = lldbutil.get_threads_stopped_at_breakpoint (self.process, break_1_in_main) if len(threads) != 1: self.fail ("Failed to stop at first breakpoint in main.") self.thread = threads[0] step_sequence = [["// In max_value template", "into"]] self.run_step_sequence(step_sequence) threads = lldbutil.continue_to_breakpoint (self.process, break_2_in_main) self.assertEqual(len(threads), 1, "Successfully ran to call site of second caller_trivial_1 call.") self.thread = threads[0] step_sequence = [["// In max_value specialized", "into"]] self.run_step_sequence(step_sequence)
def step_in_template(self): """Use Python APIs to test stepping in to templated functions.""" exe = os.path.join(os.getcwd(), "a.out") target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) break_1_in_main = target.BreakpointCreateBySourceRegex("// Call max_value template", self.main_source_spec) self.assertTrue(break_1_in_main, VALID_BREAKPOINT) break_2_in_main = target.BreakpointCreateBySourceRegex("// Call max_value specialized", self.main_source_spec) self.assertTrue(break_2_in_main, VALID_BREAKPOINT) # Now launch the process, and do not stop at entry point. self.process = target.LaunchSimple(None, None, self.get_process_working_directory()) self.assertTrue(self.process, PROCESS_IS_VALID) # The stop reason of the thread should be breakpoint. threads = lldbutil.get_threads_stopped_at_breakpoint(self.process, break_1_in_main) if len(threads) != 1: self.fail("Failed to stop at first breakpoint in main.") self.thread = threads[0] step_sequence = [["// In max_value template", "into"]] self.run_step_sequence(step_sequence) threads = lldbutil.continue_to_breakpoint(self.process, break_2_in_main) self.assertEqual(len(threads), 1, "Successfully ran to call site of second caller_trivial_1 call.") self.thread = threads[0] step_sequence = [["// In max_value specialized", "into"]] self.run_step_sequence(step_sequence)
def data_formatter_commands(self): """Benchmark different ways to continue a process""" self.runCmd("file a.out", CURRENT_EXECUTABLE_SET) bkpt = self.target().FindBreakpointByID( lldbutil.run_break_set_by_source_regexp(self, "// break here")) self.runCmd("run", RUN_SUCCEEDED) # The stop reason of the thread should be breakpoint. self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, substrs=['stopped', 'stop reason = breakpoint']) # This is the function to remove the custom formats in order to have a # clean slate for the next test case. def cleanup(): self.runCmd('type format clear', check=False) self.runCmd('type summary clear', check=False) self.runCmd('type filter clear', check=False) self.runCmd('type synth clear', check=False) self.runCmd("settings set target.max-children-count 256", check=False) # Execute the cleanup function during test case tear down. self.addTearDownHook(cleanup) runCmd_sw = Stopwatch() lldbutil_sw = Stopwatch() for i in range(0, 15): runCmd_sw.start() self.runCmd("continue") runCmd_sw.stop() for i in range(0, 15): lldbutil_sw.start() lldbutil.continue_to_breakpoint(self.process(), bkpt) lldbutil_sw.stop() print "runCmd: %s\nlldbutil: %s" % (runCmd_sw, lldbutil_sw)
def cpp_exceptions(self): """Test lldb exception breakpoint command for CPP.""" exe = os.path.join(os.getcwd(), "a.out") # Create a target from the debugger. target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) exception_bkpt = target.BreakpointCreateForException( lldb.eLanguageTypeC_plus_plus, True, True) self.assertTrue(exception_bkpt, "Made an exception breakpoint") # Now run, and make sure we hit our breakpoint: process = target.LaunchSimple(None, None, self.get_process_working_directory()) self.assertTrue(process, "Got a valid process") stopped_threads = [] stopped_threads = lldbutil.get_threads_stopped_at_breakpoint( process, exception_bkpt) self.assertTrue( len(stopped_threads) == 1, "Stopped at our exception breakpoint.") thread = stopped_threads[0] # Make sure our throw function is still above us on the stack: frame_functions = lldbutil.get_function_names(thread) self.assertTrue( frame_functions.count("throws_exception_on_even(int)") == 1, "Our throw function is still on the stack.") # Okay we hit our exception throw breakpoint, now make sure we get our catch breakpoint. # One potential complication is that we might hit a couple of the exception breakpoints in getting out of the throw. # so loop till we don't see the throws function on the stack. We should stop one more time for our exception breakpoint # and that should be the catch... while frame_functions.count("throws_exception_on_even(int)") == 1: stopped_threads = lldbutil.continue_to_breakpoint( process, exception_bkpt) self.assertTrue(len(stopped_threads) == 1) thread = stopped_threads[0] frame_functions = lldbutil.get_function_names(thread) self.assertTrue( frame_functions.count("throws_exception_on_even(int)") == 0, "At catch our throw function is off the stack") self.assertTrue( frame_functions.count("intervening_function(int)") == 0, "At catch our intervening function is off the stack") self.assertTrue( frame_functions.count("catches_exception(int)") == 1, "At catch our catch function is on the stack")
def data_formatter_commands(self): """Benchmark different ways to continue a process""" self.runCmd("file a.out", CURRENT_EXECUTABLE_SET) bkpt = self.target().FindBreakpointByID(lldbutil.run_break_set_by_source_regexp (self, "// break here")) self.runCmd("run", RUN_SUCCEEDED) # The stop reason of the thread should be breakpoint. self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, substrs = ['stopped', 'stop reason = breakpoint']) # This is the function to remove the custom formats in order to have a # clean slate for the next test case. def cleanup(): self.runCmd('type format clear', check=False) self.runCmd('type summary clear', check=False) self.runCmd('type filter clear', check=False) self.runCmd('type synth clear', check=False) self.runCmd("settings set target.max-children-count 256", check=False) # Execute the cleanup function during test case tear down. self.addTearDownHook(cleanup) runCmd_sw = Stopwatch() lldbutil_sw = Stopwatch() for i in range(0,15): runCmd_sw.start() self.runCmd("continue") runCmd_sw.stop() for i in range(0,15): lldbutil_sw.start() lldbutil.continue_to_breakpoint(self.process(), bkpt) lldbutil_sw.stop() print "runCmd: %s\nlldbutil: %s" % (runCmd_sw,lldbutil_sw)
def test(self): """Test lldb exception breakpoint command for CPP.""" self.build() exe = os.path.join(os.getcwd(), "a.out") # Create a target from the debugger. target = self.dbg.CreateTarget (exe) self.assertTrue(target, VALID_TARGET) exception_bkpt = target.BreakpointCreateForException (lldb.eLanguageTypeC_plus_plus, True, True) self.assertTrue (exception_bkpt, "Made an exception breakpoint") # Now run, and make sure we hit our breakpoint: process = target.LaunchSimple (None, None, self.get_process_working_directory()) self.assertTrue (process, "Got a valid process") stopped_threads = [] stopped_threads = lldbutil.get_threads_stopped_at_breakpoint (process, exception_bkpt) self.assertTrue (len(stopped_threads) == 1, "Stopped at our exception breakpoint.") thread = stopped_threads[0] # Make sure our throw function is still above us on the stack: frame_functions = lldbutil.get_function_names(thread) self.assertTrue (frame_functions.count ("throws_exception_on_even(int)") == 1, "Our throw function is still on the stack.") # Okay we hit our exception throw breakpoint, now make sure we get our catch breakpoint. # One potential complication is that we might hit a couple of the exception breakpoints in getting out of the throw. # so loop till we don't see the throws function on the stack. We should stop one more time for our exception breakpoint # and that should be the catch... while frame_functions.count ("throws_exception_on_even(int)") == 1: stopped_threads = lldbutil.continue_to_breakpoint (process, exception_bkpt) self.assertTrue (len(stopped_threads) == 1) thread = stopped_threads[0] frame_functions = lldbutil.get_function_names(thread) self.assertTrue (frame_functions.count ("throws_exception_on_even(int)") == 0, "At catch our throw function is off the stack") self.assertTrue (frame_functions.count ("intervening_function(int)") == 0, "At catch our intervening function is off the stack") self.assertTrue (frame_functions.count ("catches_exception(int)") == 1, "At catch our catch function is on the stack")
def objc_stepping(self): """Use Python APIs to test stepping into ObjC methods.""" exe = os.path.join(os.getcwd(), "a.out") target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) self.main_source_spec = lldb.SBFileSpec (self.main_source) breakpoints_to_disable = [] break1 = target.BreakpointCreateBySourceRegex ("// Set first breakpoint here.", self.main_source_spec) self.assertTrue(break1, VALID_BREAKPOINT) breakpoints_to_disable.append (break1) break2 = target.BreakpointCreateBySourceRegex ("// Set second breakpoint here.", self.main_source_spec) self.assertTrue(break2, VALID_BREAKPOINT) breakpoints_to_disable.append (break2) break3 = target.BreakpointCreateBySourceRegex ('// Set third breakpoint here.', self.main_source_spec) self.assertTrue(break3, VALID_BREAKPOINT) breakpoints_to_disable.append (break3) break4 = target.BreakpointCreateBySourceRegex ('// Set fourth breakpoint here.', self.main_source_spec) self.assertTrue(break4, VALID_BREAKPOINT) breakpoints_to_disable.append (break4) break5 = target.BreakpointCreateBySourceRegex ('// Set fifth breakpoint here.', self.main_source_spec) self.assertTrue(break5, VALID_BREAKPOINT) breakpoints_to_disable.append (break5) break_returnStruct_call_super = target.BreakpointCreateBySourceRegex ('// Source returnsStruct call line.', self.main_source_spec) self.assertTrue(break_returnStruct_call_super, VALID_BREAKPOINT) breakpoints_to_disable.append (break_returnStruct_call_super) break_step_nil = target.BreakpointCreateBySourceRegex ('// Set nil step breakpoint here.', self.main_source_spec) self.assertTrue(break_step_nil, VALID_BREAKPOINT) # Now launch the process, and do not stop at entry point. process = target.LaunchSimple (None, None, os.getcwd()) self.assertTrue(process, PROCESS_IS_VALID) # The stop reason of the thread should be breakpoint. threads = lldbutil.get_threads_stopped_at_breakpoint (process, break1) if len(threads) != 1: self.fail ("Failed to stop at breakpoint 1.") thread = threads[0] mySource = thread.GetFrameAtIndex(0).FindVariable("mySource") self.assertTrue(mySource, "Found mySource local variable.") mySource_isa = mySource.GetChildMemberWithName ("isa") self.assertTrue(mySource_isa, "Found mySource->isa local variable.") mySource_isa.GetValue () if self.TraceOn(): print mySource_isa # Lets delete mySource so we can check that after stepping a child variable # with no parent persists and is useful. del (mySource) # Now step in, that should leave us in the Source randomMethod: thread.StepInto() line_number = thread.GetFrameAtIndex(0).GetLineEntry().GetLine() self.assertTrue (line_number == self.source_randomMethod_line, "Stepped into Source randomMethod.") # Now step in again, through the super call, and that should leave us in the SourceBase randomMethod: thread.StepInto() line_number = thread.GetFrameAtIndex(0).GetLineEntry().GetLine() self.assertTrue (line_number == self.sourceBase_randomMethod_line, "Stepped through super into SourceBase randomMethod.") threads = lldbutil.continue_to_breakpoint (process, break2) self.assertTrue (len(threads) == 1, "Continued to second breakpoint in main.") # Again, step in twice gets us to a stret method and a stret super call: thread = threads[0] thread.StepInto() line_number = thread.GetFrameAtIndex(0).GetLineEntry().GetLine() self.assertTrue (line_number == self.source_returnsStruct_start_line, "Stepped into Source returnsStruct.") threads = lldbutil.continue_to_breakpoint (process, break_returnStruct_call_super) self.assertTrue (len(threads) == 1, "Stepped to the call super line in Source returnsStruct.") thread = threads[0] thread.StepInto() line_number = thread.GetFrameAtIndex(0).GetLineEntry().GetLine() self.assertTrue (line_number == self.sourceBase_returnsStruct_start_line, "Stepped through super into SourceBase returnsStruct.") # Cool now continue to get past the call that intializes the Observer, and then do our steps in again to see that # we can find our way when we're stepping through a KVO swizzled object. threads = lldbutil.continue_to_breakpoint (process, break3) self.assertTrue (len(threads) == 1, "Continued to third breakpoint in main, our object should now be swizzled.") mySource_isa.GetValue () did_change = mySource_isa.GetValueDidChange () if self.TraceOn(): print mySource_isa self.assertTrue (did_change, "The isa did indeed change, swizzled!") # Now step in, that should leave us in the Source randomMethod: thread = threads[0] thread.StepInto() line_number = thread.GetFrameAtIndex(0).GetLineEntry().GetLine() self.assertTrue (line_number == self.source_randomMethod_line, "Stepped into Source randomMethod in swizzled object.") # Now step in again, through the super call, and that should leave us in the SourceBase randomMethod: thread.StepInto() line_number = thread.GetFrameAtIndex(0).GetLineEntry().GetLine() self.assertTrue (line_number == self.sourceBase_randomMethod_line, "Stepped through super into SourceBase randomMethod in swizzled object.") threads = lldbutil.continue_to_breakpoint (process, break4) self.assertTrue (len(threads) == 1, "Continued to fourth breakpoint in main.") thread = threads[0] # Again, step in twice gets us to a stret method and a stret super call: thread.StepInto() line_number = thread.GetFrameAtIndex(0).GetLineEntry().GetLine() self.assertTrue (line_number == self.source_returnsStruct_start_line, "Stepped into Source returnsStruct in swizzled object.") threads = lldbutil.continue_to_breakpoint(process, break_returnStruct_call_super) self.assertTrue (len(threads) == 1, "Stepped to the call super line in Source returnsStruct - second time.") thread = threads[0] thread.StepInto() line_number = thread.GetFrameAtIndex(0).GetLineEntry().GetLine() self.assertTrue (line_number == self.sourceBase_returnsStruct_start_line, "Stepped through super into SourceBase returnsStruct in swizzled object.") for bkpt in breakpoints_to_disable: bkpt.SetEnabled(False) threads = lldbutil.continue_to_breakpoint (process, break_step_nil) self.assertTrue (len(threads) == 1, "Continued to step nil breakpoint.") thread.StepInto() line_number = thread.GetFrameAtIndex(0).GetLineEntry().GetLine() self.assertTrue (line_number == self.stepped_past_nil_line, "Step in over dispatch to nil stepped over.")
def test_get_dynamic_vals(self): """Test fetching C++ dynamic values from pointers & references.""" self.build(dictionary=self.getBuildFlags()) exe = os.path.join(os.getcwd(), "a.out") # Create a target from the debugger. target = self.dbg.CreateTarget (exe) self.assertTrue(target, VALID_TARGET) # Set up our breakpoints: do_something_bpt = target.BreakpointCreateByLocation('pass-to-base.cpp', self.do_something_line) self.assertTrue(do_something_bpt, VALID_BREAKPOINT) first_call_bpt = target.BreakpointCreateByLocation('pass-to-base.cpp', self.main_first_call_line) self.assertTrue(first_call_bpt, VALID_BREAKPOINT) second_call_bpt = target.BreakpointCreateByLocation('pass-to-base.cpp', self.main_second_call_line) self.assertTrue(second_call_bpt, VALID_BREAKPOINT) # Now launch the process, and do not stop at the entry point. process = target.LaunchSimple (None, None, self.get_process_working_directory()) self.assertTrue(process.GetState() == lldb.eStateStopped, PROCESS_STOPPED) threads = lldbutil.get_threads_stopped_at_breakpoint (process, first_call_bpt) self.assertTrue (len(threads) == 1) thread = threads[0] frame = thread.GetFrameAtIndex(0) # Now find the dynamic addresses of myB and otherB so we can compare them # with the dynamic values we get in doSomething: use_dynamic = lldb.eDynamicCanRunTarget no_dynamic = lldb.eNoDynamicValues myB = frame.FindVariable ('myB', no_dynamic); self.assertTrue (myB) myB_loc = int (myB.GetLocation(), 16) otherB = frame.FindVariable('otherB', no_dynamic) self.assertTrue (otherB) otherB_loc = int (otherB.GetLocation(), 16) # Okay now run to doSomething: threads = lldbutil.continue_to_breakpoint (process, do_something_bpt) self.assertTrue (len(threads) == 1) thread = threads[0] frame = thread.GetFrameAtIndex(0) # Get "this" using FindVariable: this_static = frame.FindVariable ('this', no_dynamic) this_dynamic = frame.FindVariable ('this', use_dynamic) self.examine_value_object_of_this_ptr (this_static, this_dynamic, myB_loc) # Now make sure that the "GetDynamicValue" works: # This doesn't work currently because we can't get dynamic values from ConstResult objects. fetched_dynamic_value = this_static.GetDynamicValue(use_dynamic) self.examine_value_object_of_this_ptr (this_static, fetched_dynamic_value, myB_loc) # And conversely that the GetDynamicValue() interface also works: fetched_static_value = this_dynamic.GetStaticValue() self.examine_value_object_of_this_ptr (fetched_static_value, this_dynamic, myB_loc) # Get "this" using FindValue, make sure that works too: this_static = frame.FindValue ('this', lldb.eValueTypeVariableArgument, no_dynamic) this_dynamic = frame.FindValue ('this', lldb.eValueTypeVariableArgument, use_dynamic) self.examine_value_object_of_this_ptr (this_static, this_dynamic, myB_loc) # Get "this" using the EvaluateExpression: this_static = frame.EvaluateExpression ('this', False) this_dynamic = frame.EvaluateExpression ('this', True) self.examine_value_object_of_this_ptr (this_static, this_dynamic, myB_loc) # The "frame var" code uses another path to get into children, so let's # make sure that works as well: self.expect('frame var -d run-target --ptr-depth=2 --show-types anotherA.m_client_A', 'frame var finds its way into a child member', patterns = ['\(B \*\)']) # Now make sure we also get it right for a reference as well: anotherA_static = frame.FindVariable ('anotherA', False) self.assertTrue (anotherA_static) anotherA_static_addr = int (anotherA_static.GetValue(), 16) anotherA_dynamic = frame.FindVariable ('anotherA', True) self.assertTrue (anotherA_dynamic) anotherA_dynamic_addr = int (anotherA_dynamic.GetValue(), 16) anotherA_dynamic_typename = anotherA_dynamic.GetTypeName() self.assertTrue (anotherA_dynamic_typename.find('B') != -1) self.assertTrue(anotherA_dynamic_addr < anotherA_static_addr) anotherA_m_b_value_dynamic = anotherA_dynamic.GetChildMemberWithName('m_b_value', True) self.assertTrue (anotherA_m_b_value_dynamic) anotherA_m_b_val = int (anotherA_m_b_value_dynamic.GetValue(), 10) self.assertTrue (anotherA_m_b_val == 300) anotherA_m_b_value_static = anotherA_static.GetChildMemberWithName('m_b_value', True) self.assertFalse (anotherA_m_b_value_static) # Okay, now continue again, and when we hit the second breakpoint in main threads = lldbutil.continue_to_breakpoint (process, second_call_bpt) self.assertTrue (len(threads) == 1) thread = threads[0] frame = thread.GetFrameAtIndex(0) reallyA_value = frame.FindVariable ('reallyA', False) self.assertTrue(reallyA_value) reallyA_loc = int (reallyA_value.GetLocation(), 16) # Finally continue to doSomething again, and make sure we get the right value for anotherA, # which this time around is just an "A". threads = lldbutil.continue_to_breakpoint (process, do_something_bpt) self.assertTrue(len(threads) == 1) thread = threads[0] frame = thread.GetFrameAtIndex(0) anotherA_value = frame.FindVariable ('anotherA', True) self.assertTrue(anotherA_value) anotherA_loc = int (anotherA_value.GetValue(), 16) self.assertTrue (anotherA_loc == reallyA_loc) self.assertTrue (anotherA_value.GetTypeName().find ('B') == -1)
def do_sbvalue_cast (self, exe_name): """Test SBValue::Cast(SBType) API for C++ types.""" exe = os.path.join(os.getcwd(), exe_name) # Create a target from the debugger. target = self.dbg.CreateTarget (exe) self.assertTrue(target, VALID_TARGET) # Set up our breakpoints: breakpoint = target.BreakpointCreateByLocation(self.source, self.line) self.assertTrue(breakpoint, VALID_BREAKPOINT) # Now launch the process, and do not stop at the entry point. process = target.LaunchSimple (None, None, self.get_process_working_directory()) self.assertTrue(process.GetState() == lldb.eStateStopped, PROCESS_STOPPED) # Find DerivedA and DerivedB types. typeA = target.FindFirstType('DerivedA') typeB = target.FindFirstType('DerivedB') self.DebugSBType(typeA) self.DebugSBType(typeB) self.assertTrue(typeA) self.assertTrue(typeB) error = lldb.SBError() # First stop is for DerivedA instance. threads = lldbutil.get_threads_stopped_at_breakpoint (process, breakpoint) self.assertTrue (len(threads) == 1) thread = threads[0] frame0 = thread.GetFrameAtIndex(0) tellerA = frame0.FindVariable('teller', lldb.eNoDynamicValues) self.DebugSBValue(tellerA) self.assertTrue(tellerA.GetChildMemberWithName('m_base_val').GetValueAsUnsigned(error, 0) == 20) if self.TraceOn(): for child in tellerA: print "child name:", child.GetName() print child # Call SBValue.Cast() to obtain instanceA. instanceA = tellerA.Cast(typeA.GetPointerType()) self.DebugSBValue(instanceA) # Iterate through all the children and print their values. if self.TraceOn(): for child in instanceA: print "child name:", child.GetName() print child a_member_val = instanceA.GetChildMemberWithName('m_a_val') self.DebugSBValue(a_member_val) self.assertTrue(a_member_val.GetValueAsUnsigned(error, 0) == 10) # Second stop is for DerivedB instance. threads = lldbutil.continue_to_breakpoint (process, breakpoint) self.assertTrue (len(threads) == 1) thread = threads[0] frame0 = thread.GetFrameAtIndex(0) tellerB = frame0.FindVariable('teller', lldb.eNoDynamicValues) self.DebugSBValue(tellerB) self.assertTrue(tellerB.GetChildMemberWithName('m_base_val').GetValueAsUnsigned(error, 0) == 12) if self.TraceOn(): for child in tellerB: print "child name:", child.GetName() print child # Call SBValue.Cast() to obtain instanceB. instanceB = tellerB.Cast(typeB.GetPointerType()) self.DebugSBValue(instanceB) # Iterate through all the children and print their values. if self.TraceOn(): for child in instanceB: print "child name:", child.GetName() print child b_member_val = instanceB.GetChildMemberWithName('m_b_val') self.DebugSBValue(b_member_val) self.assertTrue(b_member_val.GetValueAsUnsigned(error, 0) == 36)
def do_sbvalue_cast(self, exe_name): """Test SBValue::Cast(SBType) API for C++ types.""" exe = os.path.join(os.getcwd(), exe_name) # Create a target from the debugger. target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) # Set up our breakpoints: breakpoint = target.BreakpointCreateByLocation(self.source, self.line) self.assertTrue(breakpoint, VALID_BREAKPOINT) # Now launch the process, and do not stop at the entry point. process = target.LaunchSimple(None, None, os.getcwd()) self.assertTrue(process.GetState() == lldb.eStateStopped, PROCESS_STOPPED) # Find DerivedA and DerivedB types. typeA = target.FindFirstType('DerivedA') typeB = target.FindFirstType('DerivedB') self.DebugSBType(typeA) self.DebugSBType(typeB) self.assertTrue(typeA) self.assertTrue(typeB) error = lldb.SBError() # First stop is for DerivedA instance. threads = lldbutil.get_threads_stopped_at_breakpoint( process, breakpoint) self.assertTrue(len(threads) == 1) thread = threads[0] frame0 = thread.GetFrameAtIndex(0) tellerA = frame0.FindVariable('teller', lldb.eNoDynamicValues) self.DebugSBValue(tellerA) self.assertTrue( tellerA.GetChildMemberWithName('m_base_val').GetValueAsUnsigned( error, 0) == 20) if self.TraceOn(): for child in tellerA: print "child name:", child.GetName() print child # Call SBValue.Cast() to obtain instanceA. instanceA = tellerA.Cast(typeA.GetPointerType()) self.DebugSBValue(instanceA) # Iterate through all the children and print their values. if self.TraceOn(): for child in instanceA: print "child name:", child.GetName() print child a_member_val = instanceA.GetChildMemberWithName('m_a_val') self.DebugSBValue(a_member_val) self.assertTrue(a_member_val.GetValueAsUnsigned(error, 0) == 10) # Second stop is for DerivedB instance. threads = lldbutil.continue_to_breakpoint(process, breakpoint) self.assertTrue(len(threads) == 1) thread = threads[0] frame0 = thread.GetFrameAtIndex(0) tellerB = frame0.FindVariable('teller', lldb.eNoDynamicValues) self.DebugSBValue(tellerB) self.assertTrue( tellerB.GetChildMemberWithName('m_base_val').GetValueAsUnsigned( error, 0) == 12) if self.TraceOn(): for child in tellerB: print "child name:", child.GetName() print child # Call SBValue.Cast() to obtain instanceB. instanceB = tellerB.Cast(typeB.GetPointerType()) self.DebugSBValue(instanceB) # Iterate through all the children and print their values. if self.TraceOn(): for child in instanceB: print "child name:", child.GetName() print child b_member_val = instanceB.GetChildMemberWithName('m_b_val') self.DebugSBValue(b_member_val) self.assertTrue(b_member_val.GetValueAsUnsigned(error, 0) == 36)
def test_with_run_command(self): """Test that that file and class static variables display correctly.""" self.build() self.runCmd("file a.out", CURRENT_EXECUTABLE_SET) lldbutil.skip_if_library_missing(self, self.target(), lldbutil.PrintableRegex("libc\+\+")) bkpt = self.target().FindBreakpointByID(lldbutil.run_break_set_by_source_regexp (self, "Set break point at this line.")) self.runCmd("run", RUN_SUCCEEDED) # The stop reason of the thread should be breakpoint. self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, substrs = ['stopped', 'stop reason = breakpoint']) # This is the function to remove the custom formats in order to have a # clean slate for the next test case. def cleanup(): self.runCmd('type format clear', check=False) self.runCmd('type summary clear', check=False) self.runCmd('type filter clear', check=False) self.runCmd('type synth clear', check=False) self.runCmd("settings set target.max-children-count 256", check=False) # Execute the cleanup function during test case tear down. self.addTearDownHook(cleanup) self.expect('image list', substrs = self.getLibcPlusPlusLibs()) self.expect("frame variable ii",substrs = ["size=0","{}"]) lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect("frame variable ii",substrs = ["size=6","[0] = 0","[1] = 1", "[2] = 2", "[3] = 3", "[4] = 4", "[5] = 5"]) lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect("frame variable ii",substrs = ["size=7","[2] = 2", "[3] = 3", "[6] = 6"]) self.expect("p ii",substrs = ["size=7","[2] = 2", "[3] = 3", "[6] = 6"]) self.expect("frame variable ii[2]",substrs = [" = 2"]) lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect("frame variable ii",substrs = ["size=0","{}"]) lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect("frame variable ii",substrs = ["size=0","{}"]) self.expect("frame variable ss",substrs = ["size=0","{}"]) lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect("frame variable ss",substrs = ["size=2",'[0] = "a"','[1] = "a very long string is right here"']) lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect("frame variable ss",substrs = ["size=4",'[2] = "b"','[3] = "c"','[0] = "a"','[1] = "a very long string is right here"']) self.expect("p ss",substrs = ["size=4",'[2] = "b"','[3] = "c"','[0] = "a"','[1] = "a very long string is right here"']) self.expect("frame variable ss[2]",substrs = [' = "b"']) lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect("frame variable ss",substrs = ["size=3",'[0] = "a"','[1] = "a very long string is right here"','[2] = "c"'])
def inline_stepping(self): """Use Python APIs to test stepping over and hitting breakpoints.""" exe = os.path.join(os.getcwd(), "a.out") target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) break_1_in_main = target.BreakpointCreateBySourceRegex ('// Stop here and step over to set up stepping over.', self.main_source_spec) self.assertTrue(break_1_in_main, VALID_BREAKPOINT) # Now launch the process, and do not stop at entry point. self.process = target.LaunchSimple (None, None, os.getcwd()) self.assertTrue(self.process, PROCESS_IS_VALID) # The stop reason of the thread should be breakpoint. threads = lldbutil.get_threads_stopped_at_breakpoint (self.process, break_1_in_main) if len(threads) != 1: self.fail ("Failed to stop at first breakpoint in main.") self.thread = threads[0] # Step over the inline_value = 0 line to get us to inline_trivial_1 called from main. Doing it this way works # around a bug in lldb where the breakpoint on the containing line of an inlined function with no return value # gets set past the insertion line in the function. # Then test stepping over a simple inlined function. Note, to test all the parts of the inlined stepping # the calls inline_stepping_1 and inline_stepping_2 should line up at the same address, that way we will test # the "virtual" stepping. # FIXME: Put in a check to see if that is true and warn if it is not. step_sequence = [["// At inline_trivial_1 called from main.", "over"], ["// At first call of caller_trivial_1 in main.", "over"]] self.run_step_sequence(step_sequence) # Now step from caller_ref_1 all the way into called_by_inline_trivial step_sequence = [["// In caller_trivial_1.", "into"], ["// In caller_trivial_2.", "into"], ["// In inline_trivial_1.", "into"], ["// In inline_trivial_2.", "into"], ["// At caller_by_inline_trivial in inline_trivial_2.", "over"], ["// In called_by_inline_trivial.", "into"]] self.run_step_sequence(step_sequence) # Now run to the inline_trivial_1 just before the immediate step into inline_trivial_2: break_2_in_main = target.BreakpointCreateBySourceRegex ('// At second call of caller_trivial_1 in main.', self.main_source_spec) self.assertTrue(break_2_in_main, VALID_BREAKPOINT) threads = lldbutil.continue_to_breakpoint (self.process, break_2_in_main) self.assertTrue (len(threads) == 1, "Successfully ran to call site of second caller_trivial_1 call.") self.thread = threads[0] step_sequence = [["// In caller_trivial_1.", "into"], ["// In caller_trivial_2.", "into"], ["// In inline_trivial_1.", "into"]] self.run_step_sequence(step_sequence) # Then call some trivial function, and make sure we end up back where we were in the inlined call stack: frame = self.thread.GetFrameAtIndex(0) before_line_entry = frame.GetLineEntry() value = frame.EvaluateExpression ("function_to_call()") after_line_entry = frame.GetLineEntry() self.assertTrue (before_line_entry.GetLine() == after_line_entry.GetLine(), "Line entry before and after function calls are the same.") # Now make sure stepping OVER in the middle of the stack works, and then check finish from the inlined frame: step_sequence = [["// At increment in inline_trivial_1.", "over"], ["// At increment in caller_trivial_2.", "out"]] self.run_step_sequence(step_sequence) # Now run to the place in main just before the first call to caller_ref_1: break_3_in_main = target.BreakpointCreateBySourceRegex ('// At first call of caller_ref_1 in main.', self.main_source_spec) self.assertTrue(break_3_in_main, VALID_BREAKPOINT) threads = lldbutil.continue_to_breakpoint (self.process, break_3_in_main) self.assertTrue (len(threads) == 1, "Successfully ran to call site of first caller_ref_1 call.") self.thread = threads[0] step_sequence = [["// In caller_ref_1.", "into"], ["// In caller_ref_2.", "into"], ["// In inline_ref_1.", "into"], ["// In inline_ref_2.", "into"], ["// In called_by_inline_ref.", "into"], ["// In inline_ref_2.", "out"], ["// In inline_ref_1.", "out"], ["// At increment in inline_ref_1.", "over"], ["// In caller_ref_2.", "out"], ["// At increment in caller_ref_2.", "over"]] self.run_step_sequence (step_sequence)
def data_formatter_commands(self): """Test that that file and class static variables display correctly.""" self.runCmd("file a.out", CURRENT_EXECUTABLE_SET) bkpt = self.target().FindBreakpointByID(lldbutil.run_break_set_by_source_regexp (self, "break here")) self.runCmd("run", RUN_SUCCEEDED) # The stop reason of the thread should be breakpoint. self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, substrs = ['stopped', 'stop reason = breakpoint']) # This is the function to remove the custom formats in order to have a # clean slate for the next test case. def cleanup(): self.runCmd('type format clear', check=False) self.runCmd('type summary clear', check=False) self.runCmd('type filter clear', check=False) self.runCmd('type synth clear', check=False) self.runCmd("settings set target.max-children-count 256", check=False) # Execute the cleanup function during test case tear down. self.addTearDownHook(cleanup) # empty vectors (and storage pointers SHOULD BOTH BE NULL..) self.expect("frame variable numbers", substrs = ['numbers = size=0']) lldbutil.continue_to_breakpoint(self.process(), bkpt) # first value added self.expect("frame variable numbers", substrs = ['numbers = size=1', '[0] = 1', '}']) # add some more data lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect("frame variable numbers", substrs = ['numbers = size=4', '[0] = 1', '[1] = 12', '[2] = 123', '[3] = 1234', '}']) self.expect("p numbers", substrs = ['$', 'size=4', '[0] = 1', '[1] = 12', '[2] = 123', '[3] = 1234', '}']) # check access to synthetic children self.runCmd("type summary add --summary-string \"item 0 is ${var[0]}\" std::int_vect int_vect") self.expect('frame variable numbers', substrs = ['item 0 is 1']); self.runCmd("type summary add --summary-string \"item 0 is ${svar[0]}\" std::int_vect int_vect") self.expect('frame variable numbers', substrs = ['item 0 is 1']); # move on with synths self.runCmd("type summary delete std::int_vect") self.runCmd("type summary delete int_vect") # add some more data lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect("frame variable numbers", substrs = ['numbers = size=7', '[0] = 1', '[1] = 12', '[2] = 123', '[3] = 1234', '[4] = 12345', '[5] = 123456', '[6] = 1234567', '}']) self.expect("p numbers", substrs = ['$', 'size=7', '[0] = 1', '[1] = 12', '[2] = 123', '[3] = 1234', '[4] = 12345', '[5] = 123456', '[6] = 1234567', '}']) # check access-by-index self.expect("frame variable numbers[0]", substrs = ['1']); self.expect("frame variable numbers[1]", substrs = ['12']); self.expect("frame variable numbers[2]", substrs = ['123']); self.expect("frame variable numbers[3]", substrs = ['1234']); # clear out the vector and see that we do the right thing once again lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect("frame variable numbers", substrs = ['numbers = size=0']) lldbutil.continue_to_breakpoint(self.process(), bkpt) # first value added self.expect("frame variable numbers", substrs = ['numbers = size=1', '[0] = 7', '}']) # check if we can display strings self.expect("frame variable strings", substrs = ['goofy', 'is', 'smart']) self.expect("p strings", substrs = ['goofy', 'is', 'smart']) # test summaries based on synthetic children self.runCmd("type summary add std::string_vect string_vect --summary-string \"vector has ${svar%#} items\" -e") self.expect("frame variable strings", substrs = ['vector has 3 items', 'goofy', 'is', 'smart']) self.expect("p strings", substrs = ['vector has 3 items', 'goofy', 'is', 'smart']) lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect("frame variable strings", substrs = ['vector has 4 items']) # check access-by-index self.expect("frame variable strings[0]", substrs = ['goofy']); self.expect("frame variable strings[1]", substrs = ['is']); lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect("frame variable strings", substrs = ['vector has 0 items'])
def data_formatter_commands(self): """Test that that file and class static variables display correctly.""" self.runCmd("file a.out", CURRENT_EXECUTABLE_SET) bkpt = self.target().FindBreakpointByID(lldbutil.run_break_set_by_source_regexp (self, "Set break point at this line.")) self.runCmd("run", RUN_SUCCEEDED) # The stop reason of the thread should be breakpoint. self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, substrs = ['stopped', 'stop reason = breakpoint']) # This is the function to remove the custom formats in order to have a # clean slate for the next test case. def cleanup(): self.runCmd('type format clear', check=False) self.runCmd('type summary clear', check=False) self.runCmd('type filter clear', check=False) self.runCmd('type synth clear', check=False) self.runCmd("settings set target.max-children-count 256", check=False) # Execute the cleanup function during test case tear down. self.addTearDownHook(cleanup) self.expect('image list', substrs = self.getLibcPlusPlusLibs()) self.expect('frame variable ii', substrs = ['size=0', '{}']) lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect('frame variable ii', substrs = ['size=2', '[0] = ', 'first = 0', 'second = 0', '[1] = ', 'first = 1', 'second = 1']) lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect('frame variable ii', substrs = ['size=4', '[2] = ', 'first = 2', 'second = 0', '[3] = ', 'first = 3', 'second = 1']) lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect("frame variable ii", substrs = ['size=8', '[5] = ', 'first = 5', 'second = 0', '[7] = ', 'first = 7', 'second = 1']) self.expect("p ii", substrs = ['size=8', '[5] = ', 'first = 5', 'second = 0', '[7] = ', 'first = 7', 'second = 1']) # check access-by-index self.expect("frame variable ii[0]", substrs = ['first = 0', 'second = 0']); self.expect("frame variable ii[3]", substrs = ['first =', 'second =']); # check that MightHaveChildren() gets it right self.assertTrue(self.frame().FindVariable("ii").MightHaveChildren(), "ii.MightHaveChildren() says False for non empty!") # check that the expression parser does not make use of # synthetic children instead of running code # TOT clang has a fix for this, which makes the expression command here succeed # since this would make the test fail or succeed depending on clang version in use # this is safer commented for the time being #self.expect("expression ii[8]", matching=False, error=True, # substrs = ['1234567']) self.runCmd("continue"); self.expect('frame variable ii', substrs = ['size=0', '{}']) self.expect('frame variable si', substrs = ['size=0', '{}']) self.runCmd("continue"); self.expect('frame variable si', substrs = ['size=1', '[0] = ', 'first = \"zero\"', 'second = 0']) lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect("frame variable si", substrs = ['size=4', '[0] = ', 'first = \"zero\"', 'second = 0', '[1] = ', 'first = \"one\"', 'second = 1', '[2] = ', 'first = \"two\"', 'second = 2', '[3] = ', 'first = \"three\"', 'second = 3']) self.expect("p si", substrs = ['size=4', '[0] = ', 'first = \"zero\"', 'second = 0', '[1] = ', 'first = \"one\"', 'second = 1', '[2] = ', 'first = \"two\"', 'second = 2', '[3] = ', 'first = \"three\"', 'second = 3']) # check that MightHaveChildren() gets it right self.assertTrue(self.frame().FindVariable("si").MightHaveChildren(), "si.MightHaveChildren() says False for non empty!") # check access-by-index self.expect("frame variable si[0]", substrs = ['first = ', 'one', 'second = 1']); # check that the expression parser does not make use of # synthetic children instead of running code # TOT clang has a fix for this, which makes the expression command here succeed # since this would make the test fail or succeed depending on clang version in use # this is safer commented for the time being #self.expect("expression si[0]", matching=False, error=True, # substrs = ['first = ', 'zero']) lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect('frame variable si', substrs = ['size=0', '{}']) lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect('frame variable is', substrs = ['size=0', '{}']) lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect("frame variable is", substrs = ['size=4', '[0] = ', 'second = \"goofy\"', 'first = 85', '[1] = ', 'second = \"is\"', 'first = 1', '[2] = ', 'second = \"smart\"', 'first = 2', '[3] = ', 'second = \"!!!\"', 'first = 3']) self.expect("p is", substrs = ['size=4', '[0] = ', 'second = \"goofy\"', 'first = 85', '[1] = ', 'second = \"is\"', 'first = 1', '[2] = ', 'second = \"smart\"', 'first = 2', '[3] = ', 'second = \"!!!\"', 'first = 3']) # check that MightHaveChildren() gets it right self.assertTrue(self.frame().FindVariable("is").MightHaveChildren(), "is.MightHaveChildren() says False for non empty!") # check access-by-index self.expect("frame variable is[0]", substrs = ['first = ', 'second =']); # check that the expression parser does not make use of # synthetic children instead of running code # TOT clang has a fix for this, which makes the expression command here succeed # since this would make the test fail or succeed depending on clang version in use # this is safer commented for the time being #self.expect("expression is[0]", matching=False, error=True, # substrs = ['first = ', 'goofy']) lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect('frame variable is', substrs = ['size=0', '{}']) lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect('frame variable ss', substrs = ['size=0', '{}']) lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect("frame variable ss", substrs = ['size=3', '[0] = ', 'second = \"hello\"', 'first = \"ciao\"', '[1] = ', 'second = \"house\"', 'first = \"casa\"', '[2] = ', 'second = \"cat\"', 'first = \"gatto\"']) self.expect("p ss", substrs = ['size=3', '[0] = ', 'second = \"hello\"', 'first = \"ciao\"', '[1] = ', 'second = \"house\"', 'first = \"casa\"', '[2] = ', 'second = \"cat\"', 'first = \"gatto\"']) # check that MightHaveChildren() gets it right self.assertTrue(self.frame().FindVariable("ss").MightHaveChildren(), "ss.MightHaveChildren() says False for non empty!") # check access-by-index self.expect("frame variable ss[2]", substrs = ['gatto', 'cat']); # check that the expression parser does not make use of # synthetic children instead of running code # TOT clang has a fix for this, which makes the expression command here succeed # since this would make the test fail or succeed depending on clang version in use # this is safer commented for the time being #self.expect("expression ss[3]", matching=False, error=True, # substrs = ['gatto']) lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect('frame variable ss', substrs = ['size=0', '{}'])
def data_formatter_commands(self): """Test that that file and class static variables display correctly.""" self.runCmd("file a.out", CURRENT_EXECUTABLE_SET) bkpt = self.target().FindBreakpointByID( lldbutil.run_break_set_by_source_regexp( self, "Set break point at this line.")) self.runCmd("run", RUN_SUCCEEDED) # The stop reason of the thread should be breakpoint. self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, substrs=['stopped', 'stop reason = breakpoint']) # This is the function to remove the custom formats in order to have a # clean slate for the next test case. def cleanup(): self.runCmd('type format clear', check=False) self.runCmd('type summary clear', check=False) self.runCmd('type filter clear', check=False) self.runCmd('type synth clear', check=False) self.runCmd("settings set target.max-children-count 256", check=False) # Execute the cleanup function during test case tear down. self.addTearDownHook(cleanup) self.expect('image list', substrs=self.getLibcPlusPlusLibs()) self.expect("frame variable ii", substrs=["size=0", "{}"]) lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect("frame variable ii", substrs=[ "size=6", "[0] = 0", "[1] = 1", "[2] = 2", "[3] = 3", "[4] = 4", "[5] = 5" ]) lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect("frame variable ii", substrs=["size=7", "[2] = 2", "[3] = 3", "[6] = 6"]) self.expect("p ii", substrs=["size=7", "[2] = 2", "[3] = 3", "[6] = 6"]) self.expect("frame variable ii[2]", substrs=[" = 2"]) lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect("frame variable ii", substrs=["size=0", "{}"]) lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect("frame variable ii", substrs=["size=0", "{}"]) self.expect("frame variable ss", substrs=["size=0", "{}"]) lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect("frame variable ss", substrs=[ "size=2", '[0] = "a"', '[1] = "a very long string is right here"' ]) lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect("frame variable ss", substrs=[ "size=4", '[2] = "b"', '[3] = "c"', '[0] = "a"', '[1] = "a very long string is right here"' ]) self.expect("p ss", substrs=[ "size=4", '[2] = "b"', '[3] = "c"', '[0] = "a"', '[1] = "a very long string is right here"' ]) self.expect("frame variable ss[2]", substrs=[' = "b"']) lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect("frame variable ss", substrs=[ "size=3", '[0] = "a"', '[1] = "a very long string is right here"', '[2] = "c"' ])
def do_get_dynamic_vals(self): """Make sure we get dynamic values correctly both for compiled in classes and dynamic ones""" exe = os.path.join(os.getcwd(), "a.out") # Create a target from the debugger. target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) # Set up our breakpoints: handle_SourceBase_bkpt = target.BreakpointCreateByLocation(self.source_name, self.handle_SourceBase) self.assertTrue(handle_SourceBase_bkpt and handle_SourceBase_bkpt.GetNumLocations() == 1, VALID_BREAKPOINT) main_before_setProperty_bkpt = target.BreakpointCreateByLocation( self.source_name, self.main_before_setProperty_line ) self.assertTrue( main_before_setProperty_bkpt and main_before_setProperty_bkpt.GetNumLocations() == 1, VALID_BREAKPOINT ) # Now launch the process, and do not stop at the entry point. process = target.LaunchSimple(None, None, os.getcwd()) self.assertTrue(process.GetState() == lldb.eStateStopped, PROCESS_STOPPED) threads = lldbutil.get_threads_stopped_at_breakpoint(process, main_before_setProperty_bkpt) self.assertTrue(len(threads) == 1) thread = threads[0] # # At this point, myObserver has a Source pointer that is actually a KVO swizzled SourceDerived # make sure we can get that properly: frame = thread.GetFrameAtIndex(0) myObserver = frame.FindVariable("myObserver", lldb.eDynamicCanRunTarget) self.assertTrue(myObserver) myObserver_source = myObserver.GetChildMemberWithName("_source", lldb.eDynamicCanRunTarget) self.examine_SourceDerived_ptr(myObserver_source) # # Make sure a static value can be correctly turned into a dynamic value. frame = thread.GetFrameAtIndex(0) myObserver_static = frame.FindVariable("myObserver", lldb.eNoDynamicValues) self.assertTrue(myObserver_static) myObserver = myObserver_static.GetDynamicValue(lldb.eDynamicCanRunTarget) myObserver_source = myObserver.GetChildMemberWithName("_source", lldb.eDynamicCanRunTarget) self.examine_SourceDerived_ptr(myObserver_source) # The "frame var" code uses another path to get into children, so let's # make sure that works as well: result = lldb.SBCommandReturnObject() self.expect( "frame var -d run-target myObserver->_source", "frame var finds its way into a child member", patterns=["\(SourceDerived \*\)"], ) # check that our ObjC GetISA() does a good job at hiding KVO swizzled classes self.expect( "frame var -d run-target myObserver->_source -T", "the KVO-ed class is hidden", substrs=["dynamic type: SourceDerived"], ) self.expect( "frame var -d run-target myObserver->_source -T", "the KVO-ed class is hidden", matching=False, substrs=["dynamic type: NSKVONotify"], ) # This test is not entirely related to the main thrust of this test case, but since we're here, # try stepping into setProperty, and make sure we get into the version in Source: thread.StepInto() threads = lldbutil.get_stopped_threads(process, lldb.eStopReasonPlanComplete) self.assertTrue(len(threads) == 1) line_entry = threads[0].GetFrameAtIndex(0).GetLineEntry() self.assertTrue(line_entry.GetLine() == self.set_property_line) self.assertTrue(line_entry.GetFileSpec().GetFilename() == self.source_name) # Okay, back to the main business. Continue to the handle_SourceBase and make sure we get the correct dynamic value. threads = lldbutil.continue_to_breakpoint(process, handle_SourceBase_bkpt) self.assertTrue(len(threads) == 1) thread = threads[0] frame = thread.GetFrameAtIndex(0) # Get "object" using FindVariable: noDynamic = lldb.eNoDynamicValues useDynamic = lldb.eDynamicCanRunTarget object_static = frame.FindVariable("object", noDynamic) object_dynamic = frame.FindVariable("object", useDynamic) # Delete this object to make sure that this doesn't cause havoc with the dynamic object that depends on it. del (object_static) self.examine_SourceDerived_ptr(object_dynamic) # Get "this" using FindValue, make sure that works too: object_static = frame.FindValue("object", lldb.eValueTypeVariableArgument, noDynamic) object_dynamic = frame.FindValue("object", lldb.eValueTypeVariableArgument, useDynamic) del (object_static) self.examine_SourceDerived_ptr(object_dynamic) # Get "this" using the EvaluateExpression: object_static = frame.EvaluateExpression("object", noDynamic) object_dynamic = frame.EvaluateExpression("object", useDynamic) del (object_static) self.examine_SourceDerived_ptr(object_dynamic) # Continue again to the handle_SourceBase and make sure we get the correct dynamic value. # This one looks exactly the same, but in fact this is an "un-KVO'ed" version of SourceBase, so # its isa pointer points to SourceBase not NSKVOSourceBase or whatever... threads = lldbutil.continue_to_breakpoint(process, handle_SourceBase_bkpt) self.assertTrue(len(threads) == 1) thread = threads[0] frame = thread.GetFrameAtIndex(0) # Get "object" using FindVariable: object_static = frame.FindVariable("object", noDynamic) object_dynamic = frame.FindVariable("object", useDynamic) # Delete this object to make sure that this doesn't cause havoc with the dynamic object that depends on it. del (object_static) self.examine_SourceDerived_ptr(object_dynamic)
def data_formatter_commands(self): """Test that that file and class static variables display correctly.""" self.runCmd("file a.out", CURRENT_EXECUTABLE_SET) bkpt = self.target().FindBreakpointByID(lldbutil.run_break_set_by_source_regexp (self, "Set break point at this line.")) self.runCmd("run", RUN_SUCCEEDED) # The stop reason of the thread should be breakpoint. self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, substrs = ['stopped', 'stop reason = breakpoint']) # This is the function to remove the custom formats in order to have a # clean slate for the next test case. def cleanup(): self.runCmd('type format clear', check=False) self.runCmd('type summary clear', check=False) self.runCmd('type filter clear', check=False) self.runCmd('type synth clear', check=False) self.runCmd("settings set target.max-children-count 256", check=False) # Execute the cleanup function during test case tear down. self.addTearDownHook(cleanup) self.expect('image list', substrs = self.getLibcPlusPlusLibs()) self.expect('frame variable ii', substrs = ['size=0', '{}']) lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect('frame variable ii', substrs = ['size=2', '[0] = ', 'first = 0', 'second = 0', '[1] = ', 'first = 1', 'second = 1']) lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect('frame variable ii', substrs = ['size=4', '[2] = ', 'first = 2', 'second = 0', '[3] = ', 'first = 3', 'second = 1']) lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect("frame variable ii", substrs = ['size=8', '[5] = ', 'first = 5', 'second = 0', '[7] = ', 'first = 7', 'second = 1']) self.expect("p ii", substrs = ['size=8', '[5] = ', 'first = 5', 'second = 0', '[7] = ', 'first = 7', 'second = 1']) # check access-by-index self.expect("frame variable ii[0]", substrs = ['first = 0', 'second = 0']); self.expect("frame variable ii[3]", substrs = ['first =', 'second =']); # check that MightHaveChildren() gets it right self.assertTrue(self.frame().FindVariable("ii").MightHaveChildren(), "ii.MightHaveChildren() says False for non empty!") # check that the expression parser does not make use of # synthetic children instead of running code # TOT clang has a fix for this, which makes the expression command here succeed # since this would make the test fail or succeed depending on clang version in use # this is safer commented for the time being #self.expect("expression ii[8]", matching=False, error=True, # substrs = ['1234567']) lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect('frame variable ii', substrs = ['size=0', '{}']) self.expect('frame variable si', substrs = ['size=0', '{}']) lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect('frame variable si', substrs = ['size=1', '[0] = ', 'first = \"zero\"', 'second = 0']) lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect("frame variable si", substrs = ['size=4', '[0] = ', 'first = \"zero\"', 'second = 0', '[1] = ', 'first = \"one\"', 'second = 1', '[2] = ', 'first = \"two\"', 'second = 2', '[3] = ', 'first = \"three\"', 'second = 3']) self.expect("p si", substrs = ['size=4', '[0] = ', 'first = \"zero\"', 'second = 0', '[1] = ', 'first = \"one\"', 'second = 1', '[2] = ', 'first = \"two\"', 'second = 2', '[3] = ', 'first = \"three\"', 'second = 3']) # check that MightHaveChildren() gets it right self.assertTrue(self.frame().FindVariable("si").MightHaveChildren(), "si.MightHaveChildren() says False for non empty!") # check access-by-index self.expect("frame variable si[0]", substrs = ['first = ', 'one', 'second = 1']); # check that the expression parser does not make use of # synthetic children instead of running code # TOT clang has a fix for this, which makes the expression command here succeed # since this would make the test fail or succeed depending on clang version in use # this is safer commented for the time being #self.expect("expression si[0]", matching=False, error=True, # substrs = ['first = ', 'zero']) lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect('frame variable si', substrs = ['size=0', '{}']) lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect('frame variable is', substrs = ['size=0', '{}']) lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect("frame variable is", substrs = ['size=4', '[0] = ', 'second = \"goofy\"', 'first = 85', '[1] = ', 'second = \"is\"', 'first = 1', '[2] = ', 'second = \"smart\"', 'first = 2', '[3] = ', 'second = \"!!!\"', 'first = 3']) self.expect("p is", substrs = ['size=4', '[0] = ', 'second = \"goofy\"', 'first = 85', '[1] = ', 'second = \"is\"', 'first = 1', '[2] = ', 'second = \"smart\"', 'first = 2', '[3] = ', 'second = \"!!!\"', 'first = 3']) # check that MightHaveChildren() gets it right self.assertTrue(self.frame().FindVariable("is").MightHaveChildren(), "is.MightHaveChildren() says False for non empty!") # check access-by-index self.expect("frame variable is[0]", substrs = ['first = ', 'second =']); # check that the expression parser does not make use of # synthetic children instead of running code # TOT clang has a fix for this, which makes the expression command here succeed # since this would make the test fail or succeed depending on clang version in use # this is safer commented for the time being #self.expect("expression is[0]", matching=False, error=True, # substrs = ['first = ', 'goofy']) lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect('frame variable is', substrs = ['size=0', '{}']) lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect('frame variable ss', substrs = ['size=0', '{}']) lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect("frame variable ss", substrs = ['size=3', '[0] = ', 'second = \"hello\"', 'first = \"ciao\"', '[1] = ', 'second = \"house\"', 'first = \"casa\"', '[2] = ', 'second = \"cat\"', 'first = \"gatto\"']) self.expect("p ss", substrs = ['size=3', '[0] = ', 'second = \"hello\"', 'first = \"ciao\"', '[1] = ', 'second = \"house\"', 'first = \"casa\"', '[2] = ', 'second = \"cat\"', 'first = \"gatto\"']) # check that MightHaveChildren() gets it right self.assertTrue(self.frame().FindVariable("ss").MightHaveChildren(), "ss.MightHaveChildren() says False for non empty!") # check access-by-index self.expect("frame variable ss[2]", substrs = ['gatto', 'cat']); # check that the expression parser does not make use of # synthetic children instead of running code # TOT clang has a fix for this, which makes the expression command here succeed # since this would make the test fail or succeed depending on clang version in use # this is safer commented for the time being #self.expect("expression ss[3]", matching=False, error=True, # substrs = ['gatto']) lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect('frame variable ss', substrs = ['size=0', '{}'])
def test_get_dynamic_vals(self): """Test fetching C++ dynamic values from pointers & references.""" self.build(dictionary=self.getBuildFlags()) exe = os.path.join(os.getcwd(), "a.out") # Create a target from the debugger. target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) # Set up our breakpoints: do_something_bpt = target.BreakpointCreateByLocation( 'pass-to-base.cpp', self.do_something_line) self.assertTrue(do_something_bpt, VALID_BREAKPOINT) first_call_bpt = target.BreakpointCreateByLocation( 'pass-to-base.cpp', self.main_first_call_line) self.assertTrue(first_call_bpt, VALID_BREAKPOINT) second_call_bpt = target.BreakpointCreateByLocation( 'pass-to-base.cpp', self.main_second_call_line) self.assertTrue(second_call_bpt, VALID_BREAKPOINT) # Now launch the process, and do not stop at the entry point. process = target.LaunchSimple(None, None, self.get_process_working_directory()) self.assertTrue(process.GetState() == lldb.eStateStopped, PROCESS_STOPPED) threads = lldbutil.get_threads_stopped_at_breakpoint( process, first_call_bpt) self.assertTrue(len(threads) == 1) thread = threads[0] frame = thread.GetFrameAtIndex(0) # Now find the dynamic addresses of myB and otherB so we can compare them # with the dynamic values we get in doSomething: use_dynamic = lldb.eDynamicCanRunTarget no_dynamic = lldb.eNoDynamicValues myB = frame.FindVariable('myB', no_dynamic) self.assertTrue(myB) myB_loc = int(myB.GetLocation(), 16) otherB = frame.FindVariable('otherB', no_dynamic) self.assertTrue(otherB) otherB_loc = int(otherB.GetLocation(), 16) # Okay now run to doSomething: threads = lldbutil.continue_to_breakpoint(process, do_something_bpt) self.assertTrue(len(threads) == 1) thread = threads[0] frame = thread.GetFrameAtIndex(0) # Get "this" using FindVariable: this_static = frame.FindVariable('this', no_dynamic) this_dynamic = frame.FindVariable('this', use_dynamic) self.examine_value_object_of_this_ptr(this_static, this_dynamic, myB_loc) # Now make sure that the "GetDynamicValue" works: # This doesn't work currently because we can't get dynamic values from ConstResult objects. fetched_dynamic_value = this_static.GetDynamicValue(use_dynamic) self.examine_value_object_of_this_ptr(this_static, fetched_dynamic_value, myB_loc) # And conversely that the GetDynamicValue() interface also works: fetched_static_value = this_dynamic.GetStaticValue() self.examine_value_object_of_this_ptr(fetched_static_value, this_dynamic, myB_loc) # Get "this" using FindValue, make sure that works too: this_static = frame.FindValue('this', lldb.eValueTypeVariableArgument, no_dynamic) this_dynamic = frame.FindValue('this', lldb.eValueTypeVariableArgument, use_dynamic) self.examine_value_object_of_this_ptr(this_static, this_dynamic, myB_loc) # Get "this" using the EvaluateExpression: this_static = frame.EvaluateExpression('this', False) this_dynamic = frame.EvaluateExpression('this', True) self.examine_value_object_of_this_ptr(this_static, this_dynamic, myB_loc) # The "frame var" code uses another path to get into children, so let's # make sure that works as well: self.expect( 'frame var -d run-target --ptr-depth=2 --show-types anotherA.m_client_A', 'frame var finds its way into a child member', patterns=['\(B \*\)']) # Now make sure we also get it right for a reference as well: anotherA_static = frame.FindVariable('anotherA', False) self.assertTrue(anotherA_static) anotherA_static_addr = int(anotherA_static.GetValue(), 16) anotherA_dynamic = frame.FindVariable('anotherA', True) self.assertTrue(anotherA_dynamic) anotherA_dynamic_addr = int(anotherA_dynamic.GetValue(), 16) anotherA_dynamic_typename = anotherA_dynamic.GetTypeName() self.assertTrue(anotherA_dynamic_typename.find('B') != -1) self.assertTrue(anotherA_dynamic_addr < anotherA_static_addr) anotherA_m_b_value_dynamic = anotherA_dynamic.GetChildMemberWithName( 'm_b_value', True) self.assertTrue(anotherA_m_b_value_dynamic) anotherA_m_b_val = int(anotherA_m_b_value_dynamic.GetValue(), 10) self.assertTrue(anotherA_m_b_val == 300) anotherA_m_b_value_static = anotherA_static.GetChildMemberWithName( 'm_b_value', True) self.assertFalse(anotherA_m_b_value_static) # Okay, now continue again, and when we hit the second breakpoint in main threads = lldbutil.continue_to_breakpoint(process, second_call_bpt) self.assertTrue(len(threads) == 1) thread = threads[0] frame = thread.GetFrameAtIndex(0) reallyA_value = frame.FindVariable('reallyA', False) self.assertTrue(reallyA_value) reallyA_loc = int(reallyA_value.GetLocation(), 16) # Finally continue to doSomething again, and make sure we get the right value for anotherA, # which this time around is just an "A". threads = lldbutil.continue_to_breakpoint(process, do_something_bpt) self.assertTrue(len(threads) == 1) thread = threads[0] frame = thread.GetFrameAtIndex(0) anotherA_value = frame.FindVariable('anotherA', True) self.assertTrue(anotherA_value) anotherA_loc = int(anotherA_value.GetValue(), 16) self.assertTrue(anotherA_loc == reallyA_loc) self.assertTrue(anotherA_value.GetTypeName().find('B') == -1)
def test_with_python_api(self): """Test stepping and setting breakpoints in indirect and re-exported symbols.""" self.build() exe = os.path.join(os.getcwd(), "a.out") target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) self.main_source_spec = lldb.SBFileSpec (self.main_source) break1 = target.BreakpointCreateBySourceRegex ("Set breakpoint here to step in indirect.", self.main_source_spec) self.assertTrue(break1, VALID_BREAKPOINT) break2 = target.BreakpointCreateBySourceRegex ("Set breakpoint here to step in reexported.", self.main_source_spec) self.assertTrue(break2, VALID_BREAKPOINT) # Now launch the process, and do not stop at entry point. process = target.LaunchSimple (None, None, self.get_process_working_directory()) self.assertTrue(process, PROCESS_IS_VALID) # The stop reason of the thread should be breakpoint. threads = lldbutil.get_threads_stopped_at_breakpoint (process, break1) if len(threads) != 1: self.fail ("Failed to stop at breakpoint 1.") thread = threads[0] # Now do a step-into, and we should end up in the hidden target of this indirect function. thread.StepInto() curr_function = thread.GetFrameAtIndex(0).GetFunctionName() self.assertTrue (curr_function == "call_through_indirect_hidden", "Stepped into indirect symbols.") # Now set a breakpoint using the indirect symbol name, and make sure we get to that: break_indirect = target.BreakpointCreateByName ("call_through_indirect"); self.assertTrue (break_indirect, VALID_BREAKPOINT) # Now continue should take us to the second call through the indirect symbol: threads = lldbutil.continue_to_breakpoint (process, break_indirect) self.assertTrue (len(threads) == 1, "Stopped at breakpoint in indirect function.") curr_function = thread.GetFrameAtIndex(0).GetFunctionName() self.assertTrue (curr_function == "call_through_indirect_hidden", "Stepped into indirect symbols.") # Delete this breakpoint so it won't get in the way: target.BreakpointDelete (break_indirect.GetID()) # Now continue to the site of the first re-exported function call in main: threads = lldbutil.continue_to_breakpoint (process, break2) # This is stepping Into through a re-exported symbol to an indirect symbol: thread.StepInto() curr_function = thread.GetFrameAtIndex(0).GetFunctionName() self.assertTrue (curr_function == "call_through_indirect_hidden", "Stepped into indirect symbols.") # And the last bit is to set a breakpoint on the re-exported symbol and make sure we are again in out target function. break_reexported = target.BreakpointCreateByName ("reexport_to_indirect"); self.assertTrue (break_reexported, VALID_BREAKPOINT) # Now continue should take us to the second call through the indirect symbol: threads = lldbutil.continue_to_breakpoint (process, break_reexported) self.assertTrue (len(threads) == 1, "Stopped at breakpoint in reexported function target.") curr_function = thread.GetFrameAtIndex(0).GetFunctionName() self.assertTrue (curr_function == "call_through_indirect_hidden", "Stepped into indirect symbols.")
def step_over_stepping(self): """Use Python APIs to test stepping over and hitting breakpoints.""" exe = os.path.join(os.getcwd(), "a.out") target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) self.main_source_spec = lldb.SBFileSpec(self.main_source) breakpoints_to_disable = [] break_1_in_main = target.BreakpointCreateBySourceRegex( '// frame select 2, thread step-out while stopped at .c.1..', self.main_source_spec) self.assertTrue(break_1_in_main, VALID_BREAKPOINT) breakpoints_to_disable.append(break_1_in_main) break_in_a = target.BreakpointCreateBySourceRegex( '// break here to stop in a before calling b', self.main_source_spec) self.assertTrue(break_in_a, VALID_BREAKPOINT) breakpoints_to_disable.append(break_in_a) break_in_b = target.BreakpointCreateBySourceRegex( '// thread step-out while stopped at .c.2..', self.main_source_spec) self.assertTrue(break_in_b, VALID_BREAKPOINT) breakpoints_to_disable.append(break_in_b) break_in_c = target.BreakpointCreateBySourceRegex( '// Find the line number of function .c. here.', self.main_source_spec) self.assertTrue(break_in_c, VALID_BREAKPOINT) breakpoints_to_disable.append(break_in_c) # Now launch the process, and do not stop at entry point. process = target.LaunchSimple(None, None, os.getcwd()) self.assertTrue(process, PROCESS_IS_VALID) # The stop reason of the thread should be breakpoint. threads = lldbutil.get_threads_stopped_at_breakpoint( process, break_1_in_main) if len(threads) != 1: self.fail("Failed to stop at first breakpoint in main.") thread = threads[0] # Get the stop id and for fun make sure it increases: old_stop_id = process.GetStopID() # Now step over, which should cause us to hit the breakpoint in "a" thread.StepOver() # The stop reason of the thread should be breakpoint. threads = lldbutil.get_threads_stopped_at_breakpoint( process, break_in_a) if len(threads) != 1: self.fail("Failed to stop at breakpoint in a.") # Check that the stop ID increases: new_stop_id = process.GetStopID() self.assertTrue(new_stop_id > old_stop_id, "Stop ID increases monotonically.") thread = threads[0] # Step over, and we should hit the breakpoint in b: thread.StepOver() threads = lldbutil.get_threads_stopped_at_breakpoint( process, break_in_b) if len(threads) != 1: self.fail("Failed to stop at breakpoint in b.") thread = threads[0] # Now try running some function, and make sure that we still end up in the same place # and with the same stop reason. frame = thread.GetFrameAtIndex(0) current_line = frame.GetLineEntry().GetLine() current_file = frame.GetLineEntry().GetFileSpec() current_bp = [] current_bp.append(thread.GetStopReasonDataAtIndex(0)) current_bp.append(thread.GetStopReasonDataAtIndex(1)) stop_id_before_expression = process.GetStopID() stop_id_before_including_expressions = process.GetStopID(True) frame.EvaluateExpression("(int) printf (print_string)") frame = thread.GetFrameAtIndex(0) self.assertTrue(current_line == frame.GetLineEntry().GetLine(), "The line stayed the same after expression.") self.assertTrue(current_file == frame.GetLineEntry().GetFileSpec(), "The file stayed the same after expression.") self.assertTrue(thread.GetStopReason() == lldb.eStopReasonBreakpoint, "We still say we stopped for a breakpoint.") self.assertTrue( thread.GetStopReasonDataAtIndex(0) == current_bp[0] and thread.GetStopReasonDataAtIndex(1) == current_bp[1], "And it is the same breakpoint.") # Also make sure running the expression didn't change the public stop id # but did change if we are asking for expression stops as well. stop_id_after_expression = process.GetStopID() stop_id_after_including_expressions = process.GetStopID(True) self.assertTrue(stop_id_before_expression == stop_id_after_expression, "Expression calling doesn't change stop ID") self.assertTrue( stop_id_after_including_expressions > stop_id_before_including_expressions, "Stop ID including expressions increments over expression call.") # Do the same thing with an expression that's going to crash, and make sure we are still unchanged. frame.EvaluateExpression("((char *) 0)[0] = 'a'") frame = thread.GetFrameAtIndex(0) self.assertTrue(current_line == frame.GetLineEntry().GetLine(), "The line stayed the same after expression.") self.assertTrue(current_file == frame.GetLineEntry().GetFileSpec(), "The file stayed the same after expression.") self.assertTrue(thread.GetStopReason() == lldb.eStopReasonBreakpoint, "We still say we stopped for a breakpoint.") self.assertTrue( thread.GetStopReasonDataAtIndex(0) == current_bp[0] and thread.GetStopReasonDataAtIndex(1) == current_bp[1], "And it is the same breakpoint.") # Now continue and make sure we just complete the step: # Disable all our breakpoints first - sometimes the compiler puts two line table entries in for the # breakpoint a "b" and we don't want to hit that. for bkpt in breakpoints_to_disable: bkpt.SetEnabled(False) process.Continue() self.assertTrue(thread.GetFrameAtIndex(0).GetFunctionName() == "a") self.assertTrue(thread.GetStopReason() == lldb.eStopReasonPlanComplete) # And one more time should get us back to main: process.Continue() self.assertTrue(thread.GetFrameAtIndex(0).GetFunctionName() == "main") self.assertTrue(thread.GetStopReason() == lldb.eStopReasonPlanComplete) # Now make sure we can call a function, break in the called function, then have "continue" get us back out again: frame = thread.GetFrameAtIndex(0) frame = thread.GetFrameAtIndex(0) current_line = frame.GetLineEntry().GetLine() current_file = frame.GetLineEntry().GetFileSpec() break_in_b.SetEnabled(True) frame.EvaluateExpression("b (4)", lldb.eNoDynamicValues, False) threads = lldbutil.get_threads_stopped_at_breakpoint( process, break_in_b) if len(threads) != 1: self.fail("Failed to stop at breakpoint in b when calling b.") thread = threads[0] # So do a step over here to make sure we can still do that: thread.StepOver() # See that we are still in b: self.assertTrue(thread.GetFrameAtIndex(0).GetFunctionName() == "b") # Okay, now if we continue, we will finish off our function call and we should end up back in "a" as if nothing had happened: process.Continue() self.assertTrue( thread.GetFrameAtIndex(0).GetLineEntry().GetLine() == current_line) self.assertTrue( thread.GetFrameAtIndex(0).GetLineEntry().GetFileSpec() == current_file) # Now we are going to test step in targetting a function: break_in_b.SetEnabled(False) break_before_complex_1 = target.BreakpointCreateBySourceRegex( '// Stop here to try step in targetting b.', self.main_source_spec) self.assertTrue(break_before_complex_1, VALID_BREAKPOINT) break_before_complex_2 = target.BreakpointCreateBySourceRegex( '// Stop here to try step in targetting complex.', self.main_source_spec) self.assertTrue(break_before_complex_2, VALID_BREAKPOINT) break_before_complex_3 = target.BreakpointCreateBySourceRegex( '// Stop here to step targetting b and hitting breakpoint.', self.main_source_spec) self.assertTrue(break_before_complex_3, VALID_BREAKPOINT) break_before_complex_4 = target.BreakpointCreateBySourceRegex( '// Stop here to make sure bogus target steps over.', self.main_source_spec) self.assertTrue(break_before_complex_4, VALID_BREAKPOINT) threads = lldbutil.continue_to_breakpoint(process, break_before_complex_1) self.assertTrue(len(threads) == 1) thread = threads[0] break_before_complex_1.SetEnabled(False) thread.StepInto("b") self.assertTrue(thread.GetFrameAtIndex(0).GetFunctionName() == "b") # Now continue out and stop at the next call to complex. This time step all the way into complex: threads = lldbutil.continue_to_breakpoint(process, break_before_complex_2) self.assertTrue(len(threads) == 1) thread = threads[0] break_before_complex_2.SetEnabled(False) thread.StepInto("complex") self.assertTrue( thread.GetFrameAtIndex(0).GetFunctionName() == "complex") # Now continue out and stop at the next call to complex. This time enable breakpoints in a and c and then step targetting b: threads = lldbutil.continue_to_breakpoint(process, break_before_complex_3) self.assertTrue(len(threads) == 1) thread = threads[0] break_before_complex_3.SetEnabled(False) break_at_start_of_a = target.BreakpointCreateByName('a') break_at_start_of_c = target.BreakpointCreateByName('c') thread.StepInto("b") threads = lldbutil.get_stopped_threads(process, lldb.eStopReasonBreakpoint) self.assertTrue(len(threads) == 1) thread = threads[0] stop_break_id = thread.GetStopReasonDataAtIndex(0) self.assertTrue(stop_break_id == break_at_start_of_a.GetID() or stop_break_id == break_at_start_of_c.GetID()) break_at_start_of_a.SetEnabled(False) break_at_start_of_c.SetEnabled(False) process.Continue() self.assertTrue(thread.GetFrameAtIndex(0).GetFunctionName() == "b") # Now continue out and stop at the next call to complex. This time enable breakpoints in a and c and then step targetting b: threads = lldbutil.continue_to_breakpoint(process, break_before_complex_4) self.assertTrue(len(threads) == 1) thread = threads[0] break_before_complex_4.SetEnabled(False) thread.StepInto("NoSuchFunction") self.assertTrue(thread.GetFrameAtIndex(0).GetFunctionName() == "main")
def test_with_python_api(self): """Test stepping and setting breakpoints in indirect and re-exported symbols.""" self.build() exe = os.path.join(os.getcwd(), "a.out") target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) self.main_source_spec = lldb.SBFileSpec(self.main_source) break1 = target.BreakpointCreateBySourceRegex( "Set breakpoint here to step in indirect.", self.main_source_spec) self.assertTrue(break1, VALID_BREAKPOINT) break2 = target.BreakpointCreateBySourceRegex( "Set breakpoint here to step in reexported.", self.main_source_spec) self.assertTrue(break2, VALID_BREAKPOINT) # Now launch the process, and do not stop at entry point. process = target.LaunchSimple(None, None, self.get_process_working_directory()) self.assertTrue(process, PROCESS_IS_VALID) # The stop reason of the thread should be breakpoint. threads = lldbutil.get_threads_stopped_at_breakpoint(process, break1) if len(threads) != 1: self.fail("Failed to stop at breakpoint 1.") thread = threads[0] # Now do a step-into, and we should end up in the hidden target of this indirect function. thread.StepInto() curr_function = thread.GetFrameAtIndex(0).GetFunctionName() self.assertTrue(curr_function == "call_through_indirect_hidden", "Stepped into indirect symbols.") # Now set a breakpoint using the indirect symbol name, and make sure we get to that: break_indirect = target.BreakpointCreateByName("call_through_indirect") self.assertTrue(break_indirect, VALID_BREAKPOINT) # Now continue should take us to the second call through the indirect symbol: threads = lldbutil.continue_to_breakpoint(process, break_indirect) self.assertTrue( len(threads) == 1, "Stopped at breakpoint in indirect function.") curr_function = thread.GetFrameAtIndex(0).GetFunctionName() self.assertTrue(curr_function == "call_through_indirect_hidden", "Stepped into indirect symbols.") # Delete this breakpoint so it won't get in the way: target.BreakpointDelete(break_indirect.GetID()) # Now continue to the site of the first re-exported function call in main: threads = lldbutil.continue_to_breakpoint(process, break2) # This is stepping Into through a re-exported symbol to an indirect symbol: thread.StepInto() curr_function = thread.GetFrameAtIndex(0).GetFunctionName() self.assertTrue(curr_function == "call_through_indirect_hidden", "Stepped into indirect symbols.") # And the last bit is to set a breakpoint on the re-exported symbol and make sure we are again in out target function. break_reexported = target.BreakpointCreateByName( "reexport_to_indirect") self.assertTrue(break_reexported, VALID_BREAKPOINT) # Now continue should take us to the second call through the indirect symbol: threads = lldbutil.continue_to_breakpoint(process, break_reexported) self.assertTrue( len(threads) == 1, "Stopped at breakpoint in reexported function target.") curr_function = thread.GetFrameAtIndex(0).GetFunctionName() self.assertTrue(curr_function == "call_through_indirect_hidden", "Stepped into indirect symbols.")
def objc_stepping(self): """Use Python APIs to test stepping into ObjC methods.""" exe = os.path.join(os.getcwd(), "a.out") target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) self.main_source_spec = lldb.SBFileSpec(self.main_source) breakpoints_to_disable = [] break1 = target.BreakpointCreateBySourceRegex( "// Set first breakpoint here.", self.main_source_spec) self.assertTrue(break1, VALID_BREAKPOINT) breakpoints_to_disable.append(break1) break2 = target.BreakpointCreateBySourceRegex( "// Set second breakpoint here.", self.main_source_spec) self.assertTrue(break2, VALID_BREAKPOINT) breakpoints_to_disable.append(break2) break3 = target.BreakpointCreateBySourceRegex( '// Set third breakpoint here.', self.main_source_spec) self.assertTrue(break3, VALID_BREAKPOINT) breakpoints_to_disable.append(break3) break4 = target.BreakpointCreateBySourceRegex( '// Set fourth breakpoint here.', self.main_source_spec) self.assertTrue(break4, VALID_BREAKPOINT) breakpoints_to_disable.append(break4) break5 = target.BreakpointCreateBySourceRegex( '// Set fifth breakpoint here.', self.main_source_spec) self.assertTrue(break5, VALID_BREAKPOINT) breakpoints_to_disable.append(break5) break_returnStruct_call_super = target.BreakpointCreateBySourceRegex( '// Source returnsStruct call line.', self.main_source_spec) self.assertTrue(break_returnStruct_call_super, VALID_BREAKPOINT) breakpoints_to_disable.append(break_returnStruct_call_super) break_step_nil = target.BreakpointCreateBySourceRegex( '// Set nil step breakpoint here.', self.main_source_spec) self.assertTrue(break_step_nil, VALID_BREAKPOINT) # Now launch the process, and do not stop at entry point. process = target.LaunchSimple(None, None, self.get_process_working_directory()) self.assertTrue(process, PROCESS_IS_VALID) # The stop reason of the thread should be breakpoint. threads = lldbutil.get_threads_stopped_at_breakpoint(process, break1) if len(threads) != 1: self.fail("Failed to stop at breakpoint 1.") thread = threads[0] mySource = thread.GetFrameAtIndex(0).FindVariable("mySource") self.assertTrue(mySource, "Found mySource local variable.") mySource_isa = mySource.GetChildMemberWithName("isa") self.assertTrue(mySource_isa, "Found mySource->isa local variable.") className = mySource_isa.GetSummary() if self.TraceOn(): print mySource_isa # Lets delete mySource so we can check that after stepping a child variable # with no parent persists and is useful. del (mySource) # Now step in, that should leave us in the Source randomMethod: thread.StepInto() line_number = thread.GetFrameAtIndex(0).GetLineEntry().GetLine() self.assertTrue(line_number == self.source_randomMethod_line, "Stepped into Source randomMethod.") # Now step in again, through the super call, and that should leave us in the SourceBase randomMethod: thread.StepInto() line_number = thread.GetFrameAtIndex(0).GetLineEntry().GetLine() self.assertTrue(line_number == self.sourceBase_randomMethod_line, "Stepped through super into SourceBase randomMethod.") threads = lldbutil.continue_to_breakpoint(process, break2) self.assertTrue( len(threads) == 1, "Continued to second breakpoint in main.") # Again, step in twice gets us to a stret method and a stret super call: thread = threads[0] thread.StepInto() line_number = thread.GetFrameAtIndex(0).GetLineEntry().GetLine() self.assertTrue(line_number == self.source_returnsStruct_start_line, "Stepped into Source returnsStruct.") threads = lldbutil.continue_to_breakpoint( process, break_returnStruct_call_super) self.assertTrue( len(threads) == 1, "Stepped to the call super line in Source returnsStruct.") thread = threads[0] thread.StepInto() line_number = thread.GetFrameAtIndex(0).GetLineEntry().GetLine() self.assertTrue( line_number == self.sourceBase_returnsStruct_start_line, "Stepped through super into SourceBase returnsStruct.") # Cool now continue to get past the call that intializes the Observer, and then do our steps in again to see that # we can find our way when we're stepping through a KVO swizzled object. threads = lldbutil.continue_to_breakpoint(process, break3) self.assertTrue( len(threads) == 1, "Continued to third breakpoint in main, our object should now be swizzled." ) newClassName = mySource_isa.GetSummary() if self.TraceOn(): print mySource_isa self.assertTrue(newClassName != className, "The isa did indeed change, swizzled!") # Now step in, that should leave us in the Source randomMethod: thread = threads[0] thread.StepInto() line_number = thread.GetFrameAtIndex(0).GetLineEntry().GetLine() self.assertTrue( line_number == self.source_randomMethod_line, "Stepped into Source randomMethod in swizzled object.") # Now step in again, through the super call, and that should leave us in the SourceBase randomMethod: thread.StepInto() line_number = thread.GetFrameAtIndex(0).GetLineEntry().GetLine() self.assertTrue( line_number == self.sourceBase_randomMethod_line, "Stepped through super into SourceBase randomMethod in swizzled object." ) threads = lldbutil.continue_to_breakpoint(process, break4) self.assertTrue( len(threads) == 1, "Continued to fourth breakpoint in main.") thread = threads[0] # Again, step in twice gets us to a stret method and a stret super call: thread.StepInto() line_number = thread.GetFrameAtIndex(0).GetLineEntry().GetLine() self.assertTrue( line_number == self.source_returnsStruct_start_line, "Stepped into Source returnsStruct in swizzled object.") threads = lldbutil.continue_to_breakpoint( process, break_returnStruct_call_super) self.assertTrue( len(threads) == 1, "Stepped to the call super line in Source returnsStruct - second time." ) thread = threads[0] thread.StepInto() line_number = thread.GetFrameAtIndex(0).GetLineEntry().GetLine() self.assertTrue( line_number == self.sourceBase_returnsStruct_start_line, "Stepped through super into SourceBase returnsStruct in swizzled object." ) for bkpt in breakpoints_to_disable: bkpt.SetEnabled(False) threads = lldbutil.continue_to_breakpoint(process, break_step_nil) self.assertTrue(len(threads) == 1, "Continued to step nil breakpoint.") thread.StepInto() line_number = thread.GetFrameAtIndex(0).GetLineEntry().GetLine() self.assertTrue(line_number == self.stepped_past_nil_line, "Step in over dispatch to nil stepped over.")
def step_over_stepping(self): """Use Python APIs to test stepping over and hitting breakpoints.""" exe = os.path.join(os.getcwd(), "a.out") target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) self.main_source_spec = lldb.SBFileSpec (self.main_source) breakpoints_to_disable = [] break_1_in_main = target.BreakpointCreateBySourceRegex ('// frame select 2, thread step-out while stopped at .c.1..', self.main_source_spec) self.assertTrue(break_1_in_main, VALID_BREAKPOINT) breakpoints_to_disable.append (break_1_in_main) break_in_a = target.BreakpointCreateBySourceRegex ('// break here to stop in a before calling b', self.main_source_spec) self.assertTrue(break_in_a, VALID_BREAKPOINT) breakpoints_to_disable.append (break_in_a) break_in_b = target.BreakpointCreateBySourceRegex ('// thread step-out while stopped at .c.2..', self.main_source_spec) self.assertTrue(break_in_b, VALID_BREAKPOINT) breakpoints_to_disable.append (break_in_b) break_in_c = target.BreakpointCreateBySourceRegex ('// Find the line number of function .c. here.', self.main_source_spec) self.assertTrue(break_in_c, VALID_BREAKPOINT) breakpoints_to_disable.append (break_in_c) # Now launch the process, and do not stop at entry point. process = target.LaunchSimple (None, None, os.getcwd()) self.assertTrue(process, PROCESS_IS_VALID) # The stop reason of the thread should be breakpoint. threads = lldbutil.get_threads_stopped_at_breakpoint (process, break_1_in_main) if len(threads) != 1: self.fail ("Failed to stop at first breakpoint in main.") thread = threads[0] # Get the stop id and for fun make sure it increases: old_stop_id = process.GetStopID() # Now step over, which should cause us to hit the breakpoint in "a" thread.StepOver() # The stop reason of the thread should be breakpoint. threads = lldbutil.get_threads_stopped_at_breakpoint (process, break_in_a) if len(threads) != 1: self.fail ("Failed to stop at breakpoint in a.") # Check that the stop ID increases: new_stop_id = process.GetStopID() self.assertTrue(new_stop_id > old_stop_id, "Stop ID increases monotonically.") thread = threads[0] # Step over, and we should hit the breakpoint in b: thread.StepOver() threads = lldbutil.get_threads_stopped_at_breakpoint (process, break_in_b) if len(threads) != 1: self.fail ("Failed to stop at breakpoint in b.") thread = threads[0] # Now try running some function, and make sure that we still end up in the same place # and with the same stop reason. frame = thread.GetFrameAtIndex(0) current_line = frame.GetLineEntry().GetLine() current_file = frame.GetLineEntry().GetFileSpec() current_bp = [] current_bp.append(thread.GetStopReasonDataAtIndex(0)) current_bp.append(thread.GetStopReasonDataAtIndex(1)) stop_id_before_expression = process.GetStopID() stop_id_before_including_expressions = process.GetStopID(True) frame.EvaluateExpression ("(int) printf (print_string)") frame = thread.GetFrameAtIndex(0) self.assertTrue (current_line == frame.GetLineEntry().GetLine(), "The line stayed the same after expression.") self.assertTrue (current_file == frame.GetLineEntry().GetFileSpec(), "The file stayed the same after expression.") self.assertTrue (thread.GetStopReason() == lldb.eStopReasonBreakpoint, "We still say we stopped for a breakpoint.") self.assertTrue (thread.GetStopReasonDataAtIndex(0) == current_bp[0] and thread.GetStopReasonDataAtIndex(1) == current_bp[1], "And it is the same breakpoint.") # Also make sure running the expression didn't change the public stop id # but did change if we are asking for expression stops as well. stop_id_after_expression = process.GetStopID() stop_id_after_including_expressions = process.GetStopID(True) self.assertTrue (stop_id_before_expression == stop_id_after_expression, "Expression calling doesn't change stop ID") self.assertTrue (stop_id_after_including_expressions > stop_id_before_including_expressions, "Stop ID including expressions increments over expression call.") # Do the same thing with an expression that's going to crash, and make sure we are still unchanged. frame.EvaluateExpression ("((char *) 0)[0] = 'a'") frame = thread.GetFrameAtIndex(0) self.assertTrue (current_line == frame.GetLineEntry().GetLine(), "The line stayed the same after expression.") self.assertTrue (current_file == frame.GetLineEntry().GetFileSpec(), "The file stayed the same after expression.") self.assertTrue (thread.GetStopReason() == lldb.eStopReasonBreakpoint, "We still say we stopped for a breakpoint.") self.assertTrue (thread.GetStopReasonDataAtIndex(0) == current_bp[0] and thread.GetStopReasonDataAtIndex(1) == current_bp[1], "And it is the same breakpoint.") # Now continue and make sure we just complete the step: # Disable all our breakpoints first - sometimes the compiler puts two line table entries in for the # breakpoint a "b" and we don't want to hit that. for bkpt in breakpoints_to_disable: bkpt.SetEnabled(False) process.Continue() self.assertTrue (thread.GetFrameAtIndex(0).GetFunctionName() == "a") self.assertTrue (thread.GetStopReason() == lldb.eStopReasonPlanComplete) # And one more time should get us back to main: process.Continue() self.assertTrue (thread.GetFrameAtIndex(0).GetFunctionName() == "main") self.assertTrue (thread.GetStopReason() == lldb.eStopReasonPlanComplete) # Now make sure we can call a function, break in the called function, then have "continue" get us back out again: frame = thread.GetFrameAtIndex(0) frame = thread.GetFrameAtIndex(0) current_line = frame.GetLineEntry().GetLine() current_file = frame.GetLineEntry().GetFileSpec() break_in_b.SetEnabled(True) frame.EvaluateExpression ("b (4)", lldb.eNoDynamicValues, False) threads = lldbutil.get_threads_stopped_at_breakpoint (process, break_in_b) if len(threads) != 1: self.fail ("Failed to stop at breakpoint in b when calling b.") thread = threads[0] # So do a step over here to make sure we can still do that: thread.StepOver() # See that we are still in b: self.assertTrue (thread.GetFrameAtIndex(0).GetFunctionName() == "b") # Okay, now if we continue, we will finish off our function call and we should end up back in "a" as if nothing had happened: process.Continue () self.assertTrue (thread.GetFrameAtIndex(0).GetLineEntry().GetLine() == current_line) self.assertTrue (thread.GetFrameAtIndex(0).GetLineEntry().GetFileSpec() == current_file) # Now we are going to test step in targetting a function: break_in_b.SetEnabled (False) break_before_complex_1 = target.BreakpointCreateBySourceRegex ('// Stop here to try step in targetting b.', self.main_source_spec) self.assertTrue(break_before_complex_1, VALID_BREAKPOINT) break_before_complex_2 = target.BreakpointCreateBySourceRegex ('// Stop here to try step in targetting complex.', self.main_source_spec) self.assertTrue(break_before_complex_2, VALID_BREAKPOINT) break_before_complex_3 = target.BreakpointCreateBySourceRegex ('// Stop here to step targetting b and hitting breakpoint.', self.main_source_spec) self.assertTrue(break_before_complex_3, VALID_BREAKPOINT) break_before_complex_4 = target.BreakpointCreateBySourceRegex ('// Stop here to make sure bogus target steps over.', self.main_source_spec) self.assertTrue(break_before_complex_4, VALID_BREAKPOINT) threads = lldbutil.continue_to_breakpoint(process, break_before_complex_1) self.assertTrue (len(threads) == 1) thread = threads[0] break_before_complex_1.SetEnabled(False) thread.StepInto ("b") self.assertTrue (thread.GetFrameAtIndex(0).GetFunctionName() == "b") # Now continue out and stop at the next call to complex. This time step all the way into complex: threads = lldbutil.continue_to_breakpoint (process, break_before_complex_2) self.assertTrue (len(threads) == 1) thread = threads[0] break_before_complex_2.SetEnabled(False) thread.StepInto ("complex") self.assertTrue (thread.GetFrameAtIndex(0).GetFunctionName() == "complex") # Now continue out and stop at the next call to complex. This time enable breakpoints in a and c and then step targetting b: threads = lldbutil.continue_to_breakpoint (process, break_before_complex_3) self.assertTrue (len(threads) == 1) thread = threads[0] break_before_complex_3.SetEnabled(False) break_at_start_of_a = target.BreakpointCreateByName ('a') break_at_start_of_c = target.BreakpointCreateByName ('c') thread.StepInto ("b") threads = lldbutil.get_stopped_threads(process, lldb.eStopReasonBreakpoint); self.assertTrue (len(threads) == 1) thread = threads[0] stop_break_id = thread.GetStopReasonDataAtIndex(0) self.assertTrue(stop_break_id == break_at_start_of_a.GetID() or stop_break_id == break_at_start_of_c.GetID()) break_at_start_of_a.SetEnabled(False) break_at_start_of_c.SetEnabled(False) process.Continue() self.assertTrue (thread.GetFrameAtIndex(0).GetFunctionName() == "b") # Now continue out and stop at the next call to complex. This time enable breakpoints in a and c and then step targetting b: threads = lldbutil.continue_to_breakpoint (process, break_before_complex_4) self.assertTrue (len(threads) == 1) thread = threads[0] break_before_complex_4.SetEnabled(False) thread.StepInto("NoSuchFunction") self.assertTrue (thread.GetFrameAtIndex(0).GetFunctionName() == "main")
def data_formatter_commands(self): """Test that that file and class static variables display correctly.""" self.runCmd("file a.out", CURRENT_EXECUTABLE_SET) bkpt = self.target().FindBreakpointByID( lldbutil.run_break_set_by_source_regexp(self, "break here")) self.runCmd("run", RUN_SUCCEEDED) # The stop reason of the thread should be breakpoint. self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, substrs=['stopped', 'stop reason = breakpoint']) # This is the function to remove the custom formats in order to have a # clean slate for the next test case. def cleanup(): self.runCmd('type format clear', check=False) self.runCmd('type summary clear', check=False) self.runCmd('type filter clear', check=False) self.runCmd('type synth clear', check=False) self.runCmd("settings set target.max-children-count 256", check=False) # Execute the cleanup function during test case tear down. self.addTearDownHook(cleanup) # empty vectors (and storage pointers SHOULD BOTH BE NULL..) self.expect("frame variable numbers", substrs=['numbers = size=0']) lldbutil.continue_to_breakpoint(self.process(), bkpt) # first value added self.expect("frame variable numbers", substrs=['numbers = size=1', '[0] = 1', '}']) # add some more data lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect("frame variable numbers", substrs=[ 'numbers = size=4', '[0] = 1', '[1] = 12', '[2] = 123', '[3] = 1234', '}' ]) self.expect("p numbers", substrs=[ '$', 'size=4', '[0] = 1', '[1] = 12', '[2] = 123', '[3] = 1234', '}' ]) # check access to synthetic children self.runCmd( "type summary add --summary-string \"item 0 is ${var[0]}\" std::int_vect int_vect" ) self.expect('frame variable numbers', substrs=['item 0 is 1']) self.runCmd( "type summary add --summary-string \"item 0 is ${svar[0]}\" std::int_vect int_vect" ) self.expect('frame variable numbers', substrs=['item 0 is 1']) # move on with synths self.runCmd("type summary delete std::int_vect") self.runCmd("type summary delete int_vect") # add some more data lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect("frame variable numbers", substrs=[ 'numbers = size=7', '[0] = 1', '[1] = 12', '[2] = 123', '[3] = 1234', '[4] = 12345', '[5] = 123456', '[6] = 1234567', '}' ]) self.expect("p numbers", substrs=[ '$', 'size=7', '[0] = 1', '[1] = 12', '[2] = 123', '[3] = 1234', '[4] = 12345', '[5] = 123456', '[6] = 1234567', '}' ]) # check access-by-index self.expect("frame variable numbers[0]", substrs=['1']) self.expect("frame variable numbers[1]", substrs=['12']) self.expect("frame variable numbers[2]", substrs=['123']) self.expect("frame variable numbers[3]", substrs=['1234']) # clear out the vector and see that we do the right thing once again lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect("frame variable numbers", substrs=['numbers = size=0']) lldbutil.continue_to_breakpoint(self.process(), bkpt) # first value added self.expect("frame variable numbers", substrs=['numbers = size=1', '[0] = 7', '}']) # check if we can display strings self.expect("frame variable strings", substrs=['goofy', 'is', 'smart']) self.expect("p strings", substrs=['goofy', 'is', 'smart']) # test summaries based on synthetic children self.runCmd( "type summary add std::string_vect string_vect --summary-string \"vector has ${svar%#} items\" -e" ) self.expect("frame variable strings", substrs=['vector has 3 items', 'goofy', 'is', 'smart']) self.expect("p strings", substrs=['vector has 3 items', 'goofy', 'is', 'smart']) lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect("frame variable strings", substrs=['vector has 4 items']) # check access-by-index self.expect("frame variable strings[0]", substrs=['goofy']) self.expect("frame variable strings[1]", substrs=['is']) lldbutil.continue_to_breakpoint(self.process(), bkpt) self.expect("frame variable strings", substrs=['vector has 0 items'])
def inline_stepping(self): """Use Python APIs to test stepping over and hitting breakpoints.""" exe = os.path.join(os.getcwd(), "a.out") target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) break_1_in_main = target.BreakpointCreateBySourceRegex ('// Stop here and step over to set up stepping over.', self.main_source_spec) self.assertTrue(break_1_in_main, VALID_BREAKPOINT) # Now launch the process, and do not stop at entry point. self.process = target.LaunchSimple (None, None, self.get_process_working_directory()) self.assertTrue(self.process, PROCESS_IS_VALID) # The stop reason of the thread should be breakpoint. threads = lldbutil.get_threads_stopped_at_breakpoint (self.process, break_1_in_main) if len(threads) != 1: self.fail ("Failed to stop at first breakpoint in main.") self.thread = threads[0] # Step over the inline_value = 0 line to get us to inline_trivial_1 called from main. Doing it this way works # around a bug in lldb where the breakpoint on the containing line of an inlined function with no return value # gets set past the insertion line in the function. # Then test stepping over a simple inlined function. Note, to test all the parts of the inlined stepping # the calls inline_stepping_1 and inline_stepping_2 should line up at the same address, that way we will test # the "virtual" stepping. # FIXME: Put in a check to see if that is true and warn if it is not. step_sequence = [["// At inline_trivial_1 called from main.", "over"], ["// At first call of caller_trivial_1 in main.", "over"]] self.run_step_sequence(step_sequence) # Now step from caller_ref_1 all the way into called_by_inline_trivial step_sequence = [["// In caller_trivial_1.", "into"], ["// In caller_trivial_2.", "into"], ["// In inline_trivial_1.", "into"], ["// In inline_trivial_2.", "into"], ["// At caller_by_inline_trivial in inline_trivial_2.", "over"], ["// In called_by_inline_trivial.", "into"]] self.run_step_sequence(step_sequence) # Now run to the inline_trivial_1 just before the immediate step into inline_trivial_2: break_2_in_main = target.BreakpointCreateBySourceRegex ('// At second call of caller_trivial_1 in main.', self.main_source_spec) self.assertTrue(break_2_in_main, VALID_BREAKPOINT) threads = lldbutil.continue_to_breakpoint (self.process, break_2_in_main) self.assertTrue (len(threads) == 1, "Successfully ran to call site of second caller_trivial_1 call.") self.thread = threads[0] step_sequence = [["// In caller_trivial_1.", "into"], ["// In caller_trivial_2.", "into"], ["// In inline_trivial_1.", "into"]] self.run_step_sequence(step_sequence) # Then call some trivial function, and make sure we end up back where we were in the inlined call stack: frame = self.thread.GetFrameAtIndex(0) before_line_entry = frame.GetLineEntry() value = frame.EvaluateExpression ("function_to_call()") after_line_entry = frame.GetLineEntry() self.assertTrue (before_line_entry.GetLine() == after_line_entry.GetLine(), "Line entry before and after function calls are the same.") # Now make sure stepping OVER in the middle of the stack works, and then check finish from the inlined frame: step_sequence = [["// At increment in inline_trivial_1.", "over"], ["// At increment in caller_trivial_2.", "out"]] self.run_step_sequence(step_sequence) # Now run to the place in main just before the first call to caller_ref_1: break_3_in_main = target.BreakpointCreateBySourceRegex ('// At first call of caller_ref_1 in main.', self.main_source_spec) self.assertTrue(break_3_in_main, VALID_BREAKPOINT) threads = lldbutil.continue_to_breakpoint (self.process, break_3_in_main) self.assertTrue (len(threads) == 1, "Successfully ran to call site of first caller_ref_1 call.") self.thread = threads[0] step_sequence = [["// In caller_ref_1.", "into"], ["// In caller_ref_2.", "into"], ["// In inline_ref_1.", "into"], ["// In inline_ref_2.", "into"], ["// In called_by_inline_ref.", "into"], ["// In inline_ref_2.", "out"], ["// In inline_ref_1.", "out"], ["// At increment in inline_ref_1.", "over"], ["// In caller_ref_2.", "out"], ["// At increment in caller_ref_2.", "over"]] self.run_step_sequence (step_sequence)
def do_get_dynamic_vals(self): """Make sure we get dynamic values correctly both for compiled in classes and dynamic ones""" exe = os.path.join(os.getcwd(), "a.out") # Create a target from the debugger. target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) # Set up our breakpoints: handle_SourceBase_bkpt = target.BreakpointCreateByLocation( self.source_name, self.handle_SourceBase) self.assertTrue( handle_SourceBase_bkpt and handle_SourceBase_bkpt.GetNumLocations() == 1, VALID_BREAKPOINT) main_before_setProperty_bkpt = target.BreakpointCreateByLocation( self.source_name, self.main_before_setProperty_line) self.assertTrue( main_before_setProperty_bkpt and main_before_setProperty_bkpt.GetNumLocations() == 1, VALID_BREAKPOINT) # Now launch the process, and do not stop at the entry point. process = target.LaunchSimple(None, None, self.get_process_working_directory()) self.assertTrue(process.GetState() == lldb.eStateStopped, PROCESS_STOPPED) threads = lldbutil.get_threads_stopped_at_breakpoint( process, main_before_setProperty_bkpt) self.assertTrue(len(threads) == 1) thread = threads[0] # # At this point, myObserver has a Source pointer that is actually a KVO swizzled SourceDerived # make sure we can get that properly: frame = thread.GetFrameAtIndex(0) myObserver = frame.FindVariable('myObserver', lldb.eDynamicCanRunTarget) self.assertTrue(myObserver) myObserver_source = myObserver.GetChildMemberWithName( '_source', lldb.eDynamicCanRunTarget) self.examine_SourceDerived_ptr(myObserver_source) # # Make sure a static value can be correctly turned into a dynamic value. frame = thread.GetFrameAtIndex(0) myObserver_static = frame.FindVariable('myObserver', lldb.eNoDynamicValues) self.assertTrue(myObserver_static) myObserver = myObserver_static.GetDynamicValue( lldb.eDynamicCanRunTarget) myObserver_source = myObserver.GetChildMemberWithName( '_source', lldb.eDynamicCanRunTarget) self.examine_SourceDerived_ptr(myObserver_source) # The "frame var" code uses another path to get into children, so let's # make sure that works as well: result = lldb.SBCommandReturnObject() self.expect('frame var -d run-target myObserver->_source', 'frame var finds its way into a child member', patterns=['\(SourceDerived \*\)']) # check that our ObjC GetISA() does a good job at hiding KVO swizzled classes self.expect('frame var -d run-target myObserver->_source -T', 'the KVO-ed class is hidden', substrs=['SourceDerived']) self.expect('frame var -d run-target myObserver->_source -T', 'the KVO-ed class is hidden', matching=False, substrs=['NSKVONotify']) # This test is not entirely related to the main thrust of this test case, but since we're here, # try stepping into setProperty, and make sure we get into the version in Source: thread.StepInto() threads = lldbutil.get_stopped_threads(process, lldb.eStopReasonPlanComplete) self.assertTrue(len(threads) == 1) line_entry = threads[0].GetFrameAtIndex(0).GetLineEntry() self.assertTrue(line_entry.GetLine() == self.set_property_line) self.assertTrue( line_entry.GetFileSpec().GetFilename() == self.source_name) # Okay, back to the main business. Continue to the handle_SourceBase and make sure we get the correct dynamic value. threads = lldbutil.continue_to_breakpoint(process, handle_SourceBase_bkpt) self.assertTrue(len(threads) == 1) thread = threads[0] frame = thread.GetFrameAtIndex(0) # Get "object" using FindVariable: noDynamic = lldb.eNoDynamicValues useDynamic = lldb.eDynamicCanRunTarget object_static = frame.FindVariable('object', noDynamic) object_dynamic = frame.FindVariable('object', useDynamic) # Delete this object to make sure that this doesn't cause havoc with the dynamic object that depends on it. del (object_static) self.examine_SourceDerived_ptr(object_dynamic) # Get "this" using FindValue, make sure that works too: object_static = frame.FindValue('object', lldb.eValueTypeVariableArgument, noDynamic) object_dynamic = frame.FindValue('object', lldb.eValueTypeVariableArgument, useDynamic) del (object_static) self.examine_SourceDerived_ptr(object_dynamic) # Get "this" using the EvaluateExpression: object_static = frame.EvaluateExpression('object', noDynamic) object_dynamic = frame.EvaluateExpression('object', useDynamic) del (object_static) self.examine_SourceDerived_ptr(object_dynamic) # Continue again to the handle_SourceBase and make sure we get the correct dynamic value. # This one looks exactly the same, but in fact this is an "un-KVO'ed" version of SourceBase, so # its isa pointer points to SourceBase not NSKVOSourceBase or whatever... threads = lldbutil.continue_to_breakpoint(process, handle_SourceBase_bkpt) self.assertTrue(len(threads) == 1) thread = threads[0] frame = thread.GetFrameAtIndex(0) # Get "object" using FindVariable: object_static = frame.FindVariable('object', noDynamic) object_dynamic = frame.FindVariable('object', useDynamic) # Delete this object to make sure that this doesn't cause havoc with the dynamic object that depends on it. del (object_static) self.examine_SourceDerived_ptr(object_dynamic)