1""" Test that stop-on-sharedlibrary-events works and cooperates with breakpoints. """ 2import lldb 3from lldbsuite.test.decorators import * 4from lldbsuite.test.lldbtest import * 5from lldbsuite.test import lldbutil 6 7 8class TestStopOnSharedlibraryEvents(TestBase): 9 @skipIfRemote 10 @skipIfWindows 11 @no_debug_info_test 12 def test_stopping_breakpoints(self): 13 self.do_test() 14 15 @skipIfRemote 16 @skipIfWindows 17 @no_debug_info_test 18 def test_auto_continue(self): 19 def auto_continue(bkpt): 20 bkpt.SetAutoContinue(True) 21 22 self.do_test(auto_continue) 23 24 @skipIfRemote 25 @skipIfWindows 26 @no_debug_info_test 27 def test_failing_condition(self): 28 def condition(bkpt): 29 bkpt.SetCondition("1 == 2") 30 31 self.do_test(condition) 32 33 @skipIfRemote 34 @skipIfWindows 35 @no_debug_info_test 36 def test_continue_callback(self): 37 def bkpt_callback(bkpt): 38 bkpt.SetScriptCallbackBody("return False") 39 40 self.do_test(bkpt_callback) 41 42 def do_test(self, bkpt_modifier=None): 43 self.build() 44 main_spec = lldb.SBFileSpec("main.cpp") 45 # Launch and stop before the dlopen call. 46 target, process, thread, _ = lldbutil.run_to_source_breakpoint( 47 self, 48 "// Set a breakpoint here", 49 main_spec, 50 extra_images=["load_a", "load_b"], 51 ) 52 53 # Now turn on shared library events, continue and make sure we stop for the event. 54 self.runCmd("settings set target.process.stop-on-sharedlibrary-events 1") 55 self.addTearDownHook( 56 lambda: self.runCmd( 57 "settings set target.process.stop-on-sharedlibrary-events 0" 58 ) 59 ) 60 61 # Since I don't know how to check that we are at the "right place" to stop for 62 # shared library events, make an breakpoint after the load is done and 63 # make sure we don't stop there: 64 backstop_bkpt_1 = target.BreakpointCreateBySourceRegex( 65 "Set another here - we should not hit this one", main_spec 66 ) 67 self.assertGreater( 68 backstop_bkpt_1.GetNumLocations(), 0, "Set our second breakpoint" 69 ) 70 71 process.Continue() 72 self.assertState( 73 process.GetState(), lldb.eStateStopped, "We didn't stop for the load" 74 ) 75 self.assertEqual( 76 backstop_bkpt_1.GetHitCount(), 0, "Hit our backstop breakpoint" 77 ) 78 79 # We should be stopped after the library is loaded, check that: 80 found_it = False 81 for module in target.modules: 82 if module.file.basename.find("load_a") > -1: 83 found_it = True 84 break 85 self.assertTrue(found_it, "Found the loaded module.") 86 87 # Now capture the place where we stopped so we can set a breakpoint and make 88 # sure the breakpoint there works correctly: 89 load_address = process.GetSelectedThread().frames[0].addr 90 load_bkpt = target.BreakpointCreateBySBAddress(load_address) 91 self.assertGreater(load_bkpt.GetNumLocations(), 0, "Set the load breakpoint") 92 93 backstop_bkpt_1.SetEnabled(False) 94 95 backstop_bkpt_2 = target.BreakpointCreateBySourceRegex( 96 "Set a third here - we should not hit this one", main_spec 97 ) 98 self.assertGreater( 99 backstop_bkpt_2.GetNumLocations(), 0, "Set our third breakpoint" 100 ) 101 102 if bkpt_modifier is None: 103 process.Continue() 104 self.assertState( 105 process.GetState(), lldb.eStateStopped, "We didn't stop for the load" 106 ) 107 self.assertEqual( 108 backstop_bkpt_2.GetHitCount(), 0, "Hit our backstop breakpoint" 109 ) 110 self.assertStopReason( 111 thread.stop_reason, 112 lldb.eStopReasonBreakpoint, 113 "We attributed the stop to the breakpoint", 114 ) 115 self.assertEqual( 116 load_bkpt.GetHitCount(), 1, "We hit our breakpoint at the load address" 117 ) 118 else: 119 bkpt_modifier(load_bkpt) 120 process.Continue() 121 self.assertState(process.GetState(), lldb.eStateStopped, "We didn't stop") 122 self.assertTrue(thread.IsValid(), "Our thread was no longer valid.") 123 self.assertStopReason( 124 thread.stop_reason, 125 lldb.eStopReasonBreakpoint, 126 "We didn't hit some breakpoint", 127 ) 128 self.assertEqual( 129 backstop_bkpt_2.GetHitCount(), 1, "We continued to the right breakpoint" 130 ) 131