| """ |
| Test stop hook functionality |
| """ |
| |
| |
| |
| import lldb |
| import lldbsuite.test.lldbutil as lldbutil |
| from lldbsuite.test.lldbtest import * |
| |
| |
| class TestStopHooks(TestBase): |
| |
| mydir = TestBase.compute_mydir(__file__) |
| |
| # If your test case doesn't stress debug info, the |
| # set this to true. That way it won't be run once for |
| # each debug info format. |
| NO_DEBUG_INFO_TESTCASE = True |
| |
| def setUp(self): |
| TestBase.setUp(self) |
| self.build() |
| self.main_source_file = lldb.SBFileSpec("main.c") |
| full_path = os.path.join(self.getSourceDir(), "main.c") |
| self.main_start_line = line_number(full_path, "main()") |
| |
| def test_stop_hooks_step_out(self): |
| """Test that stop hooks fire on step-out.""" |
| self.step_out_test() |
| |
| def test_stop_hooks_after_expr(self): |
| """Test that a stop hook fires when hitting a breakpoint |
| that runs an expression""" |
| self.after_expr_test() |
| |
| def step_out_test(self): |
| (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self, |
| "Set a breakpoint here", self.main_source_file) |
| |
| interp = self.dbg.GetCommandInterpreter() |
| result = lldb.SBCommandReturnObject() |
| interp.HandleCommand("target stop-hook add -o 'expr g_var++'", result) |
| self.assertTrue(result.Succeeded, "Set the target stop hook") |
| thread.StepOut() |
| var = target.FindFirstGlobalVariable("g_var") |
| self.assertTrue(var.IsValid()) |
| self.assertEqual(var.GetValueAsUnsigned(), 1, "Updated g_var") |
| |
| def after_expr_test(self): |
| interp = self.dbg.GetCommandInterpreter() |
| result = lldb.SBCommandReturnObject() |
| interp.HandleCommand("target stop-hook add -o 'expr g_var++'", result) |
| self.assertTrue(result.Succeeded, "Set the target stop hook") |
| |
| (target, process, thread, first_bkpt) = lldbutil.run_to_source_breakpoint(self, |
| "Set a breakpoint here", self.main_source_file) |
| |
| var = target.FindFirstGlobalVariable("g_var") |
| self.assertTrue(var.IsValid()) |
| self.assertEqual(var.GetValueAsUnsigned(), 1, "Updated g_var") |
| |
| bkpt = target.BreakpointCreateBySourceRegex("Continue to here", self.main_source_file) |
| self.assertNotEqual(bkpt.GetNumLocations(), 0, "Set the second breakpoint") |
| commands = lldb.SBStringList() |
| commands.AppendString("expr increment_gvar()") |
| bkpt.SetCommandLineCommands(commands); |
| |
| threads = lldbutil.continue_to_breakpoint(process, bkpt) |
| self.assertEqual(len(threads), 1, "Hit my breakpoint") |
| |
| self.assertTrue(var.IsValid()) |
| self.assertEqual(var.GetValueAsUnsigned(), 3, "Updated g_var") |
| |
| # Make sure running an expression does NOT run the stop hook. |
| # Our expression will increment it by one, but the stop shouldn't |
| # have gotten it to 5. |
| threads[0].frames[0].EvaluateExpression("increment_gvar()") |
| self.assertTrue(var.IsValid()) |
| self.assertEqual(var.GetValueAsUnsigned(), 4, "Updated g_var") |
| |
| |
| # Make sure a rerun doesn't upset the state we've set up: |
| process.Kill() |
| lldbutil.run_to_breakpoint_do_run(self, target, first_bkpt) |
| var = target.FindFirstGlobalVariable("g_var") |
| self.assertTrue(var.IsValid()) |
| self.assertEqual(var.GetValueAsUnsigned(), 1, "Updated g_var") |
| |
| |