xref: /llvm-project/lldb/test/API/functionalities/thread/multi_break/TestMultipleBreakpoints.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 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.assertGreaterEqual(
64            num_threads,
65            3,
66            "Number of expected threads and actual threads do not match.",
67        )
68
69        # Get the thread objects
70        thread1 = process.GetThreadAtIndex(0)
71        thread2 = process.GetThreadAtIndex(1)
72        thread3 = process.GetThreadAtIndex(2)
73
74        # Make sure both threads are stopped
75        self.assertTrue(
76            thread1.IsStopped(), "Primary thread didn't stop during breakpoint"
77        )
78        self.assertTrue(
79            thread2.IsStopped(), "Secondary thread didn't stop during breakpoint"
80        )
81        self.assertTrue(
82            thread3.IsStopped(), "Tertiary thread didn't stop during breakpoint"
83        )
84
85        # Delete the first breakpoint then continue
86        self.runCmd("breakpoint delete 1")
87
88        # Run to completion
89        self.runCmd("continue")
90
91        # At this point, the inferior process should have exited.
92        self.assertEqual(process.GetState(), lldb.eStateExited, PROCESS_EXITED)
93