1c0dbdc089884c1fe07568588558199824357eacaJohnny Chen"""
2c0dbdc089884c1fe07568588558199824357eacaJohnny ChenTest "print object" where another thread blocks the print object from making progress.
3c0dbdc089884c1fe07568588558199824357eacaJohnny Chen"""
4c0dbdc089884c1fe07568588558199824357eacaJohnny Chen
5c0dbdc089884c1fe07568588558199824357eacaJohnny Chenimport os, time
6c0dbdc089884c1fe07568588558199824357eacaJohnny Chenimport unittest2
7c0dbdc089884c1fe07568588558199824357eacaJohnny Chenimport lldb
8c0dbdc089884c1fe07568588558199824357eacaJohnny Chenfrom lldbtest import *
9c0dbdc089884c1fe07568588558199824357eacaJohnny Chen
10c0dbdc089884c1fe07568588558199824357eacaJohnny Chen@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
11c0dbdc089884c1fe07568588558199824357eacaJohnny Chenclass PrintObjTestCase(TestBase):
12c0dbdc089884c1fe07568588558199824357eacaJohnny Chen
13c0dbdc089884c1fe07568588558199824357eacaJohnny Chen    mydir = os.path.join("lang", "objc", "print-obj")
14c0dbdc089884c1fe07568588558199824357eacaJohnny Chen
1521b1984e161b0cadee331d32bfd721eccfdf4b1fJohnny Chen    @dsym_test
16c0dbdc089884c1fe07568588558199824357eacaJohnny Chen    def test_print_obj_with_dsym(self):
17c0dbdc089884c1fe07568588558199824357eacaJohnny Chen        """Test "print object" where another thread blocks the print object from making progress."""
18c0dbdc089884c1fe07568588558199824357eacaJohnny Chen        d = {'EXE': 'a.out'}
19c0dbdc089884c1fe07568588558199824357eacaJohnny Chen        self.buildDsym(dictionary=d)
20c0dbdc089884c1fe07568588558199824357eacaJohnny Chen        self.setTearDownCleanup(dictionary=d)
21c0dbdc089884c1fe07568588558199824357eacaJohnny Chen        self.print_obj('a.out')
22c0dbdc089884c1fe07568588558199824357eacaJohnny Chen
2321b1984e161b0cadee331d32bfd721eccfdf4b1fJohnny Chen    @dwarf_test
24c0dbdc089884c1fe07568588558199824357eacaJohnny Chen    def test_print_obj_with_dwarf(self):
25c0dbdc089884c1fe07568588558199824357eacaJohnny Chen        """Test "print object" where another thread blocks the print object from making progress."""
26c0dbdc089884c1fe07568588558199824357eacaJohnny Chen        d = {'EXE': 'b.out'}
27c0dbdc089884c1fe07568588558199824357eacaJohnny Chen        self.buildDwarf(dictionary=d)
28c0dbdc089884c1fe07568588558199824357eacaJohnny Chen        self.setTearDownCleanup(dictionary=d)
29c0dbdc089884c1fe07568588558199824357eacaJohnny Chen        self.print_obj('b.out')
30c0dbdc089884c1fe07568588558199824357eacaJohnny Chen
31c0dbdc089884c1fe07568588558199824357eacaJohnny Chen    def setUp(self):
32c0dbdc089884c1fe07568588558199824357eacaJohnny Chen        # Call super's setUp().
33c0dbdc089884c1fe07568588558199824357eacaJohnny Chen        TestBase.setUp(self)
34c0dbdc089884c1fe07568588558199824357eacaJohnny Chen        # My source program.
35c0dbdc089884c1fe07568588558199824357eacaJohnny Chen        self.source = "blocked.m"
36c0dbdc089884c1fe07568588558199824357eacaJohnny Chen        # Find the line numbers to break at.
37c0dbdc089884c1fe07568588558199824357eacaJohnny Chen        self.line = line_number(self.source, '// Set a breakpoint here.')
38c0dbdc089884c1fe07568588558199824357eacaJohnny Chen
39c0dbdc089884c1fe07568588558199824357eacaJohnny Chen    def print_obj(self, exe_name):
40c0dbdc089884c1fe07568588558199824357eacaJohnny Chen        """
41c0dbdc089884c1fe07568588558199824357eacaJohnny Chen        Test "print object" where another thread blocks the print object from making progress.
42c0dbdc089884c1fe07568588558199824357eacaJohnny Chen
43c0dbdc089884c1fe07568588558199824357eacaJohnny Chen        Set a breakpoint on the line in my_pthread_routine.  Then switch threads
44c0dbdc089884c1fe07568588558199824357eacaJohnny Chen        to the main thread, and do print the lock_me object.  Since that will
45c0dbdc089884c1fe07568588558199824357eacaJohnny Chen        try to get the lock already gotten by my_pthread_routime thread, it will
46c0dbdc089884c1fe07568588558199824357eacaJohnny Chen        have to switch to running all threads, and that should then succeed.
47c0dbdc089884c1fe07568588558199824357eacaJohnny Chen        """
48c0dbdc089884c1fe07568588558199824357eacaJohnny Chen        exe = os.path.join(os.getcwd(), exe_name)
49c0dbdc089884c1fe07568588558199824357eacaJohnny Chen
50c0dbdc089884c1fe07568588558199824357eacaJohnny Chen        target = self.dbg.CreateTarget(exe)
51c0dbdc089884c1fe07568588558199824357eacaJohnny Chen        self.assertTrue(target, VALID_TARGET)
52c0dbdc089884c1fe07568588558199824357eacaJohnny Chen
53c0dbdc089884c1fe07568588558199824357eacaJohnny Chen        breakpoint = target.BreakpointCreateByLocation(self.source, self.line)
54c0dbdc089884c1fe07568588558199824357eacaJohnny Chen        self.assertTrue(breakpoint, VALID_BREAKPOINT)
55c0dbdc089884c1fe07568588558199824357eacaJohnny Chen        self.runCmd("breakpoint list")
56c0dbdc089884c1fe07568588558199824357eacaJohnny Chen
57c0dbdc089884c1fe07568588558199824357eacaJohnny Chen        # Launch the process, and do not stop at the entry point.
58c0dbdc089884c1fe07568588558199824357eacaJohnny Chen        process = target.LaunchSimple(None, None, os.getcwd())
59c0dbdc089884c1fe07568588558199824357eacaJohnny Chen
60c0dbdc089884c1fe07568588558199824357eacaJohnny Chen        self.runCmd("thread backtrace all")
61c0dbdc089884c1fe07568588558199824357eacaJohnny Chen
62c0dbdc089884c1fe07568588558199824357eacaJohnny Chen        # Let's get the current stopped thread.  We'd like to switch to the
63c0dbdc089884c1fe07568588558199824357eacaJohnny Chen        # other thread to issue our 'po lock_me' command.
64c0dbdc089884c1fe07568588558199824357eacaJohnny Chen        import lldbutil
65c0dbdc089884c1fe07568588558199824357eacaJohnny Chen        this_thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint)
66c0dbdc089884c1fe07568588558199824357eacaJohnny Chen        self.assertTrue(this_thread)
67c0dbdc089884c1fe07568588558199824357eacaJohnny Chen
68c0dbdc089884c1fe07568588558199824357eacaJohnny Chen        # Find the other thread.  The iteration protocol of SBProcess and the
6933a1c57c86faf168064ca0157a2416aad79a2127Johnny Chen        # rich comparison methods (__eq__/__ne__) of SBThread come in handy.
70c0dbdc089884c1fe07568588558199824357eacaJohnny Chen        other_thread = None
71c0dbdc089884c1fe07568588558199824357eacaJohnny Chen        for t in process:
72c0dbdc089884c1fe07568588558199824357eacaJohnny Chen            if t != this_thread:
73c0dbdc089884c1fe07568588558199824357eacaJohnny Chen                other_thread = t
74c0dbdc089884c1fe07568588558199824357eacaJohnny Chen                break
75c0dbdc089884c1fe07568588558199824357eacaJohnny Chen
76c0dbdc089884c1fe07568588558199824357eacaJohnny Chen        # Set the other thread as the selected thread to issue our 'po' command.other
77c0dbdc089884c1fe07568588558199824357eacaJohnny Chen        self.assertTrue(other_thread)
78c0dbdc089884c1fe07568588558199824357eacaJohnny Chen        process.SetSelectedThread(other_thread)
7933a1c57c86faf168064ca0157a2416aad79a2127Johnny Chen        if self.TraceOn():
8033a1c57c86faf168064ca0157a2416aad79a2127Johnny Chen            print "selected thread:" + lldbutil.get_description(other_thread)
81c0dbdc089884c1fe07568588558199824357eacaJohnny Chen        self.runCmd("thread backtrace")
82c0dbdc089884c1fe07568588558199824357eacaJohnny Chen
83c0dbdc089884c1fe07568588558199824357eacaJohnny Chen        # We want to traverse the frame to the one corresponding to blocked.m to
84c0dbdc089884c1fe07568588558199824357eacaJohnny Chen        # issue our 'po lock_me' command.
85c0dbdc089884c1fe07568588558199824357eacaJohnny Chen
86c0dbdc089884c1fe07568588558199824357eacaJohnny Chen        depth = other_thread.GetNumFrames()
87c0dbdc089884c1fe07568588558199824357eacaJohnny Chen        for i in range(depth):
88c0dbdc089884c1fe07568588558199824357eacaJohnny Chen            frame = other_thread.GetFrameAtIndex(i)
89c0dbdc089884c1fe07568588558199824357eacaJohnny Chen            name = frame.GetFunctionName()
90c0dbdc089884c1fe07568588558199824357eacaJohnny Chen            if name == 'main':
91c0dbdc089884c1fe07568588558199824357eacaJohnny Chen                other_thread.SetSelectedFrame(i)
92c0dbdc089884c1fe07568588558199824357eacaJohnny Chen                if self.TraceOn():
9333a1c57c86faf168064ca0157a2416aad79a2127Johnny Chen                    print "selected frame:" + lldbutil.get_description(frame)
94c0dbdc089884c1fe07568588558199824357eacaJohnny Chen                break
95c0dbdc089884c1fe07568588558199824357eacaJohnny Chen
96c0dbdc089884c1fe07568588558199824357eacaJohnny Chen        self.expect("po lock_me", OBJECT_PRINTED_CORRECTLY,
9712213586035d4af8f200e5c8ab4642728f8c5f30Enrico Granata            substrs = ['I am pretty special.'])
98c0dbdc089884c1fe07568588558199824357eacaJohnny Chen
99c0dbdc089884c1fe07568588558199824357eacaJohnny Chen
100c0dbdc089884c1fe07568588558199824357eacaJohnny Chenif __name__ == '__main__':
101c0dbdc089884c1fe07568588558199824357eacaJohnny Chen    import atexit
102c0dbdc089884c1fe07568588558199824357eacaJohnny Chen    lldb.SBDebugger.Initialize()
103c0dbdc089884c1fe07568588558199824357eacaJohnny Chen    atexit.register(lambda: lldb.SBDebugger.Terminate())
104c0dbdc089884c1fe07568588558199824357eacaJohnny Chen    unittest2.main()
105