• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1"""
2Test number of threads.
3"""
4
5import os, time
6import unittest2
7import lldb
8from lldbtest import *
9import lldbutil
10
11class CreateDuringStepTestCase(TestBase):
12
13    mydir = os.path.join("functionalities", "thread", "create_during_step")
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_step_inst_with_dsym(self):
19        """Test thread creation during step-inst handling."""
20        self.buildDsym(dictionary=self.getBuildFlags())
21        self.create_during_step_inst_test()
22
23    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
24    @expectedFailureDarwin("llvm.org/pr15824") # thread states not properly maintained
25    @dsym_test
26    def test_step_over_with_dsym(self):
27        """Test thread creation during step-over handling."""
28        self.buildDsym(dictionary=self.getBuildFlags())
29        self.create_during_step_over_test()
30
31    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
32    @expectedFailureDarwin("llvm.org/pr15824") # thread states not properly maintained
33    @dsym_test
34    def test_step_in_with_dsym(self):
35        """Test thread creation during step-in handling."""
36        self.buildDsym(dictionary=self.getBuildFlags())
37        self.create_during_step_in_test()
38
39    @expectedFailureFreeBSD("llvm.org/pr16696") # threaded inferior not yet implemented on FreeBSD
40    @expectedFailureDarwin("llvm.org/pr15824") # thread states not properly maintained
41    @dwarf_test
42    def test_step_inst_with_dwarf(self):
43        """Test thread creation during step-inst handling."""
44        self.buildDwarf(dictionary=self.getBuildFlags())
45        self.create_during_step_inst_test()
46
47    @expectedFailureFreeBSD("llvm.org/pr16696") # threaded inferior not yet implemented on FreeBSD
48    @expectedFailureDarwin("llvm.org/pr15824") # thread states not properly maintained
49    @dwarf_test
50    def test_step_over_with_dwarf(self):
51        """Test thread creation during step-over handling."""
52        self.buildDwarf(dictionary=self.getBuildFlags())
53        self.create_during_step_over_test()
54
55    @expectedFailureFreeBSD("llvm.org/pr16696") # threaded inferior not yet implemented on FreeBSD
56    @expectedFailureDarwin("llvm.org/pr15824") # thread states not properly maintained
57    @dwarf_test
58    def test_step_in_with_dwarf(self):
59        """Test thread creation during step-in handling."""
60        self.buildDwarf(dictionary=self.getBuildFlags())
61        self.create_during_step_in_test()
62
63    def setUp(self):
64        # Call super's setUp().
65        TestBase.setUp(self)
66        # Find the line numbers to break and continue.
67        self.breakpoint = line_number('main.cpp', '// Set breakpoint here')
68        self.continuepoint = line_number('main.cpp', '// Continue from here')
69
70    def create_during_step_inst_test(self):
71        """Test thread creation while using step-inst."""
72        self.create_during_step_base("thread step-inst -m all-threads", 'stop reason = instruction step')
73
74    def create_during_step_over_test(self):
75        """Test thread creation while using step-over."""
76        self.create_during_step_base("thread step-over -m all-threads", 'stop reason = step over')
77
78    def create_during_step_in_test(self):
79        """Test thread creation while using step-in."""
80        self.create_during_step_base("thread step-in -m all-threads", 'stop reason = step in')
81
82    def create_during_step_base(self, step_cmd, step_stop_reason):
83        """Test thread creation while using step-in."""
84        exe = os.path.join(os.getcwd(), "a.out")
85        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
86
87        # This should create a breakpoint in the stepping thread.
88        lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.breakpoint, num_expected_locations=1)
89
90        # The breakpoint list should show 1 location.
91        self.expect("breakpoint list -f", "Breakpoint location shown correctly",
92            substrs = ["1: file = 'main.cpp', line = %d, locations = 1" % self.breakpoint])
93
94        # Run the program.
95        self.runCmd("run", RUN_SUCCEEDED)
96
97        # The stop reason of the thread should be breakpoint.
98        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
99            substrs = ['stopped',
100                       'stop reason = breakpoint'])
101
102        # Get the target process
103        target = self.dbg.GetSelectedTarget()
104        process = target.GetProcess()
105
106        # Get the number of threads
107        num_threads = process.GetNumThreads()
108
109        # Make sure we see only two threads
110        self.assertTrue(num_threads == 2, 'Number of expected threads and actual threads do not match.')
111
112        # Get the thread objects
113        thread1 = process.GetThreadAtIndex(0)
114        thread2 = process.GetThreadAtIndex(1)
115
116        # Make sure both threads are stopped
117        self.assertTrue(thread1.IsStopped(), "Thread 1 didn't stop during breakpoint")
118        self.assertTrue(thread2.IsStopped(), "Thread 2 didn't stop during breakpoint")
119
120        # Keep stepping until we've reached our designated continue point
121        stepping_thread = process.GetSelectedThread()
122        current_line = self.breakpoint
123        while current_line != self.continuepoint:
124            self.runCmd(step_cmd)
125
126            # The thread creation may change the selected thread.
127            # If it does, we just change it back here.
128            if stepping_thread != process.GetSelectedThread():
129                process.SetSelectedThread(stepping_thread)
130
131            frame = stepping_thread.GetFrameAtIndex(0)
132            current_line = frame.GetLineEntry().GetLine()
133
134            # Make sure we're still where we thought we were
135            self.assertTrue(current_line >= self.breakpoint, "Stepped to unexpected line, " + str(current_line))
136            self.assertTrue(current_line <= self.continuepoint, "Stepped to unexpected line, " + str(current_line))
137
138        # Update the number of threads
139        num_threads = process.GetNumThreads()
140
141        # Check to see that we increased the number of threads as expected
142        self.assertTrue(num_threads == 3, 'Number of expected threads and actual threads do not match after thread exit.')
143
144        self.expect("thread list", 'Process state is stopped due to step',
145                substrs = ['stopped',
146                           step_stop_reason])
147
148        # Run to completion
149        self.runCmd("process continue")
150
151        # At this point, the inferior process should have exited.
152        self.assertTrue(process.GetState() == lldb.eStateExited, PROCESS_EXITED)
153
154if __name__ == '__main__':
155    import atexit
156    lldb.SBDebugger.Initialize()
157    atexit.register(lambda: lldb.SBDebugger.Terminate())
158    unittest2.main()
159