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