xref: /llvm-project/lldb/test/API/functionalities/thread/break_after_join/TestBreakAfterJoin.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 BreakpointAfterJoinTestCase(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    @expectedFailureNetBSD
32    def test(self):
33        """Test breakpoint handling after a thread join."""
34        self.build()
35
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        # The breakpoint list should show 1 location.
45        self.expect(
46            "breakpoint list -f",
47            "Breakpoint location shown correctly",
48            substrs=[
49                "1: file = 'main.cpp', line = %d, exact_match = 0, locations = 1"
50                % self.breakpoint
51            ],
52        )
53
54        # Run the program.
55        self.runCmd("run", RUN_SUCCEEDED)
56
57        # The stop reason of the thread should be breakpoint.
58        self.expect(
59            "thread list",
60            STOPPED_DUE_TO_BREAKPOINT,
61            substrs=["stopped", "stop reason = breakpoint"],
62        )
63
64        # Get the target process
65        target = self.dbg.GetSelectedTarget()
66        process = target.GetProcess()
67
68        # The exit probably occurred during breakpoint handling, but it isn't
69        # guaranteed.  The main thing we're testing here is that the debugger
70        # handles this cleanly is some way.
71
72        # Get the number of threads
73        num_threads = process.GetNumThreads()
74
75        # Make sure we see at least six threads
76        self.assertGreaterEqual(
77            num_threads,
78            6,
79            "Number of expected threads and actual threads do not match.",
80        )
81
82        # Make sure all threads are stopped
83        for i in range(0, num_threads):
84            self.assertTrue(
85                process.GetThreadAtIndex(i).IsStopped(),
86                "Thread {0} didn't stop during breakpoint.".format(i),
87            )
88
89        # Run to completion
90        self.runCmd("continue")
91
92        # If the process hasn't exited, collect some information
93        if process.GetState() != lldb.eStateExited:
94            self.runCmd("thread list")
95            self.runCmd("process status")
96
97        # At this point, the inferior process should have exited.
98        self.assertEqual(process.GetState(), lldb.eStateExited, PROCESS_EXITED)
99