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