TestNumThreads.py
4.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
"""
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 frame.GetFunctionName() is None:
continue
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])