199451b44SJordan Rupprecht""" 299451b44SJordan RupprechtTest that you can set breakpoint commands successfully with the Python API's: 399451b44SJordan Rupprecht""" 499451b44SJordan Rupprecht 599451b44SJordan Rupprechtfrom __future__ import print_function 699451b44SJordan Rupprecht 799451b44SJordan Rupprecht 899451b44SJordan Rupprechtimport lldb 999451b44SJordan Rupprechtfrom lldbsuite.test.decorators import * 1099451b44SJordan Rupprechtfrom lldbsuite.test.lldbtest import * 1199451b44SJordan Rupprechtfrom lldbsuite.test import lldbutil 1299451b44SJordan Rupprechtimport side_effect 1399451b44SJordan Rupprecht 1499451b44SJordan Rupprecht 1599451b44SJordan Rupprechtclass PythonBreakpointCommandSettingTestCase(TestBase): 1699451b44SJordan Rupprecht 1799451b44SJordan Rupprecht mydir = TestBase.compute_mydir(__file__) 1899451b44SJordan Rupprecht NO_DEBUG_INFO_TESTCASE = True 1999451b44SJordan Rupprecht 2099451b44SJordan Rupprecht @add_test_categories(['pyapi']) 2199451b44SJordan Rupprecht def test_step_out_python(self): 2299451b44SJordan Rupprecht """Test stepping out using a python breakpoint command.""" 2399451b44SJordan Rupprecht self.build() 2499451b44SJordan Rupprecht self.do_set_python_command_from_python() 2599451b44SJordan Rupprecht 2699451b44SJordan Rupprecht def test_bkpt_cmd_bad_arguments(self): 2799451b44SJordan Rupprecht """Test what happens when pass structured data to a command:""" 2899451b44SJordan Rupprecht self.build() 2999451b44SJordan Rupprecht self.do_bad_args_to_python_command() 3099451b44SJordan Rupprecht 3199451b44SJordan Rupprecht def setUp(self): 3299451b44SJordan Rupprecht TestBase.setUp(self) 3399451b44SJordan Rupprecht self.main_source = "main.c" 3499451b44SJordan Rupprecht self.main_source_spec = lldb.SBFileSpec(self.main_source) 3599451b44SJordan Rupprecht 3699451b44SJordan Rupprecht def do_set_python_command_from_python(self): 3799451b44SJordan Rupprecht error = lldb.SBError() 3899451b44SJordan Rupprecht 3954c26872SRaphael Isemann self.target = self.createTestTarget() 4099451b44SJordan Rupprecht 4199451b44SJordan Rupprecht body_bkpt = self.target.BreakpointCreateBySourceRegex( 4299451b44SJordan Rupprecht "Set break point at this line.", self.main_source_spec) 4399451b44SJordan Rupprecht self.assertTrue(body_bkpt, VALID_BREAKPOINT) 4499451b44SJordan Rupprecht 4599451b44SJordan Rupprecht func_bkpt = self.target.BreakpointCreateBySourceRegex( 4699451b44SJordan Rupprecht "Set break point at this line.", self.main_source_spec) 4799451b44SJordan Rupprecht self.assertTrue(func_bkpt, VALID_BREAKPOINT) 4899451b44SJordan Rupprecht 4999451b44SJordan Rupprecht fancy_bkpt = self.target.BreakpointCreateBySourceRegex( 5099451b44SJordan Rupprecht "Set break point at this line.", self.main_source_spec) 5199451b44SJordan Rupprecht self.assertTrue(fancy_bkpt, VALID_BREAKPOINT) 5299451b44SJordan Rupprecht 5399451b44SJordan Rupprecht fancier_bkpt = self.target.BreakpointCreateBySourceRegex( 5499451b44SJordan Rupprecht "Set break point at this line.", self.main_source_spec) 5599451b44SJordan Rupprecht self.assertTrue(fancier_bkpt, VALID_BREAKPOINT) 5699451b44SJordan Rupprecht 579a2e9c5dSJim Ingham # Also test the list version of this: 589a2e9c5dSJim Ingham file_list = lldb.SBFileSpecList() 599a2e9c5dSJim Ingham file_list.Append(self.main_source_spec) 609a2e9c5dSJim Ingham module_list = lldb.SBFileSpecList() 619a2e9c5dSJim Ingham module_list.Append(self.target.GetExecutable()) 629a2e9c5dSJim Ingham 639a2e9c5dSJim Ingham list_bkpt = self.target.BreakpointCreateBySourceRegex( 649a2e9c5dSJim Ingham "Set break point at this line.", module_list, file_list) 659a2e9c5dSJim Ingham self.assertTrue(list_bkpt, VALID_BREAKPOINT) 669a2e9c5dSJim Ingham 679a2e9c5dSJim Ingham 6899451b44SJordan Rupprecht not_so_fancy_bkpt = self.target.BreakpointCreateBySourceRegex( 6999451b44SJordan Rupprecht "Set break point at this line.", self.main_source_spec) 7099451b44SJordan Rupprecht self.assertTrue(not_so_fancy_bkpt, VALID_BREAKPOINT) 7199451b44SJordan Rupprecht 7299451b44SJordan Rupprecht # Also test that setting a source regex breakpoint with an empty file 7399451b44SJordan Rupprecht # spec list sets it on all files: 7499451b44SJordan Rupprecht no_files_bkpt = self.target.BreakpointCreateBySourceRegex( 7599451b44SJordan Rupprecht "Set a breakpoint here", lldb.SBFileSpecList(), lldb.SBFileSpecList()) 7699451b44SJordan Rupprecht self.assertTrue(no_files_bkpt, VALID_BREAKPOINT) 7799451b44SJordan Rupprecht num_locations = no_files_bkpt.GetNumLocations() 7899451b44SJordan Rupprecht self.assertTrue( 7999451b44SJordan Rupprecht num_locations >= 2, 8099451b44SJordan Rupprecht "Got at least two breakpoint locations") 8199451b44SJordan Rupprecht got_one_in_A = False 8299451b44SJordan Rupprecht got_one_in_B = False 8399451b44SJordan Rupprecht for idx in range(0, num_locations): 8499451b44SJordan Rupprecht comp_unit = no_files_bkpt.GetLocationAtIndex(idx).GetAddress().GetSymbolContext( 8599451b44SJordan Rupprecht lldb.eSymbolContextCompUnit).GetCompileUnit().GetFileSpec() 8699451b44SJordan Rupprecht print("Got comp unit: ", comp_unit.GetFilename()) 8799451b44SJordan Rupprecht if comp_unit.GetFilename() == "a.c": 8899451b44SJordan Rupprecht got_one_in_A = True 8999451b44SJordan Rupprecht elif comp_unit.GetFilename() == "b.c": 9099451b44SJordan Rupprecht got_one_in_B = True 9199451b44SJordan Rupprecht 9299451b44SJordan Rupprecht self.assertTrue(got_one_in_A, "Failed to match the pattern in A") 9399451b44SJordan Rupprecht self.assertTrue(got_one_in_B, "Failed to match the pattern in B") 9499451b44SJordan Rupprecht self.target.BreakpointDelete(no_files_bkpt.GetID()) 9599451b44SJordan Rupprecht 9699451b44SJordan Rupprecht error = lldb.SBError() 9799451b44SJordan Rupprecht error = body_bkpt.SetScriptCallbackBody( 9899451b44SJordan Rupprecht "import side_effect; side_effect.callback = 'callback was here'") 9999451b44SJordan Rupprecht self.assertTrue( 10099451b44SJordan Rupprecht error.Success(), 10199451b44SJordan Rupprecht "Failed to set the script callback body: %s." % 10299451b44SJordan Rupprecht (error.GetCString())) 10399451b44SJordan Rupprecht 10499451b44SJordan Rupprecht self.expect("command script import --allow-reload ./bktptcmd.py") 10599451b44SJordan Rupprecht 10699451b44SJordan Rupprecht func_bkpt.SetScriptCallbackFunction("bktptcmd.function") 10799451b44SJordan Rupprecht 10899451b44SJordan Rupprecht extra_args = lldb.SBStructuredData() 10999451b44SJordan Rupprecht stream = lldb.SBStream() 11099451b44SJordan Rupprecht stream.Print('{"side_effect" : "I am fancy"}') 11199451b44SJordan Rupprecht extra_args.SetFromJSON(stream) 11299451b44SJordan Rupprecht error = fancy_bkpt.SetScriptCallbackFunction("bktptcmd.another_function", extra_args) 113*779bbbf2SDave Lee self.assertSuccess(error, "Failed to add callback") 11499451b44SJordan Rupprecht 11599451b44SJordan Rupprecht stream.Clear() 11699451b44SJordan Rupprecht stream.Print('{"side_effect" : "I am so much fancier"}') 11799451b44SJordan Rupprecht extra_args.SetFromJSON(stream) 11899451b44SJordan Rupprecht 11999451b44SJordan Rupprecht # Fancier's callback is set up from the command line 12099451b44SJordan Rupprecht id = fancier_bkpt.GetID() 12199451b44SJordan Rupprecht self.expect("breakpoint command add -F bktptcmd.a_third_function -k side_effect -v 'I am fancier' %d"%(id)) 12299451b44SJordan Rupprecht 12399451b44SJordan Rupprecht # Not so fancy gets an empty extra_args: 12499451b44SJordan Rupprecht empty_args = lldb.SBStructuredData() 12599451b44SJordan Rupprecht error = not_so_fancy_bkpt.SetScriptCallbackFunction("bktptcmd.empty_extra_args", empty_args) 126*779bbbf2SDave Lee self.assertSuccess(error, "Failed to add callback") 12799451b44SJordan Rupprecht 1289a2e9c5dSJim Ingham # Do list breakpoint like fancy: 1299a2e9c5dSJim Ingham stream.Clear() 1309a2e9c5dSJim Ingham stream.Print('{"side_effect" : "I come from list input"}') 1319a2e9c5dSJim Ingham extra_args.SetFromJSON(stream) 1329a2e9c5dSJim Ingham error = list_bkpt.SetScriptCallbackFunction("bktptcmd.a_list_function", extra_args) 133*779bbbf2SDave Lee self.assertSuccess(error, "Failed to add callback") 1349a2e9c5dSJim Ingham 13599451b44SJordan Rupprecht # Clear out canary variables 13699451b44SJordan Rupprecht side_effect.bktptcmd = None 13799451b44SJordan Rupprecht side_effect.callback = None 13899451b44SJordan Rupprecht side_effect.fancy = None 13999451b44SJordan Rupprecht side_effect.fancier = None 14099451b44SJordan Rupprecht side_effect.not_so_fancy = None 1419a2e9c5dSJim Ingham side_effect.a_list_function = None 14299451b44SJordan Rupprecht 14399451b44SJordan Rupprecht # Now launch the process, and do not stop at entry point. 14499451b44SJordan Rupprecht self.process = self.target.LaunchSimple( 14599451b44SJordan Rupprecht None, None, self.get_process_working_directory()) 14699451b44SJordan Rupprecht 14799451b44SJordan Rupprecht self.assertTrue(self.process, PROCESS_IS_VALID) 14899451b44SJordan Rupprecht 14999451b44SJordan Rupprecht # Now finish, and make sure the return value is correct. 15099451b44SJordan Rupprecht threads = lldbutil.get_threads_stopped_at_breakpoint( 15199451b44SJordan Rupprecht self.process, body_bkpt) 15299451b44SJordan Rupprecht self.assertEquals(len(threads), 1, "Stopped at inner breakpoint.") 15399451b44SJordan Rupprecht self.thread = threads[0] 15499451b44SJordan Rupprecht 1559a2e9c5dSJim Ingham print("* Num Locations: {0} ; Hit Count {1}".format(list_bkpt.GetNumLocations(), list_bkpt.GetHitCount())) 15699451b44SJordan Rupprecht self.assertEquals("callback was here", side_effect.callback) 15799451b44SJordan Rupprecht self.assertEquals("function was here", side_effect.bktptcmd) 15899451b44SJordan Rupprecht self.assertEquals("I am fancy", side_effect.fancy) 15999451b44SJordan Rupprecht self.assertEquals("I am fancier", side_effect.fancier) 16099451b44SJordan Rupprecht self.assertEquals("Not so fancy", side_effect.not_so_fancy) 1619a2e9c5dSJim Ingham self.assertEquals("I come from list input", side_effect.from_list) 16299451b44SJordan Rupprecht 16399451b44SJordan Rupprecht def do_bad_args_to_python_command(self): 16499451b44SJordan Rupprecht error = lldb.SBError() 16599451b44SJordan Rupprecht 16654c26872SRaphael Isemann self.target = self.createTestTarget() 16799451b44SJordan Rupprecht 16899451b44SJordan Rupprecht self.expect("command script import --allow-reload ./bktptcmd.py") 16999451b44SJordan Rupprecht 17099451b44SJordan Rupprecht bkpt = self.target.BreakpointCreateBySourceRegex( 17199451b44SJordan Rupprecht "Set break point at this line.", self.main_source_spec) 17299451b44SJordan Rupprecht self.assertTrue(bkpt, VALID_BREAKPOINT) 17399451b44SJordan Rupprecht 17499451b44SJordan Rupprecht # Pass a breakpoint command function that doesn't take extra_args, 17599451b44SJordan Rupprecht # but pass it extra args: 17699451b44SJordan Rupprecht 17799451b44SJordan Rupprecht extra_args = lldb.SBStructuredData() 17899451b44SJordan Rupprecht stream = lldb.SBStream() 17999451b44SJordan Rupprecht stream.Print('{"side_effect" : "I am fancy"}') 18099451b44SJordan Rupprecht extra_args.SetFromJSON(stream) 18199451b44SJordan Rupprecht 18299451b44SJordan Rupprecht error = bkpt.SetScriptCallbackFunction("bktptcmd.function", extra_args) 18399451b44SJordan Rupprecht self.assertTrue(error.Fail(), "Can't pass extra args if the function doesn't take them") 18499451b44SJordan Rupprecht 18599451b44SJordan Rupprecht error = bkpt.SetScriptCallbackFunction("bktptcmd.useless_function", extra_args) 18699451b44SJordan Rupprecht self.assertTrue(error.Fail(), "Can't pass extra args if the function has wrong number of args.") 18799451b44SJordan Rupprecht 18899451b44SJordan Rupprecht error = bkpt.SetScriptCallbackFunction("bktptcmd.nosuch_function", extra_args) 18999451b44SJordan Rupprecht self.assertTrue(error.Fail(), "Can't pass extra args if the function doesn't exist.") 19099451b44SJordan Rupprecht 191