""" Test number of threads. """ import lldb from lldbsuite.test.decorators import * from lldbsuite.test.lldbtest import * import lldbsuite.test.lldbutil as lldbutil class NumberOfThreadsTestCase(TestBase): mydir = TestBase.compute_mydir(__file__) NO_DEBUG_INFO_TESTCASE = True def setUp(self): # Call super's setUp(). TestBase.setUp(self) # Find the line numbers for our break points. self.thread3_notify_all_line = line_number('main.cpp', '// Set thread3 break point on notify_all at this line.') self.thread3_before_lock_line = line_number('main.cpp', '// thread3-before-lock') def test_number_of_threads(self): """Test number of threads.""" self.build() exe = self.getBuildArtifact("a.out") self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) # This should create a breakpoint with 1 location. lldbutil.run_break_set_by_file_and_line( self, "main.cpp", self.thread3_notify_all_line, 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.thread3_notify_all_line]) # Run the program. self.runCmd("run", RUN_SUCCEEDED) # Stopped once. self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, substrs=["stop reason = breakpoint 1."]) # Get the target process target = self.dbg.GetSelectedTarget() process = target.GetProcess() # Get the number of threads num_threads = process.GetNumThreads() # Using std::thread may involve extra threads, so we assert that there are # at least 4 rather than exactly 4. self.assertTrue( num_threads >= 13, 'Number of expected threads and actual threads do not match.') @skipIfDarwin # rdar://33462362 @skipIfWindows # This is flakey on Windows: llvm.org/pr37658, llvm.org/pr38373 @expectedFailureNetBSD def test_unique_stacks(self): """Test backtrace unique with multiple threads executing the same stack.""" self.build() exe = self.getBuildArtifact("a.out") self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) # Set a break point on the thread3 notify all (should get hit on threads 4-13). lldbutil.run_break_set_by_file_and_line( self, "main.cpp", self.thread3_before_lock_line, num_expected_locations=1) # Run the program. self.runCmd("run", RUN_SUCCEEDED) # Stopped once. self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, substrs=["stop reason = breakpoint 1."]) process = self.process() # Get the number of threads num_threads = process.GetNumThreads() # Using std::thread may involve extra threads, so we assert that there are # at least 10 thread3's rather than exactly 10. self.assertTrue( num_threads >= 10, 'Number of expected threads and actual threads do not match.') # Attempt to walk each of the thread's executing the thread3 function to # the same breakpoint. def is_thread3(thread): for frame in thread: if "thread3" in frame.GetFunctionName(): return True return False expect_threads = "" for i in range(num_threads): thread = process.GetThreadAtIndex(i) self.assertTrue(thread.IsValid()) if not is_thread3(thread): continue # If we aren't stopped out the thread breakpoint try to resume. if thread.GetStopReason() != lldb.eStopReasonBreakpoint: self.runCmd("thread continue %d"%(i+1)) self.assertEqual(thread.GetStopReason(), lldb.eStopReasonBreakpoint) expect_threads += " #%d"%(i+1) # Construct our expected back trace string expect_string = "10 thread(s)%s" % (expect_threads) # Now that we are stopped, we should have 10 threads waiting in the # thread3 function. All of these threads should show as one stack. self.expect("thread backtrace unique", "Backtrace with unique stack shown correctly", substrs=[expect_string, "main.cpp:%d"%self.thread3_before_lock_line])