1""" 2Test number of threads. 3""" 4 5 6 7import lldb 8from lldbsuite.test.decorators import * 9from lldbsuite.test.lldbtest import * 10import lldbsuite.test.lldbutil as lldbutil 11 12 13class NumberOfThreadsTestCase(TestBase): 14 15 mydir = TestBase.compute_mydir(__file__) 16 NO_DEBUG_INFO_TESTCASE = True 17 18 def setUp(self): 19 # Call super's setUp(). 20 TestBase.setUp(self) 21 # Find the line numbers for our break points. 22 self.thread3_notify_all_line = line_number('main.cpp', '// Set thread3 break point on notify_all at this line.') 23 self.thread3_before_lock_line = line_number('main.cpp', '// thread3-before-lock') 24 25 def test_number_of_threads(self): 26 """Test number of threads.""" 27 self.build() 28 exe = self.getBuildArtifact("a.out") 29 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) 30 31 # This should create a breakpoint with 1 location. 32 lldbutil.run_break_set_by_file_and_line( 33 self, "main.cpp", self.thread3_notify_all_line, num_expected_locations=1) 34 35 # The breakpoint list should show 1 location. 36 self.expect( 37 "breakpoint list -f", 38 "Breakpoint location shown correctly", 39 substrs=[ 40 "1: file = 'main.cpp', line = %d, exact_match = 0, locations = 1" % 41 self.thread3_notify_all_line]) 42 43 # Run the program. 44 self.runCmd("run", RUN_SUCCEEDED) 45 46 # Stopped once. 47 self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, 48 substrs=["stop reason = breakpoint 1."]) 49 50 # Get the target process 51 target = self.dbg.GetSelectedTarget() 52 process = target.GetProcess() 53 54 # Get the number of threads 55 num_threads = process.GetNumThreads() 56 57 # Using std::thread may involve extra threads, so we assert that there are 58 # at least 4 rather than exactly 4. 59 self.assertTrue( 60 num_threads >= 13, 61 'Number of expected threads and actual threads do not match.') 62 63 @skipIfDarwin # rdar://33462362 64 @skipIfWindows # This is flakey on Windows: llvm.org/pr37658, llvm.org/pr38373 65 @expectedFailureNetBSD 66 def test_unique_stacks(self): 67 """Test backtrace unique with multiple threads executing the same stack.""" 68 self.build() 69 exe = self.getBuildArtifact("a.out") 70 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) 71 72 # Set a break point on the thread3 notify all (should get hit on threads 4-13). 73 lldbutil.run_break_set_by_file_and_line( 74 self, "main.cpp", self.thread3_before_lock_line, num_expected_locations=1) 75 76 # Run the program. 77 self.runCmd("run", RUN_SUCCEEDED) 78 79 # Stopped once. 80 self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, 81 substrs=["stop reason = breakpoint 1."]) 82 83 process = self.process() 84 85 # Get the number of threads 86 num_threads = process.GetNumThreads() 87 88 # Using std::thread may involve extra threads, so we assert that there are 89 # at least 10 thread3's rather than exactly 10. 90 self.assertTrue( 91 num_threads >= 10, 92 'Number of expected threads and actual threads do not match.') 93 94 # Attempt to walk each of the thread's executing the thread3 function to 95 # the same breakpoint. 96 def is_thread3(thread): 97 for frame in thread: 98 if frame.GetFunctionName() is None: 99 continue 100 if "thread3" in frame.GetFunctionName(): return True 101 return False 102 103 expect_threads = "" 104 for i in range(num_threads): 105 thread = process.GetThreadAtIndex(i) 106 self.assertTrue(thread.IsValid()) 107 if not is_thread3(thread): 108 continue 109 110 # If we aren't stopped out the thread breakpoint try to resume. 111 if thread.GetStopReason() != lldb.eStopReasonBreakpoint: 112 self.runCmd("thread continue %d"%(i+1)) 113 self.assertEqual(thread.GetStopReason(), lldb.eStopReasonBreakpoint) 114 115 expect_threads += " #%d"%(i+1) 116 117 # Construct our expected back trace string 118 expect_string = "10 thread(s)%s" % (expect_threads) 119 120 # Now that we are stopped, we should have 10 threads waiting in the 121 # thread3 function. All of these threads should show as one stack. 122 self.expect("thread backtrace unique", 123 "Backtrace with unique stack shown correctly", 124 substrs=[expect_string, 125 "main.cpp:%d"%self.thread3_before_lock_line]) 126