def printThreadsStoppedByBreakpoint(self, process): stopped_threads = \ lldbutil.get_stopped_threads(process, lldb.eStopReasonBreakpoint) for thread in stopped_threads: break_id = thread.GetStopReasonDataAtIndex(0) print('Thread ' + str(thread.GetThreadID()) + \ ' stopped at breakpoint ' + str(break_id))
def do_step(self, step_type, destination_line_entry, test_stack_depth): expected_stack_depth = self.thread.GetNumFrames() if step_type == "into": expected_stack_depth += 1 self.thread.StepInto() elif step_type == "out": expected_stack_depth -= 1 self.thread.StepOut() elif step_type == "over": self.thread.StepOver() else: self.fail("Unrecognized step type: " + step_type) threads = lldbutil.get_stopped_threads(self.process, lldb.eStopReasonPlanComplete) if len(threads) != 1: destination_description = lldb.SBStream() destination_line_entry.GetDescription(destination_description) self.fail( "Failed to stop due to step " + step_type + " operation stepping to: " + destination_description.GetData() ) self.thread = threads[0] stop_line_entry = self.thread.GetFrameAtIndex(0).GetLineEntry() self.assertTrue(stop_line_entry.IsValid(), "Stop line entry was not valid.") # Don't use the line entry equal operator because we don't care about the column number. stop_at_right_place = ( stop_line_entry.GetFileSpec() == destination_line_entry.GetFileSpec() and stop_line_entry.GetLine() == destination_line_entry.GetLine() ) if stop_at_right_place == False: destination_description = lldb.SBStream() destination_line_entry.GetDescription(destination_description) actual_description = lldb.SBStream() stop_line_entry.GetDescription(actual_description) self.fail( "Step " + step_type + " stopped at wrong place: expected: " + destination_description.GetData() + " got: " + actual_description.GetData() + "." ) real_stack_depth = self.thread.GetNumFrames() if test_stack_depth and real_stack_depth != expected_stack_depth: destination_description = lldb.SBStream() destination_line_entry.GetDescription(destination_description) self.fail( "Step %s to %s got wrong number of frames, should be: %d was: %d." % (step_type, destination_description.GetData(), expected_stack_depth, real_stack_depth) )
def test_watchlocation_using_watchpoint_set(self): """Test watching a location with 'watchpoint set expression -w write -s size' option.""" self.build() self.setTearDownCleanup() exe = os.path.join(os.getcwd(), 'a.out') self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) # Add a breakpoint to set a watchpoint when stopped on the breakpoint. lldbutil.run_break_set_by_file_and_line (self, None, self.line, num_expected_locations=1) # Run the program. self.runCmd("run", RUN_SUCCEEDED) # We should be stopped again due to the breakpoint. # The stop reason of the thread should be breakpoint. self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, substrs = ['stopped', 'stop reason = breakpoint']) # Now let's set a write-type watchpoint pointed to by 'g_char_ptr' and # with offset as 7. # The main.cpp, by design, misbehaves by not following the agreed upon # protocol of only accessing the allowable index range of [0, 6]. self.expect("watchpoint set expression -w write -s 1 -- g_char_ptr + 7", WATCHPOINT_CREATED, substrs = ['Watchpoint created', 'size = 1', 'type = w']) self.runCmd("expr unsigned val = g_char_ptr[7]; val") self.expect(self.res.GetOutput().splitlines()[0], exe=False, endstr = ' = 0') # Use the '-v' option to do verbose listing of the watchpoint. # The hit count should be 0 initially. self.expect("watchpoint list -v", substrs = ['hit_count = 0']) self.runCmd("process continue") # We should be stopped again due to the watchpoint (write type), but # only once. The stop reason of the thread should be watchpoint. self.expect("thread list", STOPPED_DUE_TO_WATCHPOINT, substrs = ['stopped', 'stop reason = watchpoint', self.violating_func]) # Switch to the thread stopped due to watchpoint and issue some commands. self.switch_to_thread_with_stop_reason(lldb.eStopReasonWatchpoint) self.runCmd("thread backtrace") self.runCmd("expr unsigned val = g_char_ptr[7]; val") self.expect(self.res.GetOutput().splitlines()[0], exe=False, endstr = ' = 99') # Use the '-v' option to do verbose listing of the watchpoint. # The hit count should now be the same as the number of threads that # stopped on a watchpoint. threads = lldbutil.get_stopped_threads(self.process(), lldb.eStopReasonWatchpoint) self.expect("watchpoint list -v", substrs = ['hit_count = %d' % len(threads)]) self.runCmd("thread backtrace all")
def test(self): if self.getArchitecture() == 'x86_64': source = os.path.join (os.getcwd(), "main.cpp") o_file = os.path.join (os.getcwd(), "main.o") execute_command ("'%s' -g -O0 -arch i386 -arch x86_64 '%s' -c -o '%s'" % (os.environ["CC"], source, o_file)) execute_command ("'%s' -g -O0 -arch i386 -arch x86_64 '%s'" % (os.environ["CC"], o_file)) if self.debug_info != "dsym": dsym_path = os.path.join (os.getcwd(), "a.out.dSYM") execute_command ("rm -rf '%s'" % (dsym_path)) else: self.build() exe = os.path.join (os.getcwd(), "a.out") # Create the target target = self.dbg.CreateTarget(exe) # Create any breakpoints we need breakpoint = target.BreakpointCreateBySourceRegex ('Set breakpoint 1 here', lldb.SBFileSpec ("main.cpp", False)) self.assertTrue(breakpoint, VALID_BREAKPOINT) # Launch the process process = target.LaunchSimple (None, None, self.get_process_working_directory()) self.assertTrue(process, PROCESS_IS_VALID) for i in range(6): # The stop reason of the thread should be breakpoint. self.assertTrue(process.GetState() == lldb.eStateStopped, STOPPED_DUE_TO_BREAKPOINT) threads = lldbutil.get_threads_stopped_at_breakpoint(process, breakpoint) self.assertTrue(len(threads) == 1) # We had a deadlock tearing down the TypeSystemMap on exec, but only if some # expression had been evaluated. So make sure we do that here so the teardown # is not trivial. thread = threads[0] value = thread.frames[0].EvaluateExpression("1 + 2") self.assertTrue(value.IsValid(), "Expression evaluated successfully") int_value = value.GetValueAsSigned() self.assertTrue(int_value == 3, "Expression got the right result.") # Run and we should stop due to exec process.Continue() self.assertTrue(process.GetState() == lldb.eStateStopped, "Process should be stopped at __dyld_start") threads = lldbutil.get_stopped_threads(process, lldb.eStopReasonExec) self.assertTrue(len(threads) == 1, "We got a thread stopped for exec.") # Run and we should stop at breakpoint in main after exec process.Continue() threads = lldbutil.get_threads_stopped_at_breakpoint(process, breakpoint) self.assertTrue(len(threads) == 1, "Stopped at breakpoint in exec'ed process.")
def test(self): if self.getArchitecture() == 'x86_64': source = os.path.join (os.getcwd(), "main.cpp") o_file = os.path.join (os.getcwd(), "main.o") execute_command ("'%s' -g -O0 -arch i386 -arch x86_64 '%s' -c -o '%s'" % (os.environ["CC"], source, o_file)) execute_command ("'%s' -g -O0 -arch i386 -arch x86_64 '%s'" % (os.environ["CC"], o_file)) if self.debug_info != "dsym": dsym_path = os.path.join (os.getcwd(), "a.out.dSYM") execute_command ("rm -rf '%s'" % (dsym_path)) else: self.build() exe = os.path.join (os.getcwd(), "a.out") # Create the target target = self.dbg.CreateTarget(exe) # Create any breakpoints we need breakpoint = target.BreakpointCreateBySourceRegex ('Set breakpoint 1 here', lldb.SBFileSpec ("main.cpp", False)) self.assertTrue(breakpoint, VALID_BREAKPOINT) # Launch the process process = target.LaunchSimple (None, None, self.get_process_working_directory()) self.assertTrue(process, PROCESS_IS_VALID) for i in range(6): # The stop reason of the thread should be breakpoint. self.assertTrue(process.GetState() == lldb.eStateStopped, STOPPED_DUE_TO_BREAKPOINT) threads = lldbutil.get_threads_stopped_at_breakpoint(process, breakpoint) self.assertTrue(len(threads) == 1) # We had a deadlock tearing down the TypeSystemMap on exec, but only if some # expression had been evaluated. So make sure we do that here so the teardown # is not trivial. thread = threads[0] value = thread.frames[0].EvaluateExpression("1 + 2") self.assertTrue(value.IsValid(), "Expression evaluated successfully") int_value = value.GetValueAsSigned() self.assertTrue(int_value == 3, "Expression got the right result.") # Run and we should stop due to exec process.Continue() self.assertTrue(process.GetState() == lldb.eStateStopped, "Process should be stopped at __dyld_start") threads = lldbutil.get_stopped_threads(process, lldb.eStopReasonExec) self.assertTrue(len(threads) == 1, "We got a thread stopped for exec.") # Run and we should stop at breakpoint in main after exec process.Continue() threads = lldbutil.get_threads_stopped_at_breakpoint(process, breakpoint) self.assertTrue(len(threads) == 1, "Stopped at breakpoint in exec'ed process.")
def test_correct_thread_plan_state_before_exec(self): ''' In this test we make sure that the Thread* cache in the ThreadPlans is cleared correctly when performing exec ''' self.build() exe = self.getBuildArtifact("a.out") target = self.dbg.CreateTarget(exe) (target, process, thread, breakpoint1) = lldbutil.run_to_source_breakpoint( self, 'Set breakpoint 1 here', lldb.SBFileSpec('main.cpp', False)) # The stop reason of the thread should be breakpoint. self.assertState(process.GetState(), lldb.eStateStopped, STOPPED_DUE_TO_BREAKPOINT) threads = lldbutil.get_threads_stopped_at_breakpoint(process, breakpoint1) self.assertEqual(len(threads), 1) # We perform an instruction step, which effectively sets the cache of the base # thread plan, which should be cleared when a new thread list appears. # # Continuing after this instruction step will trigger a call to # ThreadPlan::ShouldReportRun, which sets the ThreadPlan's Thread cache to # the old Thread* value. In Process::UpdateThreadList we are clearing this # cache in preparation for the new ThreadList. # # Not doing this stepping will cause LLDB to first execute a private single step # past the current breakpoint, which eventually avoids the call to ShouldReportRun, # thus not setting the cache to its invalid value. thread.StepInstruction(False) # Run and we should stop due to exec breakpoint2 = target.BreakpointCreateBySourceRegex( 'Set breakpoint 2 here', lldb.SBFileSpec("secondprog.cpp", False)) process.Continue() self.assertNotEqual(process.GetState(), lldb.eStateExited, "Process should not have exited!") self.assertState(process.GetState(), lldb.eStateStopped, "Process should be stopped at __dyld_start") threads = lldbutil.get_stopped_threads( process, lldb.eStopReasonExec) self.assertEqual( len(threads), 1, "We got a thread stopped for exec.") # Run and we should stop at breakpoint in main after exec process.Continue() threads = lldbutil.get_threads_stopped_at_breakpoint( process, breakpoint2) self.assertEqual(len(threads), 1, "Stopped at breakpoint in exec'ed process.")
def do_step(self, step_type, destination_line_entry, test_stack_depth): expected_stack_depth = self.thread.GetNumFrames() if step_type == "into": expected_stack_depth += 1 self.thread.StepInto() elif step_type == "out": expected_stack_depth -= 1 self.thread.StepOut() elif step_type == "over": self.thread.StepOver() else: self.fail("Unrecognized step type: " + step_type) threads = lldbutil.get_stopped_threads(self.process, lldb.eStopReasonPlanComplete) if len(threads) != 1: destination_description = lldb.SBStream() destination_line_entry.GetDescription(destination_description) self.fail("Failed to stop due to step " + step_type + " operation stepping to: " + destination_description.GetData()) self.thread = threads[0] stop_line_entry = self.thread.GetFrameAtIndex(0).GetLineEntry() self.assertTrue(stop_line_entry.IsValid(), "Stop line entry was not valid.") # Don't use the line entry equal operator because we don't care about # the column number. stop_at_right_place = (stop_line_entry.GetFileSpec() == destination_line_entry.GetFileSpec() and stop_line_entry.GetLine() == destination_line_entry.GetLine()) if not stop_at_right_place: destination_description = lldb.SBStream() destination_line_entry.GetDescription(destination_description) actual_description = lldb.SBStream() stop_line_entry.GetDescription(actual_description) self.fail("Step " + step_type + " stopped at wrong place: expected: " + destination_description.GetData() + " got: " + actual_description.GetData() + ".") real_stack_depth = self.thread.GetNumFrames() if test_stack_depth and real_stack_depth != expected_stack_depth: destination_description = lldb.SBStream() destination_line_entry.GetDescription(destination_description) self.fail( "Step %s to %s got wrong number of frames, should be: %d was: %d." % (step_type, destination_description.GetData(), expected_stack_depth, real_stack_depth))
def _test(self): self.build() # Extracts path of the interpreter. exe = self.getBuildArtifact("a.out") spec = lldb.SBModuleSpec() spec.SetFileSpec(lldb.SBFileSpec(exe)) interp_section = lldb.SBModule(spec).FindSection(".interp") if not interp_section: return section_data = interp_section.GetSectionData() error = lldb.SBError() dyld_path = section_data.GetString(error, 0) if error.Fail(): return target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) # Set a breakpoint in the main function that will get hit after the # program exec's via the dynamic loader. The breakpoint will only get # hit if we can successfully read the shared library lists in the # DynamicLoaderPOSIXDYLD.cpp when we exec into the dynamic loader. breakpoint_main = target.BreakpointCreateBySourceRegex( "// Break here", lldb.SBFileSpec("main.cpp")) # Setup our launch info to supply the dynamic loader path to the # program so it gets two args: # - path to a.out # - path to dynamic loader launch_info = lldb.SBLaunchInfo([dyld_path]) error = lldb.SBError() process = target.Launch(launch_info, error) self.assertSuccess(error) threads = lldbutil.get_stopped_threads(process, lldb.eStopReasonExec) self.assertEqual(len(threads), 1, "We got a thread stopped for exec.") process.Continue() # Stopped on main here. self.assertState(process.GetState(), lldb.eStateStopped) thread = process.GetSelectedThread() self.assertIn("main", thread.GetFrameAtIndex(0).GetDisplayFunctionName())
def do_test(self, skip_exec): self.build() exe = self.getBuildArtifact("a.out") secondprog = self.getBuildArtifact("secondprog") # Create the target target = self.dbg.CreateTarget(exe) # Create any breakpoints we need breakpoint1 = target.BreakpointCreateBySourceRegex( 'Set breakpoint 1 here', lldb.SBFileSpec("main.cpp", False)) self.assertTrue(breakpoint1, VALID_BREAKPOINT) breakpoint2 = target.BreakpointCreateBySourceRegex( 'Set breakpoint 2 here', lldb.SBFileSpec("secondprog.cpp", False)) self.assertTrue(breakpoint2, VALID_BREAKPOINT) # Launch the process process = target.LaunchSimple(None, None, self.get_process_working_directory()) self.assertTrue(process, PROCESS_IS_VALID) if self.TraceOn(): self.runCmd("settings show target.process.stop-on-exec", check=False) if skip_exec: self.dbg.HandleCommand( "settings set target.process.stop-on-exec false") def cleanup(): self.runCmd("settings set target.process.stop-on-exec false", check=False) # Execute the cleanup function during test case tear down. self.addTearDownHook(cleanup) # The stop reason of the thread should be breakpoint. self.assertTrue(process.GetState() == lldb.eStateStopped, STOPPED_DUE_TO_BREAKPOINT) threads = lldbutil.get_threads_stopped_at_breakpoint( process, breakpoint1) self.assertTrue(len(threads) == 1) # We had a deadlock tearing down the TypeSystemMap on exec, but only if some # expression had been evaluated. So make sure we do that here so the teardown # is not trivial. thread = threads[0] value = thread.frames[0].EvaluateExpression("1 + 2") self.assertTrue(value.IsValid(), "Expression evaluated successfully") int_value = value.GetValueAsSigned() self.assertTrue(int_value == 3, "Expression got the right result.") # Run and we should stop due to exec process.Continue() if not skip_exec: self.assertFalse(process.GetState() == lldb.eStateExited, "Process should not have exited!") self.assertTrue(process.GetState() == lldb.eStateStopped, "Process should be stopped at __dyld_start") threads = lldbutil.get_stopped_threads(process, lldb.eStopReasonExec) self.assertTrue( len(threads) == 1, "We got a thread stopped for exec.") # Run and we should stop at breakpoint in main after exec process.Continue() threads = lldbutil.get_threads_stopped_at_breakpoint( process, breakpoint2) if self.TraceOn(): for t in process.threads: print(t) if t.GetStopReason() != lldb.eStopReasonBreakpoint: self.runCmd("bt") self.assertTrue( len(threads) == 1, "Stopped at breakpoint in exec'ed process.")
def test_and_python_api(self): """Test stepping over vrs. hitting breakpoints & subsequent stepping in various forms.""" self.build() exe = self.getBuildArtifact("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, 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, 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) options = lldb.SBExpressionOptions() options.SetIgnoreBreakpoints(False) options.SetFetchDynamicValue(False) options.SetUnwindOnError(False) frame.EvaluateExpression("b (4)", options) 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: func_name = thread.GetFrameAtIndex(0).GetFunctionName() self.assertTrue(func_name == "b", "Should be in 'b', were in %s" % (func_name)) # 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 targeting a function: break_in_b.SetEnabled(False) break_before_complex_1 = target.BreakpointCreateBySourceRegex( '// Stop here to try step in targeting 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 targeting complex.', self.main_source_spec) self.assertTrue(break_before_complex_2, VALID_BREAKPOINT) break_before_complex_3 = target.BreakpointCreateBySourceRegex( '// Stop here to step targeting 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 targeting 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 targeting b: threads = lldbutil.continue_to_breakpoint(process, break_before_complex_4) self.assertTrue(len(threads) == 1) thread = threads[0] break_before_complex_4.SetEnabled(False) thread.StepInto("NoSuchFunction") self.assertTrue(thread.GetFrameAtIndex(0).GetFunctionName() == "main")
def test_with_run_command(self): """Test that lldb command 'process signal SIGUSR1' sends a signal to the inferior process.""" self.build() exe = os.path.join(os.getcwd(), "a.out") # Create a target by the debugger. target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) # Now create a breakpoint on main.c by name 'c'. breakpoint = target.BreakpointCreateByLocation('main.c', self.line) self.assertTrue(breakpoint and breakpoint.GetNumLocations() == 1, VALID_BREAKPOINT) # Get the breakpoint location from breakpoint after we verified that, # indeed, it has one location. location = breakpoint.GetLocationAtIndex(0) self.assertTrue(location and location.IsEnabled(), VALID_BREAKPOINT_LOCATION) # Now launch the process, no arguments & do not stop at entry point. launch_info = lldb.SBLaunchInfo([exe]) launch_info.SetWorkingDirectory(self.get_process_working_directory()) process_listener = lldb.SBListener("signal_test_listener") launch_info.SetListener(process_listener) error = lldb.SBError() process = target.Launch(launch_info, error) self.assertTrue(process, PROCESS_IS_VALID) self.runCmd("process handle -n False -p True -s True SIGUSR1") thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint) self.assertTrue(thread.IsValid(), "We hit the first breakpoint.") # After resuming the process, send it a SIGUSR1 signal. self.setAsync(True) self.assertTrue(process_listener.IsValid(), "Got a good process listener") # Disable our breakpoint, we don't want to hit it anymore... breakpoint.SetEnabled(False) # Now continue: process.Continue() # If running remote test, there should be a connected event if lldb.remote_platform: self.match_state(process_listener, lldb.eStateConnected) self.match_state(process_listener, lldb.eStateRunning) # Now signal the process, and make sure it stops: process.Signal(lldbutil.get_signal_number('SIGUSR1')) self.match_state(process_listener, lldb.eStateStopped) # Now make sure the thread was stopped with a SIGUSR1: threads = lldbutil.get_stopped_threads(process, lldb.eStopReasonSignal) self.assertTrue(len(threads) == 1, "One thread stopped for a signal.") thread = threads[0] self.assertTrue(thread.GetStopReasonDataCount() >= 1, "There was data in the event.") self.assertTrue(thread.GetStopReasonDataAtIndex(0) == lldbutil.get_signal_number('SIGUSR1'), "The stop signal was SIGUSR1")
def test_and_python_api(self): """Test stepping over vrs. hitting breakpoints & subsequent stepping in various forms.""" 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) 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, 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, 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) options = lldb.SBExpressionOptions() options.SetIgnoreBreakpoints(False) options.SetFetchDynamicValue(False) options.SetUnwindOnError(False) frame.EvaluateExpression("b (4)", options) 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: func_name = thread.GetFrameAtIndex(0).GetFunctionName() self.assertTrue( func_name == "b", "Should be in 'b', were in %s" % (func_name)) # 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 targeting a function: break_in_b.SetEnabled(False) break_before_complex_1 = target.BreakpointCreateBySourceRegex( '// Stop here to try step in targeting 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 targeting complex.', self.main_source_spec) self.assertTrue(break_before_complex_2, VALID_BREAKPOINT) break_before_complex_3 = target.BreakpointCreateBySourceRegex( '// Stop here to step targeting 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 targeting 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 targeting b: threads = lldbutil.continue_to_breakpoint( process, break_before_complex_4) self.assertTrue(len(threads) == 1) thread = threads[0] break_before_complex_4.SetEnabled(False) thread.StepInto("NoSuchFunction") self.assertTrue(thread.GetFrameAtIndex(0).GetFunctionName() == "main")
def thread_plan_test(self): (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self, "Set a breakpoint here", self.main_source_file) # Now set a breakpoint in call_me and step over. We should have # two public thread plans call_me_bkpt = target.BreakpointCreateBySourceRegex( "Set another here", self.main_source_file) self.assertTrue(call_me_bkpt.GetNumLocations() > 0, "Set the breakpoint successfully") thread.StepOver() threads = lldbutil.get_threads_stopped_at_breakpoint( process, call_me_bkpt) self.assertEqual(len(threads), 1, "Hit my breakpoint while stepping over") current_id = threads[0].GetIndexID() current_tid = threads[0].GetThreadID() # Run thread plan list without the -i flag: command = "thread plan list %d" % (current_id) self.check_list_output(command, ["Stepping over line main.c"], []) # Run thread plan list with the -i flag: command = "thread plan list -i %d" % (current_id) self.check_list_output( command, ["Stepping over line main.c", "Stepping out from"]) # Run thread plan list providing TID, output should be the same: command = "thread plan list -t %d" % (current_tid) self.check_list_output(command, ["Stepping over line main.c"]) # Provide both index & tid, and make sure we only print once: command = "thread plan list -t %d %d" % (current_tid, current_id) self.check_list_output(command, ["Stepping over line main.c"]) # Try a fake TID, and make sure that fails: fake_tid = 0 for i in range(100, 10000, 100): fake_tid = current_tid + i thread = process.GetThreadByID(fake_tid) if not thread: break command = "thread plan list -t %d" % (fake_tid) self.check_list_output(command) # Now continue, and make sure we printed the completed plan: process.Continue() threads = lldbutil.get_stopped_threads(process, lldb.eStopReasonPlanComplete) self.assertEqual(len(threads), 1, "One thread completed a step") # Run thread plan list - there aren't any private plans at this point: command = "thread plan list %d" % (current_id) self.check_list_output(command, [], ["Stepping over line main.c"]) # Set another breakpoint that we can run to, to try deleting thread plans. second_step_bkpt = target.BreakpointCreateBySourceRegex( "Run here to step over again", self.main_source_file) self.assertTrue(second_step_bkpt.GetNumLocations() > 0, "Set the breakpoint successfully") final_bkpt = target.BreakpointCreateBySourceRegex( "Make sure we get here on last continue", self.main_source_file) self.assertTrue(final_bkpt.GetNumLocations() > 0, "Set the breakpoint successfully") threads = lldbutil.continue_to_breakpoint(process, second_step_bkpt) self.assertEqual(len(threads), 1, "Hit the second step breakpoint") threads[0].StepOver() threads = lldbutil.get_threads_stopped_at_breakpoint( process, call_me_bkpt) result = lldb.SBCommandReturnObject() interp = self.dbg.GetCommandInterpreter() interp.HandleCommand("thread plan discard 1", result) self.assertTrue( result.Succeeded(), "Deleted the step over plan: %s" % (result.GetOutput())) # Make sure the plan gets listed in the discarded plans: command = "thread plan list %d" % (current_id) self.check_list_output(command, [], [], ["Stepping over line main.c:"]) process.Continue() threads = lldbutil.get_threads_stopped_at_breakpoint( process, final_bkpt) self.assertEqual(len(threads), 1, "Ran to final breakpoint") threads = lldbutil.get_stopped_threads(process, lldb.eStopReasonPlanComplete) self.assertEqual(len(threads), 0, "Did NOT complete the step over plan")
def test_hello_watchlocation(self): """Test watching a location with '-s size' option.""" self.build(dictionary=self.d) self.setTearDownCleanup(dictionary=self.d) exe = self.getBuildArtifact(self.exe_name) self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) # Add a breakpoint to set a watchpoint when stopped on the breakpoint. lldbutil.run_break_set_by_file_and_line(self, None, self.line, num_expected_locations=1, loc_exact=False) # Run the program. self.runCmd("run", RUN_SUCCEEDED) # We should be stopped again due to the breakpoint. # The stop reason of the thread should be breakpoint. self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, substrs=['stopped', 'stop reason = breakpoint']) # Now let's set a write-type watchpoint pointed to by 'g_char_ptr'. self.expect("watchpoint set expression -w write -s 1 -- g_char_ptr", WATCHPOINT_CREATED, substrs=['Watchpoint created', 'size = 1', 'type = w']) # Get a hold of the watchpoint id just created, it is used later on to # match the watchpoint id which is expected to be fired. match = re.match("Watchpoint created: Watchpoint (.*):", self.res.GetOutput().splitlines()[0]) if match: expected_wp_id = int(match.group(1), 0) else: self.fail("Grokking watchpoint id faailed!") self.runCmd("expr unsigned val = *g_char_ptr; val") self.expect(self.res.GetOutput().splitlines()[0], exe=False, endstr=' = 0') self.runCmd("watchpoint set expression -w write -s 4 -- &threads[0]") # Use the '-v' option to do verbose listing of the watchpoint. # The hit count should be 0 initially. self.expect("watchpoint list -v", substrs=['hit_count = 0']) self.runCmd("process continue") # We should be stopped again due to the watchpoint (write type), but # only once. The stop reason of the thread should be watchpoint. self.expect("thread list", STOPPED_DUE_TO_WATCHPOINT, substrs=[ 'stopped', 'stop reason = watchpoint %d' % expected_wp_id ]) # Switch to the thread stopped due to watchpoint and issue some # commands. self.switch_to_thread_with_stop_reason(lldb.eStopReasonWatchpoint) self.runCmd("thread backtrace") self.expect("frame info", substrs=[self.violating_func]) # Use the '-v' option to do verbose listing of the watchpoint. # The hit count should now be the same as the number of threads that # stopped on a watchpoint. threads = lldbutil.get_stopped_threads(self.process(), lldb.eStopReasonWatchpoint) if not self.affected_by_radar_93863107(): self.expect("watchpoint list -v", substrs=['hit_count = %d' % len(threads)]) self.runCmd("thread backtrace all")
def test_with_run_command(self): """Test that lldb command 'process signal SIGUSR1' sends a signal to the inferior process.""" self.build() exe = self.getBuildArtifact("a.out") # Create a target by the debugger. target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) # Now create a breakpoint on main.c by name 'c'. breakpoint = target.BreakpointCreateByLocation('main.c', self.line) self.assertTrue(breakpoint and breakpoint.GetNumLocations() == 1, VALID_BREAKPOINT) # Get the breakpoint location from breakpoint after we verified that, # indeed, it has one location. location = breakpoint.GetLocationAtIndex(0) self.assertTrue(location and location.IsEnabled(), VALID_BREAKPOINT_LOCATION) # Now launch the process, no arguments & do not stop at entry point. launch_info = target.GetLaunchInfo() launch_info.SetWorkingDirectory(self.get_process_working_directory()) process_listener = lldb.SBListener("signal_test_listener") launch_info.SetListener(process_listener) error = lldb.SBError() process = target.Launch(launch_info, error) self.assertTrue(process, PROCESS_IS_VALID) self.runCmd("process handle -n False -p True -s True SIGUSR1") thread = lldbutil.get_stopped_thread( process, lldb.eStopReasonBreakpoint) self.assertTrue(thread.IsValid(), "We hit the first breakpoint.") # After resuming the process, send it a SIGUSR1 signal. self.setAsync(True) self.assertTrue( process_listener.IsValid(), "Got a good process listener") # Disable our breakpoint, we don't want to hit it anymore... breakpoint.SetEnabled(False) # Now continue: process.Continue() # If running remote test, there should be a connected event if lldb.remote_platform: self.match_state(process_listener, lldb.eStateConnected) self.match_state(process_listener, lldb.eStateRunning) # Now signal the process, and make sure it stops: process.Signal(lldbutil.get_signal_number('SIGUSR1')) self.match_state(process_listener, lldb.eStateStopped) # Now make sure the thread was stopped with a SIGUSR1: threads = lldbutil.get_stopped_threads(process, lldb.eStopReasonSignal) self.assertEquals(len(threads), 1, "One thread stopped for a signal.") thread = threads[0] self.assertTrue( thread.GetStopReasonDataCount() >= 1, "There was data in the event.") self.assertTrue( thread.GetStopReasonDataAtIndex(0) == lldbutil.get_signal_number('SIGUSR1'), "The stop signal was SIGUSR1")
def test_get_objc_dynamic_vals(self): """Test fetching ObjC dynamic values.""" if self.getArchitecture() == 'i386': # rdar://problem/9946499 self.skipTest("Dynamic types for ObjC V1 runtime not implemented") self.build() exe = self.getBuildArtifact("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.assertEqual(line_entry.GetLine(), self.set_property_line) self.assertEqual( 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 test_get_objc_dynamic_vals(self): """Test fetching ObjC dynamic values.""" if self.getArchitecture() == 'i386': # rdar://problem/9946499 self.skipTest("Dynamic types for ObjC V1 runtime not implemented") self.build() exe = self.getBuildArtifact("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.assertEqual(line_entry.GetLine(), self.set_property_line) self.assertEqual( 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 do_test(self, skip_exec): self.makeBuildDir() exe = self.getBuildArtifact("a.out") if self.getArchitecture() == 'x86_64': source = self.getSourcePath("main.cpp") o_file = self.getBuildArtifact("main.o") execute_command( "'%s' -g -O0 -arch i386 -arch x86_64 '%s' -c -o '%s'" % (os.environ["CC"], source, o_file)) execute_command( "'%s' -g -O0 -arch i386 -arch x86_64 '%s' -o '%s'" % (os.environ["CC"], o_file, exe)) if self.getDebugInfo() != "dsym": dsym_path = self.getBuildArtifact("a.out.dSYM") execute_command("rm -rf '%s'" % (dsym_path)) else: self.build() # Create the target target = self.dbg.CreateTarget(exe) # Create any breakpoints we need breakpoint = target.BreakpointCreateBySourceRegex( 'Set breakpoint 1 here', lldb.SBFileSpec("main.cpp", False)) self.assertTrue(breakpoint, VALID_BREAKPOINT) # Launch the process process = target.LaunchSimple( None, None, self.get_process_working_directory()) self.assertTrue(process, PROCESS_IS_VALID) if skip_exec: self.dbg.HandleCommand("settings set target.process.stop-on-exec false") def cleanup(): self.runCmd("settings set target.process.stop-on-exec false", check=False) # Execute the cleanup function during test case tear down. self.addTearDownHook(cleanup) for i in range(6): # The stop reason of the thread should be breakpoint. self.assertTrue(process.GetState() == lldb.eStateStopped, STOPPED_DUE_TO_BREAKPOINT) threads = lldbutil.get_threads_stopped_at_breakpoint( process, breakpoint) self.assertTrue(len(threads) == 1) # We had a deadlock tearing down the TypeSystemMap on exec, but only if some # expression had been evaluated. So make sure we do that here so the teardown # is not trivial. thread = threads[0] value = thread.frames[0].EvaluateExpression("1 + 2") self.assertTrue( value.IsValid(), "Expression evaluated successfully") int_value = value.GetValueAsSigned() self.assertTrue(int_value == 3, "Expression got the right result.") # Run and we should stop due to exec process.Continue() if not skip_exec: self.assertTrue(process.GetState() == lldb.eStateStopped, "Process should be stopped at __dyld_start") threads = lldbutil.get_stopped_threads( process, lldb.eStopReasonExec) self.assertTrue( len(threads) == 1, "We got a thread stopped for exec.") # Run and we should stop at breakpoint in main after exec process.Continue() threads = lldbutil.get_threads_stopped_at_breakpoint( process, breakpoint) if self.TraceOn(): for t in process.threads: print(t) if t.GetStopReason() != lldb.eStopReasonBreakpoint: self.runCmd("bt") self.assertTrue(len(threads) == 1, "Stopped at breakpoint in exec'ed process.")