예제 #1
0
    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)
예제 #2
0
    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)
예제 #3
0
    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)
예제 #4
0
    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)
예제 #5
0
    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)
예제 #6
0
    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")
예제 #7
0
    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")
예제 #9
0
    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.")
예제 #10
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)
예제 #11
0
    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)
예제 #12
0
    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)
예제 #13
0
    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"'])
예제 #14
0
    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"'
                    ])
예제 #18
0
    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',
                               '{}'])
예제 #20
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)
예제 #21
0
    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.")
예제 #22
0
    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")
예제 #23
0
    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.")
예제 #24
0
    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.")
예제 #25
0
    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")
예제 #26
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, "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'])
예제 #27
0
    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)
예제 #28
0
    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)