164 lines · python
1"""2Test number of threads.3"""4 5 6import lldb7from lldbsuite.test.decorators import *8from lldbsuite.test.lldbtest import *9import lldbsuite.test.lldbutil as lldbutil10 11 12class NumberOfThreadsTestCase(TestBase):13 NO_DEBUG_INFO_TESTCASE = True14 15 def setUp(self):16 # Call super's setUp().17 TestBase.setUp(self)18 # Find the line numbers for our break points.19 self.thread3_notify_all_line = line_number(20 "main.cpp", "// Set thread3 break point on notify_all at this line."21 )22 self.thread3_before_lock_line = line_number(23 "main.cpp", "// thread3-before-lock"24 )25 26 def test_number_of_threads(self):27 """Test number of threads."""28 self.build()29 exe = self.getBuildArtifact("a.out")30 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)31 32 # This should create a breakpoint with 1 location.33 lldbutil.run_break_set_by_file_and_line(34 self, "main.cpp", self.thread3_notify_all_line, num_expected_locations=135 )36 37 # The breakpoint list should show 1 location.38 self.expect(39 "breakpoint list -f",40 "Breakpoint location shown correctly",41 substrs=[42 "1: file = 'main.cpp', line = %d, exact_match = 0, locations = 1"43 % self.thread3_notify_all_line44 ],45 )46 47 # Run the program.48 self.runCmd("run", RUN_SUCCEEDED)49 50 # Stopped once.51 self.expect(52 "thread list",53 STOPPED_DUE_TO_BREAKPOINT,54 substrs=["stop reason = breakpoint 1."],55 )56 57 # Get the target process58 target = self.dbg.GetSelectedTarget()59 process = target.GetProcess()60 61 # Get the number of threads62 num_threads = process.GetNumThreads()63 64 # Using std::thread may involve extra threads, so we assert that there are65 # at least 4 rather than exactly 4.66 self.assertGreaterEqual(67 num_threads,68 13,69 "Number of expected threads and actual threads do not match.",70 )71 72 @skipIfDarwin # rdar://3346236273 @skipIfWindows # This is flakey on Windows: llvm.org/pr37658, llvm.org/pr3837374 def test_unique_stacks(self):75 """Test backtrace unique with multiple threads executing the same stack."""76 self.build()77 exe = self.getBuildArtifact("a.out")78 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)79 80 # Set a break point on the thread3 notify all (should get hit on threads 4-13).81 lldbutil.run_break_set_by_file_and_line(82 self, "main.cpp", self.thread3_before_lock_line, num_expected_locations=183 )84 85 # Run the program.86 self.runCmd("run", RUN_SUCCEEDED)87 88 # Stopped once.89 self.expect(90 "thread list",91 STOPPED_DUE_TO_BREAKPOINT,92 substrs=["stop reason = breakpoint 1."],93 )94 95 process = self.process()96 97 # Get the number of threads98 num_threads = process.GetNumThreads()99 100 # Using std::thread may involve extra threads, so we assert that there are101 # at least 10 thread3's rather than exactly 10.102 self.assertGreaterEqual(103 num_threads,104 10,105 "Number of expected threads and actual threads do not match.",106 )107 108 # Attempt to walk each of the thread's executing the thread3 function to109 # the same breakpoint.110 def is_thread3(thread):111 for frame in thread:112 if frame.GetFunctionName() is None:113 continue114 if "thread3" in frame.GetFunctionName():115 return True116 return False117 118 expect_threads = ""119 for i in range(num_threads):120 thread = process.GetThreadAtIndex(i)121 self.assertTrue(thread.IsValid())122 if not is_thread3(thread):123 continue124 125 # If we aren't stopped out the thread breakpoint try to resume.126 if thread.GetStopReason() != lldb.eStopReasonBreakpoint:127 self.runCmd("thread continue %d" % (i + 1))128 self.assertStopReason(thread.GetStopReason(), lldb.eStopReasonBreakpoint)129 130 expect_threads += " #%d" % (i + 1)131 132 # Construct our expected back trace string133 expect_string = "10 thread(s)%s" % (expect_threads)134 135 # There was a bug where if you used 'thread backtrace unique'136 # we would switch all future backtraces to use the137 # "frame-format-unique" not the "frame-format". Make138 # sure we don't do that...139 setting_data = self.dbg.GetSetting("frame-format-unique")140 setting_str = setting_data.GetStringValue(1000)141 setting_str = "UNIQUE: " + setting_str142 lldb.SBDebugger.SetInternalVariable(143 "frame-format-unique", setting_str, self.dbg.GetInstanceName()144 )145 # Now that we are stopped, we should have 10 threads waiting in the146 # thread3 function. All of these threads should show as one stack.147 self.expect(148 "thread backtrace unique",149 "Backtrace with unique stack shown correctly",150 substrs=[151 expect_string,152 "UNIQUE:",153 "main.cpp:%d" % self.thread3_before_lock_line,154 ],155 )156 # Make sure setting the unique flag in the command isn't157 # persistent:158 self.expect(159 "thread backtrace",160 "Backtrace unique is not sticky",161 substrs=["UNIQUE:"],162 matching=False,163 )164