jingham created this revision. Herald added subscribers: lldb-commits, JDevlieghere, abidh. Herald added a project: LLDB.
This test was timing out on the bots occasionally, so I was poking around at it. I didn't see any obvious reason why it would stall, but it had a slightly odd way of rendezvousing the two test threads, and it also finished by running the inferior to completion, even though that wasn't relevant to the test at hand. So I took the opportunity to modernize the test, and clean up these aspects of it. In order to do that I had to make run_to_source_breakpoint accept the case where the breakpoint it was setting had more than one thread hit the created breakpoint. So this diff also has the modifications to pass an "only_one_thread" parameter if you want to allow more than one thread stopping at the candidate breakpoint. The function still returns only one thread, since the vast majority of uses will require only one thread, and it's easy to find the threads stopped at a breakpoint if you need that. Repository: rLLDB LLDB https://reviews.llvm.org/D69453 Files: lldb/packages/Python/lldbsuite/test/functionalities/thread/step_out/TestThreadStepOut.py lldb/packages/Python/lldbsuite/test/lldbutil.py
Index: lldb/packages/Python/lldbsuite/test/lldbutil.py =================================================================== --- lldb/packages/Python/lldbsuite/test/lldbutil.py +++ 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.assertTrue(len(threads) == 1, "Expected 1 thread to stop at breakpoint, %d did."%(len(threads))) + else: + test.assertTrue(len(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): Index: lldb/packages/Python/lldbsuite/test/functionalities/thread/step_out/TestThreadStepOut.py =================================================================== --- lldb/packages/Python/lldbsuite/test/functionalities/thread/step_out/TestThreadStepOut.py +++ lldb/packages/Python/lldbsuite/test/functionalities/thread/step_out/TestThreadStepOut.py @@ -68,7 +68,10 @@ # 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) + self.main_file = lldb.SBFileSpec('main.cpp') + 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 +132,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, self.main_file, 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)
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits