| """ Test that stop-on-sharedlibrary-events works and cooperates with breakpoints. """ | |
| import lldb | |
| from lldbsuite.test.decorators import * | |
| from lldbsuite.test.lldbtest import * | |
| from lldbsuite.test import lldbutil | |
| @skipIfTargetDoesNotSupportSharedLibraries() | |
| class TestStopOnSharedlibraryEvents(TestBase): | |
| @skipIfRemote | |
| @skipIfWindows | |
| @no_debug_info_test | |
| def test_stopping_breakpoints(self): | |
| self.do_test() | |
| @skipIfRemote | |
| @skipIfWindows | |
| @no_debug_info_test | |
| def test_auto_continue(self): | |
| def auto_continue(bkpt): | |
| bkpt.auto_continue = True | |
| self.do_test(auto_continue) | |
| @skipIfRemote | |
| @skipIfWindows | |
| @no_debug_info_test | |
| def test_failing_condition(self): | |
| def condition(bkpt): | |
| bkpt.condition = "1 == 2" | |
| self.do_test(condition) | |
| @skipIfRemote | |
| @skipIfWindows | |
| @no_debug_info_test | |
| def test_continue_callback(self): | |
| def bkpt_callback(bkpt): | |
| bkpt.SetScriptCallbackBody("return False") | |
| self.do_test(bkpt_callback) | |
| def do_test(self, bkpt_modifier=None): | |
| self.build() | |
| main_spec = lldb.SBFileSpec("main.cpp") | |
| # Launch and stop before the dlopen call. | |
| target, process, thread, _ = lldbutil.run_to_source_breakpoint( | |
| self, | |
| "// Set a breakpoint here", | |
| main_spec, | |
| extra_images=["load_a", "load_b"], | |
| ) | |
| # Now turn on shared library events, continue and make sure we stop for the event. | |
| self.runCmd("settings set target.process.stop-on-sharedlibrary-events 1") | |
| self.addTearDownHook( | |
| lambda: self.runCmd( | |
| "settings set target.process.stop-on-sharedlibrary-events 0" | |
| ) | |
| ) | |
| # Since I don't know how to check that we are at the "right place" to stop for | |
| # shared library events, make an breakpoint after the load is done and | |
| # make sure we don't stop there: | |
| backstop_bkpt_1 = target.BreakpointCreateBySourceRegex( | |
| "Set another here - we should not hit this one", main_spec | |
| ) | |
| self.assertGreater( | |
| backstop_bkpt_1.GetNumLocations(), 0, "Set our second breakpoint" | |
| ) | |
| process.Continue() | |
| self.assertState( | |
| process.GetState(), lldb.eStateStopped, "We didn't stop for the load" | |
| ) | |
| self.assertEqual( | |
| backstop_bkpt_1.GetHitCount(), 0, "Hit our backstop breakpoint" | |
| ) | |
| # We should be stopped after the library is loaded, check that: | |
| found_it = False | |
| for module in target.modules: | |
| if module.file.basename.find("load_a") > -1: | |
| found_it = True | |
| break | |
| self.assertTrue(found_it, "Found the loaded module.") | |
| # Now capture the place where we stopped so we can set a breakpoint and make | |
| # sure the breakpoint there works correctly: | |
| load_address = process.GetSelectedThread().frames[0].addr | |
| load_bkpt = target.BreakpointCreateBySBAddress(load_address) | |
| self.assertGreater(load_bkpt.GetNumLocations(), 0, "Set the load breakpoint") | |
| backstop_bkpt_1.SetEnabled(False) | |
| backstop_bkpt_2 = target.BreakpointCreateBySourceRegex( | |
| "Set a third here - we should not hit this one", main_spec | |
| ) | |
| self.assertGreater( | |
| backstop_bkpt_2.GetNumLocations(), 0, "Set our third breakpoint" | |
| ) | |
| if bkpt_modifier is None: | |
| process.Continue() | |
| self.assertState( | |
| process.GetState(), lldb.eStateStopped, "We didn't stop for the load" | |
| ) | |
| self.assertEqual( | |
| backstop_bkpt_2.GetHitCount(), 0, "Hit our backstop breakpoint" | |
| ) | |
| self.assertStopReason( | |
| thread.stop_reason, | |
| lldb.eStopReasonBreakpoint, | |
| "We attributed the stop to the breakpoint", | |
| ) | |
| self.assertEqual( | |
| load_bkpt.GetHitCount(), 1, "We hit our breakpoint at the load address" | |
| ) | |
| else: | |
| bkpt_modifier(load_bkpt) | |
| process.Continue() | |
| self.assertState(process.GetState(), lldb.eStateStopped, "We didn't stop") | |
| self.assertTrue(thread.IsValid(), "Our thread was no longer valid.") | |
| self.assertStopReason( | |
| thread.stop_reason, | |
| lldb.eStopReasonBreakpoint, | |
| "We didn't hit some breakpoint", | |
| ) | |
| self.assertEqual( | |
| backstop_bkpt_2.GetHitCount(), 1, "We continued to the right breakpoint" | |
| ) |