diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/thread/step_out/TestThreadStepOut.py b/lldb/packages/Python/lldbsuite/test/functionalities/thread/step_out/TestThreadStepOut.py --- a/lldb/packages/Python/lldbsuite/test/functionalities/thread/step_out/TestThreadStepOut.py +++ b/lldb/packages/Python/lldbsuite/test/functionalities/thread/step_out/TestThreadStepOut.py @@ -68,7 +68,9 @@ # Call super's setUp(). TestBase.setUp(self) # Find the line number for our breakpoint. - self.breakpoint = line_number('main.cpp', '// Set breakpoint here') + self.bkpt_string = '// Set breakpoint here' + self.breakpoint = line_number('main.cpp', self.bkpt_string) + if "gcc" in self.getCompiler() or self.isIntelCompiler(): self.step_out_destination = line_number( 'main.cpp', '// Expect to stop here after step-out (icc and gcc)') @@ -129,56 +131,27 @@ def step_out_test(self, step_out_func): """Test single thread step out of a function.""" - exe = self.getBuildArtifact("a.out") - self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) - - # This should create a breakpoint in the main thread. - lldbutil.run_break_set_by_file_and_line( - self, "main.cpp", self.breakpoint, num_expected_locations=1) - - # The breakpoint list should show 1 location. - self.expect( - "breakpoint list -f", - "Breakpoint location shown correctly", - substrs=[ - "1: file = 'main.cpp', line = %d, exact_match = 0, locations = 1" % - self.breakpoint]) + (self.inferior_target, self.inferior_process, thread, bkpt) = lldbutil.run_to_source_breakpoint( + self, self.bkpt_string, lldb.SBFileSpec('main.cpp'), only_one_thread = False) - # Run the program. - self.runCmd("run", RUN_SUCCEEDED) - - # Get the target process - self.inferior_target = self.dbg.GetSelectedTarget() - self.inferior_process = self.inferior_target.GetProcess() - - # Get the number of threads, ensure we see all three. - num_threads = self.inferior_process.GetNumThreads() - self.assertEqual( - num_threads, - 3, - 'Number of expected threads and actual threads do not match.') + # We hit the breakpoint on at least one thread. If we hit it on both threads + # simultaneously, we can try the step out. Otherwise, suspend the thread + # that hit the breakpoint, and continue till the second thread hits + # the breakpoint: (breakpoint_threads, other_threads) = ([], []) lldbutil.sort_stopped_threads(self.inferior_process, breakpoint_threads=breakpoint_threads, other_threads=other_threads) - - while len(breakpoint_threads) < 2: - self.runCmd("thread continue %s" % - " ".join([str(x.GetIndexID()) for x in other_threads])) - lldbutil.sort_stopped_threads( - self.inferior_process, - breakpoint_threads=breakpoint_threads, - other_threads=other_threads) + if len(breakpoint_threads) == 1: + success = thread.Suspend() + self.assertTrue(success, "Couldn't suspend a thread") + bkpt_threads = lldbutil.continue_to_breakpoint(bkpt) + self.assertEqual(len(bkpt_threads), 1, "Second thread stopped") + success = thread.Resume() + self.assertTrue(success, "Couldn't resume a thread") self.step_out_thread = breakpoint_threads[0] # Step out of thread stopped at breakpoint step_out_func() - - # Run to completion - self.runCmd("continue") - - # At this point, the inferior process should have exited. - self.assertTrue(self.inferior_process.GetState() == - lldb.eStateExited, PROCESS_EXITED) diff --git a/lldb/packages/Python/lldbsuite/test/lldbutil.py b/lldb/packages/Python/lldbsuite/test/lldbutil.py --- a/lldb/packages/Python/lldbsuite/test/lldbutil.py +++ b/lldb/packages/Python/lldbsuite/test/lldbutil.py @@ -760,7 +760,7 @@ test.assertTrue(target, "Target: %s is not valid."%(exe_name)) return target -def run_to_breakpoint_do_run(test, target, bkpt, launch_info = None): +def run_to_breakpoint_do_run(test, target, bkpt, launch_info = None, only_one_thread = True): # Launch the process, and do not stop at the entry point. if not launch_info: @@ -778,14 +778,20 @@ threads = get_threads_stopped_at_breakpoint( process, bkpt) - test.assertTrue(len(threads) == 1, "Expected 1 thread to stop at breakpoint, %d did."%(len(threads))) + num_threads = len(threads) + if only_one_thread: + test.assertEqual(num_threads, 1, "Expected 1 thread to stop at breakpoint, %d did."%(num_threads)) + else: + test.assertGreater(num_threads, 0, "No threads stopped at breakpoint") + thread = threads[0] return (target, process, thread, bkpt) def run_to_name_breakpoint (test, bkpt_name, launch_info = None, exe_name = "a.out", bkpt_module = None, - in_cwd = True): + in_cwd = True, + only_one_thread = True): """Start up a target, using exe_name as the executable, and run it to a breakpoint set by name on bkpt_name restricted to bkpt_module. @@ -807,6 +813,11 @@ If successful it returns a tuple with the target process and thread that hit the breakpoint, and the breakpoint that we set for you. + + If only_one_thread is true, we require that there be only one + thread stopped at the breakpoint. Otherwise we only require one + or more threads stop there. If there are more than one, we return + the first thread that stopped. """ target = run_to_breakpoint_make_target(test, exe_name, in_cwd) @@ -816,12 +827,13 @@ test.assertTrue(breakpoint.GetNumLocations() > 0, "No locations found for name breakpoint: '%s'."%(bkpt_name)) - return run_to_breakpoint_do_run(test, target, breakpoint, launch_info) + return run_to_breakpoint_do_run(test, target, breakpoint, launch_info, only_one_thread) def run_to_source_breakpoint(test, bkpt_pattern, source_spec, launch_info = None, exe_name = "a.out", bkpt_module = None, - in_cwd = True): + in_cwd = True, + only_one_thread = True): """Start up a target, using exe_name as the executable, and run it to a breakpoint set by source regex bkpt_pattern. @@ -835,12 +847,13 @@ test.assertTrue(breakpoint.GetNumLocations() > 0, 'No locations found for source breakpoint: "%s", file: "%s", dir: "%s"' %(bkpt_pattern, source_spec.GetFilename(), source_spec.GetDirectory())) - return run_to_breakpoint_do_run(test, target, breakpoint, launch_info) + return run_to_breakpoint_do_run(test, target, breakpoint, launch_info, only_one_thread) def run_to_line_breakpoint(test, source_spec, line_number, column = 0, launch_info = None, exe_name = "a.out", bkpt_module = None, - in_cwd = True): + in_cwd = True, + only_one_thread = True): """Start up a target, using exe_name as the executable, and run it to a breakpoint set by (source_spec, line_number(, column)). @@ -855,7 +868,7 @@ 'No locations found for line breakpoint: "%s:%d(:%d)", dir: "%s"' %(source_spec.GetFilename(), line_number, column, source_spec.GetDirectory())) - return run_to_breakpoint_do_run(test, target, breakpoint, launch_info) + return run_to_breakpoint_do_run(test, target, breakpoint, launch_info, only_one_thread) def continue_to_breakpoint(process, bkpt):