"""
Test stop hook functionality
"""
import lldb
import lldbsuite.test.lldbutil as lldbutil
from lldbsuite.test.lldbtest import *
from lldbsuite.test.decorators import *
class TestStopHooks(TestBase):
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_bad_handler(self):
"""Test that we give a good error message when the handler is bad"""
self.script_setup()
result = lldb.SBCommandReturnObject()
command = "target stop-hook add -P stop_hook.bad_handle_stop"
self.interp.HandleCommand(command, result)
self.assertFalse(result.Succeeded(), "Set the target stop hook")
self.assertIn(
"Wrong number of args",
result.GetError(),
"Got the wrong number of args error",
)
command = "target stop-hook add -P stop_hook.no_handle_stop"
self.interp.HandleCommand(command, result)
self.assertFalse(result.Succeeded(), "Set the target stop hook")
self.assertIn(
'Class "stop_hook.no_handle_stop" is missing the required handle_stop callback',
result.GetError(),
"Got the right error",
)
def test_stop_hooks_scripted(self):
"""Test that a scripted stop hook works with no specifiers"""
self.stop_hooks_scripted(5)
def test_stop_hooks_scripted_right_func(self):
"""Test that a scripted stop hook fires when there is a function match"""
self.stop_hooks_scripted(5, "-n step_out_of_me")
def test_stop_hooks_scripted_wrong_func(self):
"""Test that a scripted stop hook doesn't fire when the function does not match"""
self.stop_hooks_scripted(0, "-n main")
def test_stop_hooks_scripted_right_lines(self):
"""Test that a scripted stop hook fires when there is a function match"""
self.stop_hooks_scripted(5, "-f main.c -l 1 -e %d" % (self.main_start_line))
def test_stop_hooks_scripted_wrong_lines(self):
"""Test that a scripted stop hook doesn't fire when the function does not match"""
self.stop_hooks_scripted(0, "-f main.c -l %d -e 100" % (self.main_start_line))
def test_stop_hooks_scripted_auto_continue(self):
"""Test that the --auto-continue flag works"""
self.do_test_auto_continue(False)
def test_stop_hooks_scripted_return_false(self):
"""Test that the returning False from a stop hook works"""
self.do_test_auto_continue(True)
def do_test_auto_continue(self, return_true):
"""Test that auto-continue works."""
self.script_setup()
result = lldb.SBCommandReturnObject()
if return_true:
command = "target stop-hook add -P stop_hook.stop_handler -k increment -v 5 -k return_false -v 1 -n step_out_of_me"
else:
command = "target stop-hook add -G 1 -P stop_hook.stop_handler -k increment -v 5 -n step_out_of_me"
self.interp.HandleCommand(command, result)
self.assertTrue(result.Succeeded(), "Set the target stop hook")
(target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(
self, "Stop here first", self.main_source_file
)
bkpt = target.BreakpointCreateBySourceRegex(
"Set a breakpoint here and step out", self.main_source_file
)
self.assertNotEqual(
bkpt.GetNumLocations(), 0, "Got breakpoints in step_out_of_me"
)
process.Continue()
var = target.FindFirstGlobalVariable("g_var")
self.assertTrue(var.IsValid())
self.assertEqual(var.GetValueAsUnsigned(), 6, "Updated g_var")
func_name = process.GetSelectedThread().frames[0].GetFunctionName()
self.assertEqual("main", func_name, "Didn't stop at the expected function.")
def script_setup(self):
self.interp = self.dbg.GetCommandInterpreter()
result = lldb.SBCommandReturnObject()
script_name = os.path.join(self.getSourceDir(), "stop_hook.py")
command = "command script import " + script_name
self.interp.HandleCommand(command, result)
self.assertTrue(
result.Succeeded(), "com scr imp failed: %s" % (result.GetError())
)
dummy_target = self.dbg.GetDummyTarget()
dummy_target.BreakpointCreateBySourceRegex(
"return result", self.main_source_file
)
def stop_hooks_scripted(self, g_var_value, specifier=None):
self.script_setup()
result = lldb.SBCommandReturnObject()
command = "target stop-hook add -P stop_hook.stop_handler -k increment -v 5 "
if specifier:
command += specifier
self.interp.HandleCommand(command, result)
self.assertTrue(result.Succeeded(), "Set the target stop hook")
(target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(
self, "Set a breakpoint here", self.main_source_file
)
while process.GetState() == lldb.eStateRunning:
continue
var = target.FindFirstGlobalVariable("g_var")
self.assertTrue(var.IsValid())
self.assertEqual(var.GetValueAsUnsigned(), g_var_value, "Updated g_var")