1"""
2Test thread creation after process attach.
3"""
4
5
6
7import lldb
8from lldbsuite.test.decorators import *
9from lldbsuite.test.lldbtest import *
10from lldbsuite.test import lldbutil
11
12
13class CreateAfterAttachTestCase(TestBase):
14
15    mydir = TestBase.compute_mydir(__file__)
16
17    def setUp(self):
18        # Call super's setUp().
19        TestBase.setUp(self)
20        # Find the line numbers for our breakpoints.
21        self.break_1 = line_number('main.cpp', '// Set first breakpoint here')
22        self.break_2 = line_number('main.cpp', '// Set second breakpoint here')
23        self.break_3 = line_number('main.cpp', '// Set third breakpoint here')
24
25    @skipIfFreeBSD  # Hangs.  May be the same as Linux issue llvm.org/pr16229 but
26    # not yet investigated.  Revisit once required functionality
27    # is implemented for FreeBSD.
28    # Occasionally hangs on Windows, may be same as other issues.
29    @skipIfWindows
30    @skipIfiOSSimulator
31    @expectedFailureNetBSD
32    def test_create_after_attach(self):
33        """Test thread creation after process attach."""
34        self.build(dictionary=self.getBuildFlags(use_cpp11=False))
35        exe = self.getBuildArtifact("a.out")
36
37        # Spawn a new process
38        popen = self.spawnSubprocess(exe)
39        pid = popen.pid
40
41        # Attach to the spawned process
42        self.runCmd("process attach -p " + str(pid))
43
44        target = self.dbg.GetSelectedTarget()
45
46        process = target.GetProcess()
47        self.assertTrue(process, PROCESS_IS_VALID)
48
49        # This should create a breakpoint in the main thread.
50        lldbutil.run_break_set_by_file_and_line(
51            self, "main.cpp", self.break_1, num_expected_locations=1)
52
53        # This should create a breakpoint in the second child thread.
54        lldbutil.run_break_set_by_file_and_line(
55            self, "main.cpp", self.break_2, num_expected_locations=1)
56
57        # This should create a breakpoint in the first child thread.
58        lldbutil.run_break_set_by_file_and_line(
59            self, "main.cpp", self.break_3, num_expected_locations=1)
60
61        # Note:  With std::thread, we cannot rely on particular thread numbers.  Using
62        # std::thread may cause the program to spin up a thread pool (and it does on
63        # Windows), so the thread numbers are non-deterministic.
64
65        # Run to the first breakpoint
66        self.runCmd("continue")
67
68        # The stop reason of the thread should be breakpoint.
69        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
70                    substrs=['stopped',
71                             '* thread #',
72                             'main',
73                             'stop reason = breakpoint'])
74
75        # Change a variable to escape the loop
76        self.runCmd("expression main_thread_continue = 1")
77
78        # Run to the second breakpoint
79        self.runCmd("continue")
80
81        # The stop reason of the thread should be breakpoint.
82        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
83                    substrs=['stopped',
84                             '* thread #',
85                             'thread_2_func',
86                             'stop reason = breakpoint'])
87
88        # Change a variable to escape the loop
89        self.runCmd("expression child_thread_continue = 1")
90
91        # Run to the third breakpoint
92        self.runCmd("continue")
93
94        # The stop reason of the thread should be breakpoint.
95        # Thread 3 may or may not have already exited.
96        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
97                    substrs=['stopped',
98                             '* thread #',
99                             'thread_1_func',
100                             'stop reason = breakpoint'])
101
102        # Run to completion
103        self.runCmd("continue")
104
105        # At this point, the inferior process should have exited.
106        self.assertTrue(
107            process.GetState() == lldb.eStateExited,
108            PROCESS_EXITED)
109