xref: /llvm-project/lldb/test/API/functionalities/thread/state/TestThreadStates.py (revision 4cc8f2a017c76af25234afc7c380550e9c93135c)
1"""
2Test thread states.
3"""
4
5
6
7import unittest2
8import lldb
9from lldbsuite.test.decorators import *
10from lldbsuite.test.lldbtest import *
11from lldbsuite.test import lldbutil
12
13
14class ThreadStateTestCase(TestBase):
15
16    @expectedFailureAll(
17        oslist=["linux"],
18        bugnumber="llvm.org/pr15824 thread states not properly maintained")
19    @skipIfDarwin # llvm.org/pr15824 thread states not properly maintained and <rdar://problem/28557237>
20    @expectedFailureAll(
21        oslist=["freebsd"],
22        bugnumber="llvm.org/pr18190 thread states not properly maintained")
23    @expectedFailureNetBSD
24    def test_state_after_breakpoint(self):
25        """Test thread state after breakpoint."""
26        self.build()
27        self.thread_state_after_breakpoint_test()
28
29    @skipIfDarwin  # 'llvm.org/pr23669', cause Python crash randomly
30    @expectedFailureAll(
31        oslist=lldbplatformutil.getDarwinOSTriples(),
32        bugnumber="llvm.org/pr23669")
33    @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24660")
34    def test_state_after_continue(self):
35        """Test thread state after continue."""
36        self.build()
37        self.thread_state_after_continue_test()
38
39    @skipIfDarwin  # 'llvm.org/pr23669', cause Python crash randomly
40    @expectedFailureDarwin('llvm.org/pr23669')
41    @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24660")
42    @expectedFailureNetBSD
43    # thread states not properly maintained
44    @expectedFailure("llvm.org/pr16712")
45    def test_state_after_expression(self):
46        """Test thread state after expression."""
47        self.build()
48        self.thread_state_after_expression_test()
49
50    # thread states not properly maintained
51    @expectedFailure("llvm.org/pr15824 and <rdar://problem/28557237>")
52    @expectedFailureAll(
53        oslist=["windows"],
54        bugnumber="llvm.org/pr24668: Breakpoints not resolved correctly")
55    @skipIfDarwin # llvm.org/pr15824 thread states not properly maintained and <rdar://problem/28557237>
56    @expectedFailureNetBSD
57    def test_process_state(self):
58        """Test thread states (comprehensive)."""
59        self.build()
60        self.thread_states_test()
61
62    def setUp(self):
63        # Call super's setUp().
64        TestBase.setUp(self)
65        # Find the line numbers for our breakpoints.
66        self.break_1 = line_number('main.cpp', '// Set first breakpoint here')
67        self.break_2 = line_number('main.cpp', '// Set second breakpoint here')
68
69    def thread_state_after_breakpoint_test(self):
70        """Test thread state after breakpoint."""
71        exe = self.getBuildArtifact("a.out")
72        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
73
74        # This should create a breakpoint in the main thread.
75        bp = lldbutil.run_break_set_by_file_and_line(
76            self, "main.cpp", self.break_1, num_expected_locations=1)
77
78        # Run the program.
79        self.runCmd("run", RUN_SUCCEEDED)
80
81        # Get the target process
82        target = self.dbg.GetSelectedTarget()
83        process = target.GetProcess()
84
85        thread = lldbutil.get_stopped_thread(
86            process, lldb.eStopReasonBreakpoint)
87        self.assertIsNotNone(thread)
88
89        # Make sure the thread is in the stopped state.
90        self.assertTrue(
91            thread.IsStopped(),
92            "Thread state isn't \'stopped\' during breakpoint 1.")
93        self.assertFalse(thread.IsSuspended(),
94                         "Thread state is \'suspended\' during breakpoint 1.")
95
96        # Kill the process
97        self.runCmd("process kill")
98
99    def wait_for_running_event(self, process):
100        listener = self.dbg.GetListener()
101        if lldb.remote_platform:
102            lldbutil.expect_state_changes(
103                self, listener, process, [
104                    lldb.eStateConnected])
105        lldbutil.expect_state_changes(
106            self, listener, process, [
107                lldb.eStateRunning])
108
109    def thread_state_after_continue_test(self):
110        """Test thread state after continue."""
111        exe = self.getBuildArtifact("a.out")
112        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
113
114        # This should create a breakpoint in the main thread.
115        lldbutil.run_break_set_by_file_and_line(
116            self, "main.cpp", self.break_1, num_expected_locations=1)
117        lldbutil.run_break_set_by_file_and_line(
118            self, "main.cpp", self.break_2, num_expected_locations=1)
119
120        # Run the program.
121        self.runCmd("run", RUN_SUCCEEDED)
122
123        # Get the target process
124        target = self.dbg.GetSelectedTarget()
125        process = target.GetProcess()
126
127        thread = lldbutil.get_stopped_thread(
128            process, lldb.eStopReasonBreakpoint)
129        self.assertIsNotNone(thread)
130
131        # Continue, the inferior will go into an infinite loop waiting for
132        # 'g_test' to change.
133        self.dbg.SetAsync(True)
134        self.runCmd("continue")
135        self.wait_for_running_event(process)
136
137        # Check the thread state. It should be running.
138        self.assertFalse(
139            thread.IsStopped(),
140            "Thread state is \'stopped\' when it should be running.")
141        self.assertFalse(
142            thread.IsSuspended(),
143            "Thread state is \'suspended\' when it should be running.")
144
145        # Go back to synchronous interactions
146        self.dbg.SetAsync(False)
147
148        # Kill the process
149        self.runCmd("process kill")
150
151    def thread_state_after_expression_test(self):
152        """Test thread state after expression."""
153        exe = self.getBuildArtifact("a.out")
154        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
155
156        # This should create a breakpoint in the main thread.
157        lldbutil.run_break_set_by_file_and_line(
158            self, "main.cpp", self.break_1, num_expected_locations=1)
159        lldbutil.run_break_set_by_file_and_line(
160            self, "main.cpp", self.break_2, num_expected_locations=1)
161
162        # Run the program.
163        self.runCmd("run", RUN_SUCCEEDED)
164
165        # Get the target process
166        target = self.dbg.GetSelectedTarget()
167        process = target.GetProcess()
168
169        thread = lldbutil.get_stopped_thread(
170            process, lldb.eStopReasonBreakpoint)
171        self.assertIsNotNone(thread)
172
173        # Get the inferior out of its loop
174        self.runCmd("expression g_test = 1")
175
176        # Check the thread state
177        self.assertTrue(
178            thread.IsStopped(),
179            "Thread state isn't \'stopped\' after expression evaluation.")
180        self.assertFalse(
181            thread.IsSuspended(),
182            "Thread state is \'suspended\' after expression evaluation.")
183
184        # Let the process run to completion
185        self.runCmd("process continue")
186
187    @expectedFailureAll(
188        oslist=["windows"],
189        bugnumber="llvm.org/pr24668: Breakpoints not resolved correctly")
190    @skipIfDarwin # llvm.org/pr15824 thread states not properly maintained and <rdar://problem/28557237>
191    @no_debug_info_test
192    def test_process_interrupt(self):
193        """Test process interrupt and continue."""
194        self.build()
195        exe = self.getBuildArtifact("a.out")
196        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
197
198        # This should create a breakpoint in the main thread.
199        bpno = lldbutil.run_break_set_by_file_and_line(
200            self, "main.cpp", self.break_1, num_expected_locations=1)
201
202        # Run the program.
203        self.runCmd("run", RUN_SUCCEEDED)
204
205        # Get the target process
206        target = self.dbg.GetSelectedTarget()
207        process = target.GetProcess()
208
209        thread = lldbutil.get_stopped_thread(
210            process, lldb.eStopReasonBreakpoint)
211        self.assertIsNotNone(thread)
212
213        # Remove the breakpoint to avoid the single-step-over-bkpt dance in the
214        # "continue" below
215        self.assertTrue(target.BreakpointDelete(bpno))
216
217        # Continue, the inferior will go into an infinite loop waiting for
218        # 'g_test' to change.
219        self.dbg.SetAsync(True)
220        self.runCmd("continue")
221        self.wait_for_running_event(process)
222
223        # Go back to synchronous interactions
224        self.dbg.SetAsync(False)
225
226        # Stop the process
227        self.runCmd("process interrupt")
228
229        self.assertEqual(thread.GetStopReason(), lldb.eStopReasonSignal)
230
231        # Get the inferior out of its loop
232        self.runCmd("expression g_test = 1")
233
234        # Run to completion
235        self.runCmd("continue")
236
237    def thread_states_test(self):
238        """Test thread states (comprehensive)."""
239        exe = self.getBuildArtifact("a.out")
240        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
241
242        # This should create a breakpoint in the main thread.
243        lldbutil.run_break_set_by_file_and_line(
244            self, "main.cpp", self.break_1, num_expected_locations=1)
245        lldbutil.run_break_set_by_file_and_line(
246            self, "main.cpp", self.break_2, num_expected_locations=1)
247
248        # Run the program.
249        self.runCmd("run", RUN_SUCCEEDED)
250
251        # Get the target process
252        target = self.dbg.GetSelectedTarget()
253        process = target.GetProcess()
254        thread = lldbutil.get_stopped_thread(
255            process, lldb.eStopReasonBreakpoint)
256        self.assertIsNotNone(thread)
257
258        # Make sure the thread is in the stopped state.
259        self.assertTrue(
260            thread.IsStopped(),
261            "Thread state isn't \'stopped\' during breakpoint 1.")
262        self.assertFalse(thread.IsSuspended(),
263                         "Thread state is \'suspended\' during breakpoint 1.")
264
265        # Continue, the inferior will go into an infinite loop waiting for
266        # 'g_test' to change.
267        self.dbg.SetAsync(True)
268        self.runCmd("continue")
269        self.wait_for_running_event(process)
270
271        # Check the thread state. It should be running.
272        self.assertFalse(
273            thread.IsStopped(),
274            "Thread state is \'stopped\' when it should be running.")
275        self.assertFalse(
276            thread.IsSuspended(),
277            "Thread state is \'suspended\' when it should be running.")
278
279        # Go back to synchronous interactions
280        self.dbg.SetAsync(False)
281
282        # Stop the process
283        self.runCmd("process interrupt")
284
285        self.assertEqual(thread.GetState(), lldb.eStopReasonSignal)
286
287        # Check the thread state
288        self.assertTrue(
289            thread.IsStopped(),
290            "Thread state isn't \'stopped\' after process stop.")
291        self.assertFalse(thread.IsSuspended(),
292                         "Thread state is \'suspended\' after process stop.")
293
294        # Get the inferior out of its loop
295        self.runCmd("expression g_test = 1")
296
297        # Check the thread state
298        self.assertTrue(
299            thread.IsStopped(),
300            "Thread state isn't \'stopped\' after expression evaluation.")
301        self.assertFalse(
302            thread.IsSuspended(),
303            "Thread state is \'suspended\' after expression evaluation.")
304
305        self.assertEqual(thread.GetState(), lldb.eStopReasonSignal)
306
307        # Run to breakpoint 2
308        self.runCmd("continue")
309
310        self.assertEqual(thread.GetState(), lldb.eStopReasonBreakpoint)
311
312        # Make sure both threads are stopped
313        self.assertTrue(
314            thread.IsStopped(),
315            "Thread state isn't \'stopped\' during breakpoint 2.")
316        self.assertFalse(thread.IsSuspended(),
317                         "Thread state is \'suspended\' during breakpoint 2.")
318
319        # Run to completion
320        self.runCmd("continue")
321
322        # At this point, the inferior process should have exited.
323        self.assertEqual(process.GetState(), lldb.eStateExited, PROCESS_EXITED)
324