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