1""" 2Test "print object" where another thread blocks the print object from making progress. 3""" 4 5from __future__ import print_function 6 7 8import lldb 9from lldbsuite.test.decorators import * 10from lldbsuite.test.lldbtest import * 11from lldbsuite.test import lldbutil 12 13 14@skipUnlessDarwin 15class PrintObjTestCase(TestBase): 16 17 mydir = TestBase.compute_mydir(__file__) 18 19 def setUp(self): 20 # Call super's setUp(). 21 TestBase.setUp(self) 22 # My source program. 23 self.source = "blocked.m" 24 # Find the line numbers to break at. 25 self.line = line_number(self.source, '// Set a breakpoint here.') 26 27 @skipIfReproducer # FIXME: Unexpected packet during (active) replay 28 def test_print_obj(self): 29 """ 30 Test "print object" where another thread blocks the print object from making progress. 31 32 Set a breakpoint on the line in my_pthread_routine. Then switch threads 33 to the main thread, and do print the lock_me object. Since that will 34 try to get the lock already gotten by my_pthread_routime thread, it will 35 have to switch to running all threads, and that should then succeed. 36 """ 37 d = {'EXE': 'b.out'} 38 self.build(dictionary=d) 39 self.setTearDownCleanup(dictionary=d) 40 exe = self.getBuildArtifact('b.out') 41 42 target = self.dbg.CreateTarget(exe) 43 self.assertTrue(target, VALID_TARGET) 44 45 breakpoint = target.BreakpointCreateByLocation(self.source, self.line) 46 self.assertTrue(breakpoint, VALID_BREAKPOINT) 47 self.runCmd("breakpoint list") 48 49 # Launch the process, and do not stop at the entry point. 50 process = target.LaunchSimple( 51 None, None, self.get_process_working_directory()) 52 53 self.runCmd("thread backtrace all") 54 55 # Let's get the current stopped thread. We'd like to switch to the 56 # other thread to issue our 'po lock_me' command. 57 import lldbsuite.test.lldbutil as lldbutil 58 this_thread = lldbutil.get_stopped_thread( 59 process, lldb.eStopReasonBreakpoint) 60 self.assertTrue(this_thread) 61 62 # Find the other thread. The iteration protocol of SBProcess and the 63 # rich comparison methods (__eq__/__ne__) of SBThread come in handy. 64 other_thread = None 65 for t in process: 66 if t != this_thread: 67 other_thread = t 68 break 69 70 # Set the other thread as the selected thread to issue our 'po' 71 # command.other 72 self.assertTrue(other_thread) 73 process.SetSelectedThread(other_thread) 74 if self.TraceOn(): 75 print("selected thread:" + lldbutil.get_description(other_thread)) 76 self.runCmd("thread backtrace") 77 78 # We want to traverse the frame to the one corresponding to blocked.m to 79 # issue our 'po lock_me' command. 80 81 depth = other_thread.GetNumFrames() 82 for i in range(depth): 83 frame = other_thread.GetFrameAtIndex(i) 84 name = frame.GetFunctionName() 85 if name == 'main': 86 other_thread.SetSelectedFrame(i) 87 if self.TraceOn(): 88 print("selected frame:" + lldbutil.get_description(frame)) 89 break 90 91 self.expect("po lock_me", OBJECT_PRINTED_CORRECTLY, 92 substrs=['I am pretty special.']) 93