xref: /llvm-project/lldb/test/API/functionalities/thread/state/TestThreadStates.py (revision 0f17d9a28c40eebd42c83956e2a7b5186c1814d7)
199451b44SJordan Rupprecht"""
299451b44SJordan RupprechtTest thread states.
399451b44SJordan Rupprecht"""
499451b44SJordan Rupprecht
599451b44SJordan Rupprecht
65b386158SJordan Rupprechtimport unittest
799451b44SJordan Rupprechtimport lldb
899451b44SJordan Rupprechtfrom lldbsuite.test.decorators import *
999451b44SJordan Rupprechtfrom lldbsuite.test.lldbtest import *
1099451b44SJordan Rupprechtfrom lldbsuite.test import lldbutil
1199451b44SJordan Rupprecht
1299451b44SJordan Rupprecht
1399451b44SJordan Rupprechtclass ThreadStateTestCase(TestBase):
1499451b44SJordan Rupprecht    @expectedFailureAll(
1599451b44SJordan Rupprecht        oslist=["linux"],
162238dcc3SJonas Devlieghere        bugnumber="llvm.org/pr15824 thread states not properly maintained",
172238dcc3SJonas Devlieghere    )
1899451b44SJordan Rupprecht    @skipIfDarwin  # llvm.org/pr15824 thread states not properly maintained and <rdar://problem/28557237>
1999451b44SJordan Rupprecht    @expectedFailureAll(
2099451b44SJordan Rupprecht        oslist=["freebsd"],
212238dcc3SJonas Devlieghere        bugnumber="llvm.org/pr18190 thread states not properly maintained",
222238dcc3SJonas Devlieghere    )
2399451b44SJordan Rupprecht    @expectedFailureNetBSD
2499451b44SJordan Rupprecht    def test_state_after_breakpoint(self):
2599451b44SJordan Rupprecht        """Test thread state after breakpoint."""
26d7dbe2c4SPavel Labath        self.build()
2799451b44SJordan Rupprecht        self.thread_state_after_breakpoint_test()
2899451b44SJordan Rupprecht
2999451b44SJordan Rupprecht    @skipIfDarwin  # 'llvm.org/pr23669', cause Python crash randomly
3099451b44SJordan Rupprecht    @expectedFailureAll(
312238dcc3SJonas Devlieghere        oslist=lldbplatformutil.getDarwinOSTriples(), bugnumber="llvm.org/pr23669"
322238dcc3SJonas Devlieghere    )
3399451b44SJordan Rupprecht    @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24660")
3499451b44SJordan Rupprecht    def test_state_after_continue(self):
3599451b44SJordan Rupprecht        """Test thread state after continue."""
36d7dbe2c4SPavel Labath        self.build()
3799451b44SJordan Rupprecht        self.thread_state_after_continue_test()
3899451b44SJordan Rupprecht
3999451b44SJordan Rupprecht    @skipIfDarwin  # 'llvm.org/pr23669', cause Python crash randomly
402238dcc3SJonas Devlieghere    @expectedFailureDarwin("llvm.org/pr23669")
4199451b44SJordan Rupprecht    @expectedFailureNetBSD
42*285bff39SDavid Spickett    # This actually passes on Windows on Arm but it's hard to describe that
43*285bff39SDavid Spickett    # and xfail it everywhere else.
44*285bff39SDavid Spickett    @skipIfWindows
4599451b44SJordan Rupprecht    # thread states not properly maintained
465b386158SJordan Rupprecht    @unittest.expectedFailure  # llvm.org/pr16712
4799451b44SJordan Rupprecht    def test_state_after_expression(self):
4899451b44SJordan Rupprecht        """Test thread state after expression."""
49d7dbe2c4SPavel Labath        self.build()
5099451b44SJordan Rupprecht        self.thread_state_after_expression_test()
5199451b44SJordan Rupprecht
5299451b44SJordan Rupprecht    # thread states not properly maintained
535b386158SJordan Rupprecht    @unittest.expectedFailure  # llvm.org/pr15824 and <rdar://problem/28557237>
5499451b44SJordan Rupprecht    @expectedFailureAll(
5599451b44SJordan Rupprecht        oslist=["windows"],
562238dcc3SJonas Devlieghere        bugnumber="llvm.org/pr24668: Breakpoints not resolved correctly",
572238dcc3SJonas Devlieghere    )
5899451b44SJordan Rupprecht    @skipIfDarwin  # llvm.org/pr15824 thread states not properly maintained and <rdar://problem/28557237>
5999451b44SJordan Rupprecht    @expectedFailureNetBSD
6099451b44SJordan Rupprecht    def test_process_state(self):
6199451b44SJordan Rupprecht        """Test thread states (comprehensive)."""
62d7dbe2c4SPavel Labath        self.build()
6399451b44SJordan Rupprecht        self.thread_states_test()
6499451b44SJordan Rupprecht
6599451b44SJordan Rupprecht    def setUp(self):
6699451b44SJordan Rupprecht        # Call super's setUp().
6799451b44SJordan Rupprecht        TestBase.setUp(self)
6899451b44SJordan Rupprecht        # Find the line numbers for our breakpoints.
692238dcc3SJonas Devlieghere        self.break_1 = line_number("main.cpp", "// Set first breakpoint here")
702238dcc3SJonas Devlieghere        self.break_2 = line_number("main.cpp", "// Set second breakpoint here")
7199451b44SJordan Rupprecht
7299451b44SJordan Rupprecht    def thread_state_after_breakpoint_test(self):
7399451b44SJordan Rupprecht        """Test thread state after breakpoint."""
7499451b44SJordan Rupprecht        exe = self.getBuildArtifact("a.out")
7599451b44SJordan Rupprecht        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
7699451b44SJordan Rupprecht
7799451b44SJordan Rupprecht        # This should create a breakpoint in the main thread.
7899451b44SJordan Rupprecht        bp = lldbutil.run_break_set_by_file_and_line(
792238dcc3SJonas Devlieghere            self, "main.cpp", self.break_1, num_expected_locations=1
802238dcc3SJonas Devlieghere        )
8199451b44SJordan Rupprecht
8299451b44SJordan Rupprecht        # Run the program.
8399451b44SJordan Rupprecht        self.runCmd("run", RUN_SUCCEEDED)
8499451b44SJordan Rupprecht
8599451b44SJordan Rupprecht        # Get the target process
8699451b44SJordan Rupprecht        target = self.dbg.GetSelectedTarget()
8799451b44SJordan Rupprecht        process = target.GetProcess()
8899451b44SJordan Rupprecht
892238dcc3SJonas Devlieghere        thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint)
9099451b44SJordan Rupprecht        self.assertIsNotNone(thread)
9199451b44SJordan Rupprecht
9299451b44SJordan Rupprecht        # Make sure the thread is in the stopped state.
9399451b44SJordan Rupprecht        self.assertTrue(
942238dcc3SJonas Devlieghere            thread.IsStopped(), "Thread state isn't 'stopped' during breakpoint 1."
952238dcc3SJonas Devlieghere        )
962238dcc3SJonas Devlieghere        self.assertFalse(
972238dcc3SJonas Devlieghere            thread.IsSuspended(), "Thread state is 'suspended' during breakpoint 1."
982238dcc3SJonas Devlieghere        )
9999451b44SJordan Rupprecht
10099451b44SJordan Rupprecht        # Kill the process
10199451b44SJordan Rupprecht        self.runCmd("process kill")
10299451b44SJordan Rupprecht
10399451b44SJordan Rupprecht    def wait_for_running_event(self, process):
10499451b44SJordan Rupprecht        listener = self.dbg.GetListener()
1052238dcc3SJonas Devlieghere        lldbutil.expect_state_changes(self, listener, process, [lldb.eStateRunning])
10699451b44SJordan Rupprecht
10799451b44SJordan Rupprecht    def thread_state_after_continue_test(self):
10899451b44SJordan Rupprecht        """Test thread state after continue."""
10999451b44SJordan Rupprecht        exe = self.getBuildArtifact("a.out")
11099451b44SJordan Rupprecht        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
11199451b44SJordan Rupprecht
11299451b44SJordan Rupprecht        # This should create a breakpoint in the main thread.
11399451b44SJordan Rupprecht        lldbutil.run_break_set_by_file_and_line(
1142238dcc3SJonas Devlieghere            self, "main.cpp", self.break_1, num_expected_locations=1
1152238dcc3SJonas Devlieghere        )
11699451b44SJordan Rupprecht        lldbutil.run_break_set_by_file_and_line(
1172238dcc3SJonas Devlieghere            self, "main.cpp", self.break_2, num_expected_locations=1
1182238dcc3SJonas Devlieghere        )
11999451b44SJordan Rupprecht
12099451b44SJordan Rupprecht        # Run the program.
12199451b44SJordan Rupprecht        self.runCmd("run", RUN_SUCCEEDED)
12299451b44SJordan Rupprecht
12399451b44SJordan Rupprecht        # Get the target process
12499451b44SJordan Rupprecht        target = self.dbg.GetSelectedTarget()
12599451b44SJordan Rupprecht        process = target.GetProcess()
12699451b44SJordan Rupprecht
1272238dcc3SJonas Devlieghere        thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint)
12899451b44SJordan Rupprecht        self.assertIsNotNone(thread)
12999451b44SJordan Rupprecht
13099451b44SJordan Rupprecht        # Continue, the inferior will go into an infinite loop waiting for
13199451b44SJordan Rupprecht        # 'g_test' to change.
13299451b44SJordan Rupprecht        self.dbg.SetAsync(True)
13399451b44SJordan Rupprecht        self.runCmd("continue")
13499451b44SJordan Rupprecht        self.wait_for_running_event(process)
13599451b44SJordan Rupprecht
13699451b44SJordan Rupprecht        # Check the thread state. It should be running.
13799451b44SJordan Rupprecht        self.assertFalse(
1382238dcc3SJonas Devlieghere            thread.IsStopped(), "Thread state is 'stopped' when it should be running."
1392238dcc3SJonas Devlieghere        )
14099451b44SJordan Rupprecht        self.assertFalse(
14199451b44SJordan Rupprecht            thread.IsSuspended(),
1422238dcc3SJonas Devlieghere            "Thread state is 'suspended' when it should be running.",
1432238dcc3SJonas Devlieghere        )
14499451b44SJordan Rupprecht
14599451b44SJordan Rupprecht        # Go back to synchronous interactions
14699451b44SJordan Rupprecht        self.dbg.SetAsync(False)
14799451b44SJordan Rupprecht
14899451b44SJordan Rupprecht        # Kill the process
14999451b44SJordan Rupprecht        self.runCmd("process kill")
15099451b44SJordan Rupprecht
15199451b44SJordan Rupprecht    def thread_state_after_expression_test(self):
15299451b44SJordan Rupprecht        """Test thread state after expression."""
15399451b44SJordan Rupprecht        exe = self.getBuildArtifact("a.out")
15499451b44SJordan Rupprecht        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
15599451b44SJordan Rupprecht
15699451b44SJordan Rupprecht        # This should create a breakpoint in the main thread.
15799451b44SJordan Rupprecht        lldbutil.run_break_set_by_file_and_line(
1582238dcc3SJonas Devlieghere            self, "main.cpp", self.break_1, num_expected_locations=1
1592238dcc3SJonas Devlieghere        )
16099451b44SJordan Rupprecht        lldbutil.run_break_set_by_file_and_line(
1612238dcc3SJonas Devlieghere            self, "main.cpp", self.break_2, num_expected_locations=1
1622238dcc3SJonas Devlieghere        )
16399451b44SJordan Rupprecht
16499451b44SJordan Rupprecht        # Run the program.
16599451b44SJordan Rupprecht        self.runCmd("run", RUN_SUCCEEDED)
16699451b44SJordan Rupprecht
16799451b44SJordan Rupprecht        # Get the target process
16899451b44SJordan Rupprecht        target = self.dbg.GetSelectedTarget()
16999451b44SJordan Rupprecht        process = target.GetProcess()
17099451b44SJordan Rupprecht
1712238dcc3SJonas Devlieghere        thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint)
17299451b44SJordan Rupprecht        self.assertIsNotNone(thread)
17399451b44SJordan Rupprecht
17499451b44SJordan Rupprecht        # Get the inferior out of its loop
17599451b44SJordan Rupprecht        self.runCmd("expression g_test = 1")
17699451b44SJordan Rupprecht
17799451b44SJordan Rupprecht        # Check the thread state
17899451b44SJordan Rupprecht        self.assertTrue(
17999451b44SJordan Rupprecht            thread.IsStopped(),
1802238dcc3SJonas Devlieghere            "Thread state isn't 'stopped' after expression evaluation.",
1812238dcc3SJonas Devlieghere        )
18299451b44SJordan Rupprecht        self.assertFalse(
18399451b44SJordan Rupprecht            thread.IsSuspended(),
1842238dcc3SJonas Devlieghere            "Thread state is 'suspended' after expression evaluation.",
1852238dcc3SJonas Devlieghere        )
18699451b44SJordan Rupprecht
18799451b44SJordan Rupprecht        # Let the process run to completion
18899451b44SJordan Rupprecht        self.runCmd("process continue")
18999451b44SJordan Rupprecht
19099451b44SJordan Rupprecht    @expectedFailureAll(
19199451b44SJordan Rupprecht        oslist=["windows"],
1922238dcc3SJonas Devlieghere        bugnumber="llvm.org/pr24668: Breakpoints not resolved correctly",
1932238dcc3SJonas Devlieghere    )
19499451b44SJordan Rupprecht    @skipIfDarwin  # llvm.org/pr15824 thread states not properly maintained and <rdar://problem/28557237>
19599451b44SJordan Rupprecht    @no_debug_info_test
19699451b44SJordan Rupprecht    def test_process_interrupt(self):
19799451b44SJordan Rupprecht        """Test process interrupt and continue."""
198d7dbe2c4SPavel Labath        self.build()
19999451b44SJordan Rupprecht        exe = self.getBuildArtifact("a.out")
20099451b44SJordan Rupprecht        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
20199451b44SJordan Rupprecht
20299451b44SJordan Rupprecht        # This should create a breakpoint in the main thread.
20399451b44SJordan Rupprecht        bpno = lldbutil.run_break_set_by_file_and_line(
2042238dcc3SJonas Devlieghere            self, "main.cpp", self.break_1, num_expected_locations=1
2052238dcc3SJonas Devlieghere        )
20699451b44SJordan Rupprecht
20799451b44SJordan Rupprecht        # Run the program.
20899451b44SJordan Rupprecht        self.runCmd("run", RUN_SUCCEEDED)
20999451b44SJordan Rupprecht
21099451b44SJordan Rupprecht        # Get the target process
21199451b44SJordan Rupprecht        target = self.dbg.GetSelectedTarget()
21299451b44SJordan Rupprecht        process = target.GetProcess()
21399451b44SJordan Rupprecht
2142238dcc3SJonas Devlieghere        thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint)
21599451b44SJordan Rupprecht        self.assertIsNotNone(thread)
21699451b44SJordan Rupprecht
21799451b44SJordan Rupprecht        # Remove the breakpoint to avoid the single-step-over-bkpt dance in the
21899451b44SJordan Rupprecht        # "continue" below
21999451b44SJordan Rupprecht        self.assertTrue(target.BreakpointDelete(bpno))
22099451b44SJordan Rupprecht
22199451b44SJordan Rupprecht        # Continue, the inferior will go into an infinite loop waiting for
22299451b44SJordan Rupprecht        # 'g_test' to change.
22399451b44SJordan Rupprecht        self.dbg.SetAsync(True)
22499451b44SJordan Rupprecht        self.runCmd("continue")
22599451b44SJordan Rupprecht        self.wait_for_running_event(process)
22699451b44SJordan Rupprecht
22799451b44SJordan Rupprecht        # Go back to synchronous interactions
22899451b44SJordan Rupprecht        self.dbg.SetAsync(False)
22999451b44SJordan Rupprecht
23099451b44SJordan Rupprecht        # Stop the process
23199451b44SJordan Rupprecht        self.runCmd("process interrupt")
23299451b44SJordan Rupprecht
2330f821339SJonas Devlieghere        self.assertStopReason(thread.GetStopReason(), lldb.eStopReasonSignal)
23499451b44SJordan Rupprecht
23599451b44SJordan Rupprecht        # Get the inferior out of its loop
23699451b44SJordan Rupprecht        self.runCmd("expression g_test = 1")
23799451b44SJordan Rupprecht
23899451b44SJordan Rupprecht        # Run to completion
23999451b44SJordan Rupprecht        self.runCmd("continue")
24099451b44SJordan Rupprecht
24199451b44SJordan Rupprecht    def thread_states_test(self):
24299451b44SJordan Rupprecht        """Test thread states (comprehensive)."""
24399451b44SJordan Rupprecht        exe = self.getBuildArtifact("a.out")
24499451b44SJordan Rupprecht        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
24599451b44SJordan Rupprecht
24699451b44SJordan Rupprecht        # This should create a breakpoint in the main thread.
24799451b44SJordan Rupprecht        lldbutil.run_break_set_by_file_and_line(
2482238dcc3SJonas Devlieghere            self, "main.cpp", self.break_1, num_expected_locations=1
2492238dcc3SJonas Devlieghere        )
25099451b44SJordan Rupprecht        lldbutil.run_break_set_by_file_and_line(
2512238dcc3SJonas Devlieghere            self, "main.cpp", self.break_2, num_expected_locations=1
2522238dcc3SJonas Devlieghere        )
25399451b44SJordan Rupprecht
25499451b44SJordan Rupprecht        # Run the program.
25599451b44SJordan Rupprecht        self.runCmd("run", RUN_SUCCEEDED)
25699451b44SJordan Rupprecht
25799451b44SJordan Rupprecht        # Get the target process
25899451b44SJordan Rupprecht        target = self.dbg.GetSelectedTarget()
25999451b44SJordan Rupprecht        process = target.GetProcess()
2602238dcc3SJonas Devlieghere        thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint)
26199451b44SJordan Rupprecht        self.assertIsNotNone(thread)
26299451b44SJordan Rupprecht
26399451b44SJordan Rupprecht        # Make sure the thread is in the stopped state.
26499451b44SJordan Rupprecht        self.assertTrue(
2652238dcc3SJonas Devlieghere            thread.IsStopped(), "Thread state isn't 'stopped' during breakpoint 1."
2662238dcc3SJonas Devlieghere        )
2672238dcc3SJonas Devlieghere        self.assertFalse(
2682238dcc3SJonas Devlieghere            thread.IsSuspended(), "Thread state is 'suspended' during breakpoint 1."
2692238dcc3SJonas Devlieghere        )
27099451b44SJordan Rupprecht
27199451b44SJordan Rupprecht        # Continue, the inferior will go into an infinite loop waiting for
27299451b44SJordan Rupprecht        # 'g_test' to change.
27399451b44SJordan Rupprecht        self.dbg.SetAsync(True)
27499451b44SJordan Rupprecht        self.runCmd("continue")
27599451b44SJordan Rupprecht        self.wait_for_running_event(process)
27699451b44SJordan Rupprecht
27799451b44SJordan Rupprecht        # Check the thread state. It should be running.
27899451b44SJordan Rupprecht        self.assertFalse(
2792238dcc3SJonas Devlieghere            thread.IsStopped(), "Thread state is 'stopped' when it should be running."
2802238dcc3SJonas Devlieghere        )
28199451b44SJordan Rupprecht        self.assertFalse(
28299451b44SJordan Rupprecht            thread.IsSuspended(),
2832238dcc3SJonas Devlieghere            "Thread state is 'suspended' when it should be running.",
2842238dcc3SJonas Devlieghere        )
28599451b44SJordan Rupprecht
28699451b44SJordan Rupprecht        # Go back to synchronous interactions
28799451b44SJordan Rupprecht        self.dbg.SetAsync(False)
28899451b44SJordan Rupprecht
28999451b44SJordan Rupprecht        # Stop the process
29099451b44SJordan Rupprecht        self.runCmd("process interrupt")
29199451b44SJordan Rupprecht
2920f821339SJonas Devlieghere        self.assertStopReason(thread.GetState(), lldb.eStopReasonSignal)
29399451b44SJordan Rupprecht
29499451b44SJordan Rupprecht        # Check the thread state
29599451b44SJordan Rupprecht        self.assertTrue(
2962238dcc3SJonas Devlieghere            thread.IsStopped(), "Thread state isn't 'stopped' after process stop."
2972238dcc3SJonas Devlieghere        )
2982238dcc3SJonas Devlieghere        self.assertFalse(
2992238dcc3SJonas Devlieghere            thread.IsSuspended(), "Thread state is 'suspended' after process stop."
3002238dcc3SJonas Devlieghere        )
30199451b44SJordan Rupprecht
30299451b44SJordan Rupprecht        # Get the inferior out of its loop
30399451b44SJordan Rupprecht        self.runCmd("expression g_test = 1")
30499451b44SJordan Rupprecht
30599451b44SJordan Rupprecht        # Check the thread state
30699451b44SJordan Rupprecht        self.assertTrue(
30799451b44SJordan Rupprecht            thread.IsStopped(),
3082238dcc3SJonas Devlieghere            "Thread state isn't 'stopped' after expression evaluation.",
3092238dcc3SJonas Devlieghere        )
31099451b44SJordan Rupprecht        self.assertFalse(
31199451b44SJordan Rupprecht            thread.IsSuspended(),
3122238dcc3SJonas Devlieghere            "Thread state is 'suspended' after expression evaluation.",
3132238dcc3SJonas Devlieghere        )
31499451b44SJordan Rupprecht
3150f821339SJonas Devlieghere        self.assertStopReason(thread.GetState(), lldb.eStopReasonSignal)
31699451b44SJordan Rupprecht
31799451b44SJordan Rupprecht        # Run to breakpoint 2
31899451b44SJordan Rupprecht        self.runCmd("continue")
31999451b44SJordan Rupprecht
3200f821339SJonas Devlieghere        self.assertStopReason(thread.GetState(), lldb.eStopReasonBreakpoint)
32199451b44SJordan Rupprecht
32299451b44SJordan Rupprecht        # Make sure both threads are stopped
32399451b44SJordan Rupprecht        self.assertTrue(
3242238dcc3SJonas Devlieghere            thread.IsStopped(), "Thread state isn't 'stopped' during breakpoint 2."
3252238dcc3SJonas Devlieghere        )
3262238dcc3SJonas Devlieghere        self.assertFalse(
3272238dcc3SJonas Devlieghere            thread.IsSuspended(), "Thread state is 'suspended' during breakpoint 2."
3282238dcc3SJonas Devlieghere        )
32999451b44SJordan Rupprecht
33099451b44SJordan Rupprecht        # Run to completion
33199451b44SJordan Rupprecht        self.runCmd("continue")
33299451b44SJordan Rupprecht
33399451b44SJordan Rupprecht        # At this point, the inferior process should have exited.
3341b8c7352SJonas Devlieghere        self.assertState(process.GetState(), lldb.eStateExited, PROCESS_EXITED)
335