1""" 2Test stop hook functionality 3""" 4 5 6import lldb 7import lldbsuite.test.lldbutil as lldbutil 8from lldbsuite.test.lldbtest import * 9 10 11class TestStopHooks(TestBase): 12 # If your test case doesn't stress debug info, then 13 # set this to true. That way it won't be run once for 14 # each debug info format. 15 NO_DEBUG_INFO_TESTCASE = True 16 17 def setUp(self): 18 TestBase.setUp(self) 19 self.build() 20 self.main_source_file = lldb.SBFileSpec("main.c") 21 full_path = os.path.join(self.getSourceDir(), "main.c") 22 self.main_start_line = line_number(full_path, "main()") 23 24 def test_stop_hooks_step_out(self): 25 """Test that stop hooks fire on step-out.""" 26 self.step_out_test() 27 28 def test_stop_hooks_after_expr(self): 29 """Test that a stop hook fires when hitting a breakpoint 30 that runs an expression""" 31 self.after_expr_test() 32 33 def step_out_test(self): 34 (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint( 35 self, "Set a breakpoint here", self.main_source_file 36 ) 37 38 interp = self.dbg.GetCommandInterpreter() 39 result = lldb.SBCommandReturnObject() 40 interp.HandleCommand("target stop-hook add -o 'expr g_var++'", result) 41 self.assertTrue(result.Succeeded(), "Set the target stop hook") 42 thread.StepOut() 43 var = target.FindFirstGlobalVariable("g_var") 44 self.assertTrue(var.IsValid()) 45 self.assertEqual(var.GetValueAsUnsigned(), 1, "Updated g_var") 46 47 def after_expr_test(self): 48 interp = self.dbg.GetCommandInterpreter() 49 result = lldb.SBCommandReturnObject() 50 interp.HandleCommand("target stop-hook add -o 'expr g_var++'", result) 51 self.assertTrue(result.Succeeded(), "Set the target stop hook") 52 53 (target, process, thread, first_bkpt) = lldbutil.run_to_source_breakpoint( 54 self, "Set a breakpoint here", self.main_source_file 55 ) 56 57 var = target.FindFirstGlobalVariable("g_var") 58 self.assertTrue(var.IsValid()) 59 self.assertEqual(var.GetValueAsUnsigned(), 1, "Updated g_var") 60 61 bkpt = target.BreakpointCreateBySourceRegex( 62 "Continue to here", self.main_source_file 63 ) 64 self.assertNotEqual(bkpt.GetNumLocations(), 0, "Set the second breakpoint") 65 commands = lldb.SBStringList() 66 commands.AppendString("expr increment_gvar()") 67 bkpt.SetCommandLineCommands(commands) 68 69 threads = lldbutil.continue_to_breakpoint(process, bkpt) 70 self.assertEqual(len(threads), 1, "Hit my breakpoint") 71 72 self.assertTrue(var.IsValid()) 73 self.assertEqual(var.GetValueAsUnsigned(), 3, "Updated g_var") 74 75 # Make sure running an expression does NOT run the stop hook. 76 # Our expression will increment it by one, but the stop shouldn't 77 # have gotten it to 5. 78 threads[0].frames[0].EvaluateExpression("increment_gvar()") 79 self.assertTrue(var.IsValid()) 80 self.assertEqual(var.GetValueAsUnsigned(), 4, "Updated g_var") 81 82 # Make sure a rerun doesn't upset the state we've set up: 83 process.Kill() 84 lldbutil.run_to_breakpoint_do_run(self, target, first_bkpt) 85 var = target.FindFirstGlobalVariable("g_var") 86 self.assertTrue(var.IsValid()) 87 self.assertEqual(var.GetValueAsUnsigned(), 1, "Updated g_var") 88