d35bd45fe8056b09c12fd483dbdff54987cfed83
[openbsd] /
1 """
2 Test number of threads.
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 ExitDuringStepTestCase(TestBase):
14
15     mydir = TestBase.compute_mydir(__file__)
16
17     @skipIfFreeBSD  # llvm.org/pr21411: test is hanging
18     @skipIfWindows # This is flakey on Windows: llvm.org/pr38373
19     def test(self):
20         """Test thread exit during step handling."""
21         self.build(dictionary=self.getBuildFlags())
22         self.exit_during_step_base(
23             "thread step-inst -m all-threads",
24             'stop reason = instruction step',
25             True)
26
27     @skipIfFreeBSD  # llvm.org/pr21411: test is hanging
28     @skipIfWindows # This is flakey on Windows: llvm.org/pr38373
29     def test_step_over(self):
30         """Test thread exit during step-over handling."""
31         self.build(dictionary=self.getBuildFlags())
32         self.exit_during_step_base(
33             "thread step-over -m all-threads",
34             'stop reason = step over',
35             False)
36
37     @skipIfFreeBSD  # llvm.org/pr21411: test is hanging
38     @skipIfWindows # This is flakey on Windows: llvm.org/pr38373
39     def test_step_in(self):
40         """Test thread exit during step-in handling."""
41         self.build(dictionary=self.getBuildFlags())
42         self.exit_during_step_base(
43             "thread step-in -m all-threads",
44             'stop reason = step in',
45             False)
46
47     def setUp(self):
48         # Call super's setUp().
49         TestBase.setUp(self)
50         # Find the line numbers to break and continue.
51         self.breakpoint = line_number('main.cpp', '// Set breakpoint here')
52         self.continuepoint = line_number('main.cpp', '// Continue from here')
53
54     def exit_during_step_base(self, step_cmd, step_stop_reason, by_instruction):
55         """Test thread exit during step handling."""
56         exe = self.getBuildArtifact("a.out")
57         self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
58
59         # This should create a breakpoint in the main thread.
60         self.bp_num = lldbutil.run_break_set_by_file_and_line(
61             self, "main.cpp", self.breakpoint, num_expected_locations=1)
62
63         # The breakpoint list should show 1 location.
64         self.expect(
65             "breakpoint list -f",
66             "Breakpoint location shown correctly",
67             substrs=[
68                 "1: file = 'main.cpp', line = %d, exact_match = 0, locations = 1" %
69                 self.breakpoint])
70
71         # Run the program.
72         self.runCmd("run", RUN_SUCCEEDED)
73
74         # The stop reason of the thread should be breakpoint.
75         self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
76                     substrs=['stopped',
77                              'stop reason = breakpoint'])
78
79         # Get the target process
80         target = self.dbg.GetSelectedTarget()
81         process = target.GetProcess()
82
83         num_threads = process.GetNumThreads()
84         # Make sure we see all three threads
85         self.assertGreaterEqual(
86             num_threads,
87             3,
88             'Number of expected threads and actual threads do not match.')
89
90         stepping_thread = lldbutil.get_one_thread_stopped_at_breakpoint_id(
91             process, self.bp_num)
92         self.assertIsNotNone(
93             stepping_thread,
94             "Could not find a thread stopped at the breakpoint")
95
96         current_line = self.breakpoint
97         stepping_frame = stepping_thread.GetFrameAtIndex(0)
98         self.assertEqual(
99             current_line,
100             stepping_frame.GetLineEntry().GetLine(),
101             "Starting line for stepping doesn't match breakpoint line.")
102
103         # Keep stepping until we've reached our designated continue point
104         while current_line != self.continuepoint:
105             # Since we're using the command interpreter to issue the thread command
106             # (on the selected thread) we need to ensure the selected thread is the
107             # stepping thread.
108             if stepping_thread != process.GetSelectedThread():
109                 process.SetSelectedThread(stepping_thread)
110
111             self.runCmd(step_cmd)
112
113             frame = stepping_thread.GetFrameAtIndex(0)
114
115             current_line = frame.GetLineEntry().GetLine()
116
117             if by_instruction and current_line == 0:
118                 continue
119
120             self.assertGreaterEqual(
121                 current_line,
122                 self.breakpoint,
123                 "Stepped to unexpected line, " +
124                 str(current_line))
125             self.assertLessEqual(
126                 current_line,
127                 self.continuepoint,
128                 "Stepped to unexpected line, " +
129                 str(current_line))
130
131         self.runCmd("thread list")
132
133         # Update the number of threads
134         new_num_threads = process.GetNumThreads()
135
136         # Check to see that we reduced the number of threads as expected
137         self.assertEqual(
138             new_num_threads,
139             num_threads - 1,
140             'Number of threads did not reduce by 1 after thread exit.')
141
142         self.expect("thread list", 'Process state is stopped due to step',
143                     substrs=['stopped',
144                              step_stop_reason])
145
146         # Run to completion
147         self.runCmd("continue")
148
149         # At this point, the inferior process should have exited.
150         self.assertEqual(process.GetState(), lldb.eStateExited, PROCESS_EXITED)