xref: /llvm-project/lldb/test/API/functionalities/thread/create_during_step/TestCreateDuringStep.py (revision 9c2468821ec51defd09c246fea4a47886fff8c01)
1"""
2Test number of threads.
3"""
4
5
6import lldb
7from lldbsuite.test.decorators import *
8from lldbsuite.test.lldbtest import *
9from lldbsuite.test import lldbutil
10
11
12class CreateDuringStepTestCase(TestBase):
13    @expectedFailureAll(
14        oslist=["linux"],
15        bugnumber="llvm.org/pr15824 thread states not properly maintained",
16    )
17    @expectedFailureAll(
18        oslist=lldbplatformutil.getDarwinOSTriples(),
19        bugnumber="llvm.org/pr15824 thread states not properly maintained, <rdar://problem/28557237>",
20    )
21    @expectedFailureAll(
22        oslist=["freebsd"],
23        bugnumber="llvm.org/pr18190 thread states not properly maintained",
24    )
25    @expectedFailureAll(
26        oslist=["windows"],
27        bugnumber="llvm.org/pr24668: Breakpoints not resolved correctly",
28    )
29    @expectedFailureNetBSD
30    def test_step_inst(self):
31        """Test thread creation during step-inst handling."""
32        self.build()
33        self.create_during_step_base(
34            "thread step-inst -m all-threads", "stop reason = instruction step"
35        )
36
37    @expectedFailureAll(
38        oslist=["linux"],
39        bugnumber="llvm.org/pr15824 thread states not properly maintained",
40    )
41    @expectedFailureAll(
42        oslist=lldbplatformutil.getDarwinOSTriples(),
43        bugnumber="llvm.org/pr15824 thread states not properly maintained, <rdar://problem/28557237>",
44    )
45    @expectedFailureAll(
46        oslist=["freebsd"],
47        bugnumber="llvm.org/pr18190 thread states not properly maintained",
48    )
49    @expectedFailureAll(
50        oslist=["windows"],
51        bugnumber="llvm.org/pr24668: Breakpoints not resolved correctly",
52    )
53    @expectedFailureNetBSD
54    def test_step_over(self):
55        """Test thread creation during step-over handling."""
56        self.build()
57        self.create_during_step_base(
58            "thread step-over -m all-threads", "stop reason = step over"
59        )
60
61    @expectedFailureAll(
62        oslist=["linux"],
63        bugnumber="llvm.org/pr15824 thread states not properly maintained",
64    )
65    @expectedFailureAll(
66        oslist=lldbplatformutil.getDarwinOSTriples(),
67        bugnumber="<rdar://problem/28574077>",
68    )
69    @expectedFailureAll(
70        oslist=["freebsd"],
71        bugnumber="llvm.org/pr18190 thread states not properly maintained",
72    )
73    @expectedFailureAll(
74        oslist=["windows"],
75        bugnumber="llvm.org/pr24668: Breakpoints not resolved correctly",
76    )
77    @expectedFailureNetBSD
78    def test_step_in(self):
79        """Test thread creation during step-in handling."""
80        self.build()
81        self.create_during_step_base(
82            "thread step-in -m all-threads", "stop reason = step in"
83        )
84
85    def setUp(self):
86        # Call super's setUp().
87        TestBase.setUp(self)
88        # Find the line numbers to break and continue.
89        self.breakpoint = line_number("main.cpp", "// Set breakpoint here")
90        self.continuepoint = line_number("main.cpp", "// Continue from here")
91
92    def create_during_step_base(self, step_cmd, step_stop_reason):
93        """Test thread creation while using step-in."""
94        exe = self.getBuildArtifact("a.out")
95        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
96
97        # Get the target process
98        target = self.dbg.GetSelectedTarget()
99
100        # This should create a breakpoint in the stepping thread.
101        self.bkpt = target.BreakpointCreateByLocation("main.cpp", self.breakpoint)
102
103        # Run the program.
104        self.runCmd("run", RUN_SUCCEEDED)
105
106        process = target.GetProcess()
107
108        # The stop reason of the thread should be breakpoint.
109        stepping_thread = lldbutil.get_one_thread_stopped_at_breakpoint(
110            process, self.bkpt
111        )
112        self.assertTrue(stepping_thread.IsValid(), "We stopped at the right breakpoint")
113
114        # Get the number of threads
115        num_threads = process.GetNumThreads()
116
117        # Make sure we see only two threads
118        self.assertEqual(
119            num_threads,
120            2,
121            "Number of expected threads and actual threads do not match.",
122        )
123
124        # Get the thread objects
125        thread1 = process.GetThreadAtIndex(0)
126        thread2 = process.GetThreadAtIndex(1)
127
128        current_line = self.breakpoint
129        # Keep stepping until we've reached our designated continue point
130        while current_line != self.continuepoint:
131            if stepping_thread != process.GetSelectedThread():
132                process.SetSelectedThread(stepping_thread)
133
134            self.runCmd(step_cmd)
135
136            frame = stepping_thread.GetFrameAtIndex(0)
137            current_line = frame.GetLineEntry().GetLine()
138
139            # Make sure we're still where we thought we were
140            self.assertGreaterEqual(
141                current_line,
142                self.breakpoint,
143                "Stepped to unexpected line, " + str(current_line),
144            )
145            self.assertLessEqual(
146                current_line,
147                self.continuepoint,
148                "Stepped to unexpected line, " + str(current_line),
149            )
150
151        # Update the number of threads
152        num_threads = process.GetNumThreads()
153
154        # Check to see that we increased the number of threads as expected
155        self.assertEqual(
156            num_threads,
157            3,
158            "Number of expected threads and actual threads do not match after thread exit.",
159        )
160
161        stop_reason = stepping_thread.GetStopReason()
162        self.assertStopReason(
163            stop_reason, lldb.eStopReasonPlanComplete, "Stopped for plan completion"
164        )
165
166        # Run to completion
167        self.runCmd("process continue")
168
169        # At this point, the inferior process should have exited.
170        self.assertEqual(process.GetState(), lldb.eStateExited, PROCESS_EXITED)
171