1"""
2Test number of threads.
3"""
4
5import os, time
6import unittest2
7import lldb
8from lldbtest import *
9import lldbutil
10
11class BreakpointAfterJoinTestCase(TestBase):
12
13    mydir = os.path.join("functionalities", "thread", "break_after_join")
14
15    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
16    @expectedFailureDarwin("llvm.org/pr15824") # thread states not properly maintained
17    @dsym_test
18    def test_with_dsym(self):
19        """Test breakpoint handling after a thread join."""
20        self.buildDsym(dictionary=self.getBuildFlags())
21        self.breakpoint_after_join_test()
22
23    @expectedFailureDarwin("llvm.org/pr15824") # thread states not properly maintained
24    @expectedFailureFreeBSD("llvm.org/pr16696") # threaded inferior not yet implemented on FreeBSD
25    @dwarf_test
26    def test_with_dwarf(self):
27        """Test breakpoint handling after a thread join."""
28        self.buildDwarf(dictionary=self.getBuildFlags())
29        self.breakpoint_after_join_test()
30
31    def setUp(self):
32        # Call super's setUp().
33        TestBase.setUp(self)
34        # Find the line number for our breakpoint.
35        self.breakpoint = line_number('main.cpp', '// Set breakpoint here')
36
37    def breakpoint_after_join_test(self):
38        """Test breakpoint handling after a thread join."""
39        exe = os.path.join(os.getcwd(), "a.out")
40        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
41
42        # This should create a breakpoint in the main thread.
43        lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.breakpoint, num_expected_locations=1)
44
45        # The breakpoint list should show 1 location.
46        self.expect("breakpoint list -f", "Breakpoint location shown correctly",
47            substrs = ["1: file = 'main.cpp', line = %d, locations = 1" % self.breakpoint])
48
49        # Run the program.
50        self.runCmd("run", RUN_SUCCEEDED)
51
52        # The stop reason of the thread should be breakpoint.
53        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
54            substrs = ['stopped',
55                       'stop reason = breakpoint'])
56
57        # Get the target process
58        target = self.dbg.GetSelectedTarget()
59        process = target.GetProcess()
60
61        # The exit probably occured during breakpoint handling, but it isn't
62        # guaranteed.  The main thing we're testing here is that the debugger
63        # handles this cleanly is some way.
64
65        # Get the number of threads
66        num_threads = process.GetNumThreads()
67
68        # Make sure we see six threads
69        self.assertTrue(num_threads == 6, 'Number of expected threads and actual threads do not match.')
70
71        # Get the thread objects
72        thread1 = process.GetThreadAtIndex(0)
73        thread2 = process.GetThreadAtIndex(1)
74        thread3 = process.GetThreadAtIndex(2)
75        thread4 = process.GetThreadAtIndex(3)
76        thread5 = process.GetThreadAtIndex(4)
77        thread6 = process.GetThreadAtIndex(5)
78
79        # Make sure all threads are stopped
80        self.assertTrue(thread1.IsStopped(), "Thread 1 didn't stop during breakpoint")
81        self.assertTrue(thread2.IsStopped(), "Thread 2 didn't stop during breakpoint")
82        self.assertTrue(thread3.IsStopped(), "Thread 3 didn't stop during breakpoint")
83        self.assertTrue(thread4.IsStopped(), "Thread 4 didn't stop during breakpoint")
84        self.assertTrue(thread5.IsStopped(), "Thread 5 didn't stop during breakpoint")
85        self.assertTrue(thread6.IsStopped(), "Thread 6 didn't stop during breakpoint")
86
87        # Run to completion
88        self.runCmd("continue")
89
90        # If the process hasn't exited, collect some information
91        if process.GetState() != lldb.eStateExited:
92            self.runCmd("thread list")
93            self.runCmd("process status")
94
95        # At this point, the inferior process should have exited.
96        self.assertTrue(process.GetState() == lldb.eStateExited, PROCESS_EXITED)
97
98if __name__ == '__main__':
99    import atexit
100    lldb.SBDebugger.Initialize()
101    atexit.register(lambda: lldb.SBDebugger.Terminate())
102    unittest2.main()
103