1"""
2Test that suspended threads do not affect should-stop decisions.
3"""
4
5import lldb
6from lldbsuite.test.decorators import *
7from lldbsuite.test.lldbtest import *
8import lldbsuite.test.lldbutil as lldbutil
9
10
11class IgnoreSuspendedThreadTestCase(TestBase):
12
13    mydir = TestBase.compute_mydir(__file__)
14    NO_DEBUG_INFO_TESTCASE = True
15
16    def setUp(self):
17        #Call super's setUp().
18        TestBase.setUp(self)
19        #Find the line numbers for our breakpoints.
20        self.break_1 = line_number('main.cpp', '// Set first breakpoint here')
21        self.break_2 = line_number('main.cpp', '// Set second breakpoint here')
22        self.break_3 = line_number('main.cpp', '// Set third breakpoint here')
23
24    def printThreadsStoppedByBreakpoint(self, process):
25        stopped_threads = \
26            lldbutil.get_stopped_threads(process, lldb.eStopReasonBreakpoint)
27        for thread in stopped_threads:
28            break_id = thread.GetStopReasonDataAtIndex(0)
29            print('Thread ' + str(thread.GetThreadID()) + \
30                    ' stopped at breakpoint ' + str(break_id))
31
32    def test(self):
33        self.build()
34        target  = lldbutil.run_to_breakpoint_make_target(self)
35
36        #This should create a breakpoint with 1 location.
37        bp1_id = \
38            lldbutil.run_break_set_by_file_and_line(self,
39                                                    "main.cpp",
40                                                    self.break_1,
41                                                    num_expected_locations=1)
42
43        bp2_id = \
44            lldbutil.run_break_set_by_file_and_line(self,
45                                                    "main.cpp",
46                                                    self.break_2,
47                                                    num_expected_locations=1)
48
49        bp3_id = \
50            lldbutil.run_break_set_by_file_and_line(self,
51                                                    "main.cpp",
52                                                    self.break_3,
53                                                    num_expected_locations=1)
54
55        #Run the program.
56        self.runCmd("run", RUN_SUCCEEDED)
57        #Get the target process
58        process = target.GetProcess()
59
60        if self.TraceOn():
61            print('First stop:')
62            self.printThreadsStoppedByBreakpoint(process)
63
64        thread_to_suspend = \
65            lldbutil.get_one_thread_stopped_at_breakpoint_id(process,
66                                                                bp1_id)
67        self.assertIsNotNone(thread_to_suspend, "Should hit breakpoint 1")
68        thread_to_suspend.Suspend()
69
70        #Do not stop at bp2 and autocontinue to bp3
71        target.FindBreakpointByID(bp2_id).SetAutoContinue(True)
72
73        #Run to the third breakpoint
74        self.runCmd("continue")
75
76        if self.TraceOn():
77            print('Second stop:')
78            self.printThreadsStoppedByBreakpoint(process)
79
80        stopped_thread = \
81            lldbutil.get_one_thread_stopped_at_breakpoint_id(process,
82                                                                bp3_id)
83        self.assertIsNotNone(stopped_thread,
84                             "Should hit breakpoint 3")
85
86        thread_to_suspend.Resume()
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(),
93                            lldb.eStateExited,
94                                PROCESS_EXITED)
95