199451b44SJordan Rupprecht"""
299451b44SJordan RupprechtTest thread states.
399451b44SJordan Rupprecht"""
499451b44SJordan Rupprecht
599451b44SJordan Rupprecht
699451b44SJordan Rupprecht
799451b44SJordan Rupprechtimport unittest2
899451b44SJordan Rupprechtimport lldb
999451b44SJordan Rupprechtfrom lldbsuite.test.decorators import *
1099451b44SJordan Rupprechtfrom lldbsuite.test.lldbtest import *
1199451b44SJordan Rupprechtfrom lldbsuite.test import lldbutil
1299451b44SJordan Rupprecht
1399451b44SJordan Rupprecht
1499451b44SJordan Rupprechtclass ThreadStateTestCase(TestBase):
1599451b44SJordan Rupprecht
1699451b44SJordan Rupprecht    @expectedFailureAll(
1799451b44SJordan Rupprecht        oslist=["linux"],
1899451b44SJordan Rupprecht        bugnumber="llvm.org/pr15824 thread states not properly maintained")
1999451b44SJordan Rupprecht    @skipIfDarwin # llvm.org/pr15824 thread states not properly maintained and <rdar://problem/28557237>
2099451b44SJordan Rupprecht    @expectedFailureAll(
2199451b44SJordan Rupprecht        oslist=["freebsd"],
2299451b44SJordan Rupprecht        bugnumber="llvm.org/pr18190 thread states not properly maintained")
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(
3199451b44SJordan Rupprecht        oslist=lldbplatformutil.getDarwinOSTriples(),
3299451b44SJordan Rupprecht        bugnumber="llvm.org/pr23669")
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
4099451b44SJordan Rupprecht    @expectedFailureDarwin('llvm.org/pr23669')
4199451b44SJordan Rupprecht    @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24660")
4299451b44SJordan Rupprecht    @expectedFailureNetBSD
4399451b44SJordan Rupprecht    # thread states not properly maintained
44e9b09940SJonas Devlieghere    @expectedFailure("llvm.org/pr16712")
4599451b44SJordan Rupprecht    def test_state_after_expression(self):
4699451b44SJordan Rupprecht        """Test thread state after expression."""
47d7dbe2c4SPavel Labath        self.build()
4899451b44SJordan Rupprecht        self.thread_state_after_expression_test()
4999451b44SJordan Rupprecht
5099451b44SJordan Rupprecht    # thread states not properly maintained
51e9b09940SJonas Devlieghere    @expectedFailure("llvm.org/pr15824 and <rdar://problem/28557237>")
5299451b44SJordan Rupprecht    @expectedFailureAll(
5399451b44SJordan Rupprecht        oslist=["windows"],
5499451b44SJordan Rupprecht        bugnumber="llvm.org/pr24668: Breakpoints not resolved correctly")
5599451b44SJordan Rupprecht    @skipIfDarwin # llvm.org/pr15824 thread states not properly maintained and <rdar://problem/28557237>
5699451b44SJordan Rupprecht    @expectedFailureNetBSD
5799451b44SJordan Rupprecht    def test_process_state(self):
5899451b44SJordan Rupprecht        """Test thread states (comprehensive)."""
59d7dbe2c4SPavel Labath        self.build()
6099451b44SJordan Rupprecht        self.thread_states_test()
6199451b44SJordan Rupprecht
6299451b44SJordan Rupprecht    def setUp(self):
6399451b44SJordan Rupprecht        # Call super's setUp().
6499451b44SJordan Rupprecht        TestBase.setUp(self)
6599451b44SJordan Rupprecht        # Find the line numbers for our breakpoints.
6699451b44SJordan Rupprecht        self.break_1 = line_number('main.cpp', '// Set first breakpoint here')
6799451b44SJordan Rupprecht        self.break_2 = line_number('main.cpp', '// Set second breakpoint here')
6899451b44SJordan Rupprecht
6999451b44SJordan Rupprecht    def thread_state_after_breakpoint_test(self):
7099451b44SJordan Rupprecht        """Test thread state after breakpoint."""
7199451b44SJordan Rupprecht        exe = self.getBuildArtifact("a.out")
7299451b44SJordan Rupprecht        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
7399451b44SJordan Rupprecht
7499451b44SJordan Rupprecht        # This should create a breakpoint in the main thread.
7599451b44SJordan Rupprecht        bp = lldbutil.run_break_set_by_file_and_line(
7699451b44SJordan Rupprecht            self, "main.cpp", self.break_1, num_expected_locations=1)
7799451b44SJordan Rupprecht
7899451b44SJordan Rupprecht        # Run the program.
7999451b44SJordan Rupprecht        self.runCmd("run", RUN_SUCCEEDED)
8099451b44SJordan Rupprecht
8199451b44SJordan Rupprecht        # Get the target process
8299451b44SJordan Rupprecht        target = self.dbg.GetSelectedTarget()
8399451b44SJordan Rupprecht        process = target.GetProcess()
8499451b44SJordan Rupprecht
8599451b44SJordan Rupprecht        thread = lldbutil.get_stopped_thread(
8699451b44SJordan Rupprecht            process, lldb.eStopReasonBreakpoint)
8799451b44SJordan Rupprecht        self.assertIsNotNone(thread)
8899451b44SJordan Rupprecht
8999451b44SJordan Rupprecht        # Make sure the thread is in the stopped state.
9099451b44SJordan Rupprecht        self.assertTrue(
9199451b44SJordan Rupprecht            thread.IsStopped(),
9299451b44SJordan Rupprecht            "Thread state isn't \'stopped\' during breakpoint 1.")
9399451b44SJordan Rupprecht        self.assertFalse(thread.IsSuspended(),
9499451b44SJordan Rupprecht                         "Thread state is \'suspended\' during breakpoint 1.")
9599451b44SJordan Rupprecht
9699451b44SJordan Rupprecht        # Kill the process
9799451b44SJordan Rupprecht        self.runCmd("process kill")
9899451b44SJordan Rupprecht
9999451b44SJordan Rupprecht    def wait_for_running_event(self, process):
10099451b44SJordan Rupprecht        listener = self.dbg.GetListener()
10199451b44SJordan Rupprecht        if lldb.remote_platform:
10299451b44SJordan Rupprecht            lldbutil.expect_state_changes(
10399451b44SJordan Rupprecht                self, listener, process, [
10499451b44SJordan Rupprecht                    lldb.eStateConnected])
10599451b44SJordan Rupprecht        lldbutil.expect_state_changes(
10699451b44SJordan Rupprecht            self, listener, process, [
10799451b44SJordan Rupprecht                lldb.eStateRunning])
10899451b44SJordan Rupprecht
10999451b44SJordan Rupprecht    def thread_state_after_continue_test(self):
11099451b44SJordan Rupprecht        """Test thread state after continue."""
11199451b44SJordan Rupprecht        exe = self.getBuildArtifact("a.out")
11299451b44SJordan Rupprecht        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
11399451b44SJordan Rupprecht
11499451b44SJordan Rupprecht        # This should create a breakpoint in the main thread.
11599451b44SJordan Rupprecht        lldbutil.run_break_set_by_file_and_line(
11699451b44SJordan Rupprecht            self, "main.cpp", self.break_1, num_expected_locations=1)
11799451b44SJordan Rupprecht        lldbutil.run_break_set_by_file_and_line(
11899451b44SJordan Rupprecht            self, "main.cpp", self.break_2, num_expected_locations=1)
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
12799451b44SJordan Rupprecht        thread = lldbutil.get_stopped_thread(
12899451b44SJordan Rupprecht            process, lldb.eStopReasonBreakpoint)
12999451b44SJordan Rupprecht        self.assertIsNotNone(thread)
13099451b44SJordan Rupprecht
13199451b44SJordan Rupprecht        # Continue, the inferior will go into an infinite loop waiting for
13299451b44SJordan Rupprecht        # 'g_test' to change.
13399451b44SJordan Rupprecht        self.dbg.SetAsync(True)
13499451b44SJordan Rupprecht        self.runCmd("continue")
13599451b44SJordan Rupprecht        self.wait_for_running_event(process)
13699451b44SJordan Rupprecht
13799451b44SJordan Rupprecht        # Check the thread state. It should be running.
13899451b44SJordan Rupprecht        self.assertFalse(
13999451b44SJordan Rupprecht            thread.IsStopped(),
14099451b44SJordan Rupprecht            "Thread state is \'stopped\' when it should be running.")
14199451b44SJordan Rupprecht        self.assertFalse(
14299451b44SJordan Rupprecht            thread.IsSuspended(),
14399451b44SJordan Rupprecht            "Thread state is \'suspended\' when it should be running.")
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(
15899451b44SJordan Rupprecht            self, "main.cpp", self.break_1, num_expected_locations=1)
15999451b44SJordan Rupprecht        lldbutil.run_break_set_by_file_and_line(
16099451b44SJordan Rupprecht            self, "main.cpp", self.break_2, num_expected_locations=1)
16199451b44SJordan Rupprecht
16299451b44SJordan Rupprecht        # Run the program.
16399451b44SJordan Rupprecht        self.runCmd("run", RUN_SUCCEEDED)
16499451b44SJordan Rupprecht
16599451b44SJordan Rupprecht        # Get the target process
16699451b44SJordan Rupprecht        target = self.dbg.GetSelectedTarget()
16799451b44SJordan Rupprecht        process = target.GetProcess()
16899451b44SJordan Rupprecht
16999451b44SJordan Rupprecht        thread = lldbutil.get_stopped_thread(
17099451b44SJordan Rupprecht            process, lldb.eStopReasonBreakpoint)
17199451b44SJordan Rupprecht        self.assertIsNotNone(thread)
17299451b44SJordan Rupprecht
17399451b44SJordan Rupprecht        # Get the inferior out of its loop
17499451b44SJordan Rupprecht        self.runCmd("expression g_test = 1")
17599451b44SJordan Rupprecht
17699451b44SJordan Rupprecht        # Check the thread state
17799451b44SJordan Rupprecht        self.assertTrue(
17899451b44SJordan Rupprecht            thread.IsStopped(),
17999451b44SJordan Rupprecht            "Thread state isn't \'stopped\' after expression evaluation.")
18099451b44SJordan Rupprecht        self.assertFalse(
18199451b44SJordan Rupprecht            thread.IsSuspended(),
18299451b44SJordan Rupprecht            "Thread state is \'suspended\' after expression evaluation.")
18399451b44SJordan Rupprecht
18499451b44SJordan Rupprecht        # Let the process run to completion
18599451b44SJordan Rupprecht        self.runCmd("process continue")
18699451b44SJordan Rupprecht
18799451b44SJordan Rupprecht    @expectedFailureAll(
18899451b44SJordan Rupprecht        oslist=["windows"],
18999451b44SJordan Rupprecht        bugnumber="llvm.org/pr24668: Breakpoints not resolved correctly")
19099451b44SJordan Rupprecht    @skipIfDarwin # llvm.org/pr15824 thread states not properly maintained and <rdar://problem/28557237>
19199451b44SJordan Rupprecht    @no_debug_info_test
19299451b44SJordan Rupprecht    def test_process_interrupt(self):
19399451b44SJordan Rupprecht        """Test process interrupt and continue."""
194d7dbe2c4SPavel Labath        self.build()
19599451b44SJordan Rupprecht        exe = self.getBuildArtifact("a.out")
19699451b44SJordan Rupprecht        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
19799451b44SJordan Rupprecht
19899451b44SJordan Rupprecht        # This should create a breakpoint in the main thread.
19999451b44SJordan Rupprecht        bpno = lldbutil.run_break_set_by_file_and_line(
20099451b44SJordan Rupprecht            self, "main.cpp", self.break_1, num_expected_locations=1)
20199451b44SJordan Rupprecht
20299451b44SJordan Rupprecht        # Run the program.
20399451b44SJordan Rupprecht        self.runCmd("run", RUN_SUCCEEDED)
20499451b44SJordan Rupprecht
20599451b44SJordan Rupprecht        # Get the target process
20699451b44SJordan Rupprecht        target = self.dbg.GetSelectedTarget()
20799451b44SJordan Rupprecht        process = target.GetProcess()
20899451b44SJordan Rupprecht
20999451b44SJordan Rupprecht        thread = lldbutil.get_stopped_thread(
21099451b44SJordan Rupprecht            process, lldb.eStopReasonBreakpoint)
21199451b44SJordan Rupprecht        self.assertIsNotNone(thread)
21299451b44SJordan Rupprecht
21399451b44SJordan Rupprecht        # Remove the breakpoint to avoid the single-step-over-bkpt dance in the
21499451b44SJordan Rupprecht        # "continue" below
21599451b44SJordan Rupprecht        self.assertTrue(target.BreakpointDelete(bpno))
21699451b44SJordan Rupprecht
21799451b44SJordan Rupprecht        # Continue, the inferior will go into an infinite loop waiting for
21899451b44SJordan Rupprecht        # 'g_test' to change.
21999451b44SJordan Rupprecht        self.dbg.SetAsync(True)
22099451b44SJordan Rupprecht        self.runCmd("continue")
22199451b44SJordan Rupprecht        self.wait_for_running_event(process)
22299451b44SJordan Rupprecht
22399451b44SJordan Rupprecht        # Go back to synchronous interactions
22499451b44SJordan Rupprecht        self.dbg.SetAsync(False)
22599451b44SJordan Rupprecht
22699451b44SJordan Rupprecht        # Stop the process
22799451b44SJordan Rupprecht        self.runCmd("process interrupt")
22899451b44SJordan Rupprecht
22999451b44SJordan Rupprecht        self.assertEqual(thread.GetStopReason(), lldb.eStopReasonSignal)
23099451b44SJordan Rupprecht
23199451b44SJordan Rupprecht        # Get the inferior out of its loop
23299451b44SJordan Rupprecht        self.runCmd("expression g_test = 1")
23399451b44SJordan Rupprecht
23499451b44SJordan Rupprecht        # Run to completion
23599451b44SJordan Rupprecht        self.runCmd("continue")
23699451b44SJordan Rupprecht
23799451b44SJordan Rupprecht    def thread_states_test(self):
23899451b44SJordan Rupprecht        """Test thread states (comprehensive)."""
23999451b44SJordan Rupprecht        exe = self.getBuildArtifact("a.out")
24099451b44SJordan Rupprecht        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
24199451b44SJordan Rupprecht
24299451b44SJordan Rupprecht        # This should create a breakpoint in the main thread.
24399451b44SJordan Rupprecht        lldbutil.run_break_set_by_file_and_line(
24499451b44SJordan Rupprecht            self, "main.cpp", self.break_1, num_expected_locations=1)
24599451b44SJordan Rupprecht        lldbutil.run_break_set_by_file_and_line(
24699451b44SJordan Rupprecht            self, "main.cpp", self.break_2, num_expected_locations=1)
24799451b44SJordan Rupprecht
24899451b44SJordan Rupprecht        # Run the program.
24999451b44SJordan Rupprecht        self.runCmd("run", RUN_SUCCEEDED)
25099451b44SJordan Rupprecht
25199451b44SJordan Rupprecht        # Get the target process
25299451b44SJordan Rupprecht        target = self.dbg.GetSelectedTarget()
25399451b44SJordan Rupprecht        process = target.GetProcess()
25499451b44SJordan Rupprecht        thread = lldbutil.get_stopped_thread(
25599451b44SJordan Rupprecht            process, lldb.eStopReasonBreakpoint)
25699451b44SJordan Rupprecht        self.assertIsNotNone(thread)
25799451b44SJordan Rupprecht
25899451b44SJordan Rupprecht        # Make sure the thread is in the stopped state.
25999451b44SJordan Rupprecht        self.assertTrue(
26099451b44SJordan Rupprecht            thread.IsStopped(),
26199451b44SJordan Rupprecht            "Thread state isn't \'stopped\' during breakpoint 1.")
26299451b44SJordan Rupprecht        self.assertFalse(thread.IsSuspended(),
26399451b44SJordan Rupprecht                         "Thread state is \'suspended\' during breakpoint 1.")
26499451b44SJordan Rupprecht
26599451b44SJordan Rupprecht        # Continue, the inferior will go into an infinite loop waiting for
26699451b44SJordan Rupprecht        # 'g_test' to change.
26799451b44SJordan Rupprecht        self.dbg.SetAsync(True)
26899451b44SJordan Rupprecht        self.runCmd("continue")
26999451b44SJordan Rupprecht        self.wait_for_running_event(process)
27099451b44SJordan Rupprecht
27199451b44SJordan Rupprecht        # Check the thread state. It should be running.
27299451b44SJordan Rupprecht        self.assertFalse(
27399451b44SJordan Rupprecht            thread.IsStopped(),
27499451b44SJordan Rupprecht            "Thread state is \'stopped\' when it should be running.")
27599451b44SJordan Rupprecht        self.assertFalse(
27699451b44SJordan Rupprecht            thread.IsSuspended(),
27799451b44SJordan Rupprecht            "Thread state is \'suspended\' when it should be running.")
27899451b44SJordan Rupprecht
27999451b44SJordan Rupprecht        # Go back to synchronous interactions
28099451b44SJordan Rupprecht        self.dbg.SetAsync(False)
28199451b44SJordan Rupprecht
28299451b44SJordan Rupprecht        # Stop the process
28399451b44SJordan Rupprecht        self.runCmd("process interrupt")
28499451b44SJordan Rupprecht
28599451b44SJordan Rupprecht        self.assertEqual(thread.GetState(), lldb.eStopReasonSignal)
28699451b44SJordan Rupprecht
28799451b44SJordan Rupprecht        # Check the thread state
28899451b44SJordan Rupprecht        self.assertTrue(
28999451b44SJordan Rupprecht            thread.IsStopped(),
29099451b44SJordan Rupprecht            "Thread state isn't \'stopped\' after process stop.")
29199451b44SJordan Rupprecht        self.assertFalse(thread.IsSuspended(),
29299451b44SJordan Rupprecht                         "Thread state is \'suspended\' after process stop.")
29399451b44SJordan Rupprecht
29499451b44SJordan Rupprecht        # Get the inferior out of its loop
29599451b44SJordan Rupprecht        self.runCmd("expression g_test = 1")
29699451b44SJordan Rupprecht
29799451b44SJordan Rupprecht        # Check the thread state
29899451b44SJordan Rupprecht        self.assertTrue(
29999451b44SJordan Rupprecht            thread.IsStopped(),
30099451b44SJordan Rupprecht            "Thread state isn't \'stopped\' after expression evaluation.")
30199451b44SJordan Rupprecht        self.assertFalse(
30299451b44SJordan Rupprecht            thread.IsSuspended(),
30399451b44SJordan Rupprecht            "Thread state is \'suspended\' after expression evaluation.")
30499451b44SJordan Rupprecht
30599451b44SJordan Rupprecht        self.assertEqual(thread.GetState(), lldb.eStopReasonSignal)
30699451b44SJordan Rupprecht
30799451b44SJordan Rupprecht        # Run to breakpoint 2
30899451b44SJordan Rupprecht        self.runCmd("continue")
30999451b44SJordan Rupprecht
31099451b44SJordan Rupprecht        self.assertEqual(thread.GetState(), lldb.eStopReasonBreakpoint)
31199451b44SJordan Rupprecht
31299451b44SJordan Rupprecht        # Make sure both threads are stopped
31399451b44SJordan Rupprecht        self.assertTrue(
31499451b44SJordan Rupprecht            thread.IsStopped(),
31599451b44SJordan Rupprecht            "Thread state isn't \'stopped\' during breakpoint 2.")
31699451b44SJordan Rupprecht        self.assertFalse(thread.IsSuspended(),
31799451b44SJordan Rupprecht                         "Thread state is \'suspended\' during breakpoint 2.")
31899451b44SJordan Rupprecht
31999451b44SJordan Rupprecht        # Run to completion
32099451b44SJordan Rupprecht        self.runCmd("continue")
32199451b44SJordan Rupprecht
32299451b44SJordan Rupprecht        # At this point, the inferior process should have exited.
323*1b8c7352SJonas Devlieghere        self.assertState(process.GetState(), lldb.eStateExited, PROCESS_EXITED)
324