1"""
2Test that we obey thread conditioned breakpoints.
3"""
4
5
6
7import lldb
8from lldbsuite.test.decorators import *
9from lldbsuite.test.lldbtest import *
10from lldbsuite.test import lldbutil
11
12def set_thread_id(thread, breakpoint):
13    id = thread.id
14    breakpoint.SetThreadID(id)
15
16def set_thread_name(thread, breakpoint):
17    breakpoint.SetThreadName("main-thread")
18
19class ThreadSpecificBreakTestCase(TestBase):
20
21    mydir = TestBase.compute_mydir(__file__)
22    NO_DEBUG_INFO_TESTCASE = True
23
24    @add_test_categories(['pyapi'])
25
26    @expectedFailureAll(oslist=['ios', 'watchos', 'tvos', 'bridgeos'], archs=['armv7', 'armv7k'], bugnumber='rdar://problem/34563920') # armv7 ios problem - breakpoint with tid qualifier isn't working
27    def test_thread_id(self):
28        self.do_test(set_thread_id)
29
30    @skipUnlessDarwin
31    @expectedFailureAll(oslist=['ios', 'watchos', 'tvos', 'bridgeos'], archs=['armv7', 'armv7k'], bugnumber='rdar://problem/34563920') # armv7 ios problem - breakpoint with tid qualifier isn't working
32    def test_thread_name(self):
33        self.do_test(set_thread_name)
34
35    def do_test(self, setter_method):
36        """Test that we obey thread conditioned breakpoints."""
37        self.build()
38        main_source_spec = lldb.SBFileSpec("main.cpp")
39        (target, process, main_thread, main_breakpoint) = lldbutil.run_to_source_breakpoint(self,
40                "Set main breakpoint here", main_source_spec)
41
42        thread_breakpoint = target.BreakpointCreateBySourceRegex(
43            "Set thread-specific breakpoint here", main_source_spec)
44        self.assertGreater(
45            thread_breakpoint.GetNumLocations(),
46            0,
47            "thread breakpoint has no locations associated with it.")
48
49        # Set the thread-specific breakpoint to stop only on the main thread
50        # before the secondary thread has a chance to execute it.  The main
51        # thread joins the secondary thread, and then the main thread will
52        # execute the code at the breakpoint.  If the thread-specific
53        # breakpoint works, the next stop will be on the main thread.
54        setter_method(main_thread, thread_breakpoint)
55
56        process.Continue()
57        next_stop_state = process.GetState()
58        self.assertEqual(
59            next_stop_state,
60            lldb.eStateStopped,
61            "We should have stopped at the thread breakpoint.")
62        stopped_threads = lldbutil.get_threads_stopped_at_breakpoint(
63            process, thread_breakpoint)
64        self.assertEqual(
65            len(stopped_threads),
66            1,
67            "thread breakpoint stopped at unexpected number of threads")
68        self.assertEqual(
69            stopped_threads[0].GetThreadID(),
70            main_thread.GetThreadID(),
71            "thread breakpoint stopped at the wrong thread")
72