xref: /llvm-project/lldb/test/API/functionalities/thread/multi_break/TestMultipleBreakpoints.py (revision 2238dcc39358353cac21df75c3c3286ab20b8f53)
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 MultipleBreakpointTestCase(TestBase):
13    def setUp(self):
14        # Call super's setUp().
15        TestBase.setUp(self)
16        # Find the line number for our breakpoint.
17        self.breakpoint = line_number("main.cpp", "// Set breakpoint here")
18
19    @expectedFailureAll(
20        oslist=["linux"],
21        bugnumber="llvm.org/pr15824 thread states not properly maintained",
22    )
23    @expectedFailureAll(
24        oslist=lldbplatformutil.getDarwinOSTriples(),
25        bugnumber="llvm.org/pr15824 thread states not properly maintained and <rdar://problem/28557237>",
26    )
27    @expectedFailureAll(
28        oslist=["freebsd"],
29        bugnumber="llvm.org/pr18190 thread states not properly maintained",
30    )
31    @skipIfWindows  # This is flakey on Windows: llvm.org/pr24668, llvm.org/pr38373
32    @expectedFailureNetBSD
33    def test(self):
34        """Test simultaneous breakpoints in multiple threads."""
35        self.build()
36        exe = self.getBuildArtifact("a.out")
37        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
38
39        # This should create a breakpoint in the main thread.
40        lldbutil.run_break_set_by_file_and_line(
41            self, "main.cpp", self.breakpoint, num_expected_locations=1
42        )
43
44        # Run the program.
45        self.runCmd("run", RUN_SUCCEEDED)
46
47        # The stop reason of the thread should be breakpoint.
48        # The breakpoint may be hit in either thread 2 or thread 3.
49        self.expect(
50            "thread list",
51            STOPPED_DUE_TO_BREAKPOINT,
52            substrs=["stopped", "stop reason = breakpoint"],
53        )
54
55        # Get the target process
56        target = self.dbg.GetSelectedTarget()
57        process = target.GetProcess()
58
59        # Get the number of threads
60        num_threads = process.GetNumThreads()
61
62        # Make sure we see all three threads
63        self.assertTrue(
64            num_threads >= 3,
65            "Number of expected threads and actual threads do not match.",
66        )
67
68        # Get the thread objects
69        thread1 = process.GetThreadAtIndex(0)
70        thread2 = process.GetThreadAtIndex(1)
71        thread3 = process.GetThreadAtIndex(2)
72
73        # Make sure both threads are stopped
74        self.assertTrue(
75            thread1.IsStopped(), "Primary thread didn't stop during breakpoint"
76        )
77        self.assertTrue(
78            thread2.IsStopped(), "Secondary thread didn't stop during breakpoint"
79        )
80        self.assertTrue(
81            thread3.IsStopped(), "Tertiary thread didn't stop during breakpoint"
82        )
83
84        # Delete the first breakpoint then continue
85        self.runCmd("breakpoint delete 1")
86
87        # Run to completion
88        self.runCmd("continue")
89
90        # At this point, the inferior process should have exited.
91        self.assertEqual(process.GetState(), lldb.eStateExited, PROCESS_EXITED)
92