199451b44SJordan Rupprecht"""
299451b44SJordan RupprechtTest thread creation after process attach.
399451b44SJordan Rupprecht"""
499451b44SJordan Rupprecht
599451b44SJordan Rupprecht
699451b44SJordan Rupprecht
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 CreateAfterAttachTestCase(TestBase):
1499451b44SJordan Rupprecht
1599451b44SJordan Rupprecht    def setUp(self):
1699451b44SJordan Rupprecht        # Call super's setUp().
1799451b44SJordan Rupprecht        TestBase.setUp(self)
1899451b44SJordan Rupprecht        # Find the line numbers for our breakpoints.
1999451b44SJordan Rupprecht        self.break_1 = line_number('main.cpp', '// Set first breakpoint here')
2099451b44SJordan Rupprecht        self.break_2 = line_number('main.cpp', '// Set second breakpoint here')
2199451b44SJordan Rupprecht        self.break_3 = line_number('main.cpp', '// Set third breakpoint here')
2299451b44SJordan Rupprecht
23700dd173SJonas Devlieghere    # Occasionally hangs on Windows, may be same as other issues.
24700dd173SJonas Devlieghere    @skipIfWindows
25700dd173SJonas Devlieghere    @skipIfiOSSimulator
26266c90feSMichał Górny    @expectedFailureNetBSD
27700dd173SJonas Devlieghere    def test_create_after_attach(self):
2899451b44SJordan Rupprecht        """Test thread creation after process attach."""
29*d7dbe2c4SPavel Labath        self.build()
3099451b44SJordan Rupprecht        exe = self.getBuildArtifact("a.out")
3199451b44SJordan Rupprecht
3299451b44SJordan Rupprecht        # Spawn a new process
3315f067f1SMichał Górny        # use realpath to workaround llvm.org/pr48376
3415f067f1SMichał Górny        popen = self.spawnSubprocess(os.path.realpath(exe))
3599451b44SJordan Rupprecht        pid = popen.pid
3699451b44SJordan Rupprecht
3799451b44SJordan Rupprecht        # Attach to the spawned process
3899451b44SJordan Rupprecht        self.runCmd("process attach -p " + str(pid))
3999451b44SJordan Rupprecht
4099451b44SJordan Rupprecht        target = self.dbg.GetSelectedTarget()
4199451b44SJordan Rupprecht
4299451b44SJordan Rupprecht        process = target.GetProcess()
4399451b44SJordan Rupprecht        self.assertTrue(process, PROCESS_IS_VALID)
4499451b44SJordan Rupprecht
4599451b44SJordan Rupprecht        # This should create a breakpoint in the main thread.
4699451b44SJordan Rupprecht        lldbutil.run_break_set_by_file_and_line(
4799451b44SJordan Rupprecht            self, "main.cpp", self.break_1, num_expected_locations=1)
4899451b44SJordan Rupprecht
4999451b44SJordan Rupprecht        # This should create a breakpoint in the second child thread.
5099451b44SJordan Rupprecht        lldbutil.run_break_set_by_file_and_line(
5199451b44SJordan Rupprecht            self, "main.cpp", self.break_2, num_expected_locations=1)
5299451b44SJordan Rupprecht
5399451b44SJordan Rupprecht        # This should create a breakpoint in the first child thread.
5499451b44SJordan Rupprecht        lldbutil.run_break_set_by_file_and_line(
5599451b44SJordan Rupprecht            self, "main.cpp", self.break_3, num_expected_locations=1)
5699451b44SJordan Rupprecht
5799451b44SJordan Rupprecht        # Note:  With std::thread, we cannot rely on particular thread numbers.  Using
5899451b44SJordan Rupprecht        # std::thread may cause the program to spin up a thread pool (and it does on
5999451b44SJordan Rupprecht        # Windows), so the thread numbers are non-deterministic.
6099451b44SJordan Rupprecht
6199451b44SJordan Rupprecht        # Run to the first breakpoint
6299451b44SJordan Rupprecht        self.runCmd("continue")
6399451b44SJordan Rupprecht
6499451b44SJordan Rupprecht        # The stop reason of the thread should be breakpoint.
6599451b44SJordan Rupprecht        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
6699451b44SJordan Rupprecht                    substrs=['stopped',
6799451b44SJordan Rupprecht                             '* thread #',
6899451b44SJordan Rupprecht                             'main',
6999451b44SJordan Rupprecht                             'stop reason = breakpoint'])
7099451b44SJordan Rupprecht
7199451b44SJordan Rupprecht        # Change a variable to escape the loop
7299451b44SJordan Rupprecht        self.runCmd("expression main_thread_continue = 1")
7399451b44SJordan Rupprecht
7499451b44SJordan Rupprecht        # Run to the second breakpoint
7599451b44SJordan Rupprecht        self.runCmd("continue")
7699451b44SJordan Rupprecht
7799451b44SJordan Rupprecht        # The stop reason of the thread should be breakpoint.
7899451b44SJordan Rupprecht        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
7999451b44SJordan Rupprecht                    substrs=['stopped',
8099451b44SJordan Rupprecht                             '* thread #',
8199451b44SJordan Rupprecht                             'thread_2_func',
8299451b44SJordan Rupprecht                             'stop reason = breakpoint'])
8399451b44SJordan Rupprecht
8499451b44SJordan Rupprecht        # Change a variable to escape the loop
8599451b44SJordan Rupprecht        self.runCmd("expression child_thread_continue = 1")
8699451b44SJordan Rupprecht
8799451b44SJordan Rupprecht        # Run to the third breakpoint
8899451b44SJordan Rupprecht        self.runCmd("continue")
8999451b44SJordan Rupprecht
9099451b44SJordan Rupprecht        # The stop reason of the thread should be breakpoint.
9199451b44SJordan Rupprecht        # Thread 3 may or may not have already exited.
9299451b44SJordan Rupprecht        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
9399451b44SJordan Rupprecht                    substrs=['stopped',
9499451b44SJordan Rupprecht                             '* thread #',
9599451b44SJordan Rupprecht                             'thread_1_func',
9699451b44SJordan Rupprecht                             'stop reason = breakpoint'])
9799451b44SJordan Rupprecht
9899451b44SJordan Rupprecht        # Run to completion
9999451b44SJordan Rupprecht        self.runCmd("continue")
10099451b44SJordan Rupprecht
10199451b44SJordan Rupprecht        # At this point, the inferior process should have exited.
1020ed758b2SDave Lee        self.assertEqual(
1030ed758b2SDave Lee            process.GetState(), lldb.eStateExited,
10499451b44SJordan Rupprecht            PROCESS_EXITED)
105