199451b44SJordan Rupprecht""" 299451b44SJordan RupprechtTest that you can set breakpoint commands successfully with the Python API's: 399451b44SJordan Rupprecht""" 499451b44SJordan Rupprecht 599451b44SJordan Rupprechtimport lldb 699451b44SJordan Rupprechtfrom lldbsuite.test.decorators import * 799451b44SJordan Rupprechtfrom lldbsuite.test.lldbtest import * 899451b44SJordan Rupprechtfrom lldbsuite.test import lldbutil 999451b44SJordan Rupprechtimport side_effect 1099451b44SJordan Rupprecht 1199451b44SJordan Rupprecht 1299451b44SJordan Rupprechtclass PythonBreakpointCommandSettingTestCase(TestBase): 1399451b44SJordan Rupprecht NO_DEBUG_INFO_TESTCASE = True 1499451b44SJordan Rupprecht 152238dcc3SJonas Devlieghere @add_test_categories(["pyapi"]) 1699451b44SJordan Rupprecht def test_step_out_python(self): 1799451b44SJordan Rupprecht """Test stepping out using a python breakpoint command.""" 1899451b44SJordan Rupprecht self.build() 1999451b44SJordan Rupprecht self.do_set_python_command_from_python() 2099451b44SJordan Rupprecht 2199451b44SJordan Rupprecht def test_bkpt_cmd_bad_arguments(self): 2299451b44SJordan Rupprecht """Test what happens when pass structured data to a command:""" 2399451b44SJordan Rupprecht self.build() 2499451b44SJordan Rupprecht self.do_bad_args_to_python_command() 2599451b44SJordan Rupprecht 2699451b44SJordan Rupprecht def setUp(self): 2799451b44SJordan Rupprecht TestBase.setUp(self) 2899451b44SJordan Rupprecht self.main_source = "main.c" 2999451b44SJordan Rupprecht self.main_source_spec = lldb.SBFileSpec(self.main_source) 3099451b44SJordan Rupprecht 3199451b44SJordan Rupprecht def do_set_python_command_from_python(self): 3299451b44SJordan Rupprecht error = lldb.SBError() 3399451b44SJordan Rupprecht 3454c26872SRaphael Isemann self.target = self.createTestTarget() 3599451b44SJordan Rupprecht 3699451b44SJordan Rupprecht body_bkpt = self.target.BreakpointCreateBySourceRegex( 372238dcc3SJonas Devlieghere "Set break point at this line.", self.main_source_spec 382238dcc3SJonas Devlieghere ) 3999451b44SJordan Rupprecht self.assertTrue(body_bkpt, VALID_BREAKPOINT) 4099451b44SJordan Rupprecht 4199451b44SJordan Rupprecht func_bkpt = self.target.BreakpointCreateBySourceRegex( 422238dcc3SJonas Devlieghere "Set break point at this line.", self.main_source_spec 432238dcc3SJonas Devlieghere ) 4499451b44SJordan Rupprecht self.assertTrue(func_bkpt, VALID_BREAKPOINT) 4599451b44SJordan Rupprecht 4699451b44SJordan Rupprecht fancy_bkpt = self.target.BreakpointCreateBySourceRegex( 472238dcc3SJonas Devlieghere "Set break point at this line.", self.main_source_spec 482238dcc3SJonas Devlieghere ) 4999451b44SJordan Rupprecht self.assertTrue(fancy_bkpt, VALID_BREAKPOINT) 5099451b44SJordan Rupprecht 5199451b44SJordan Rupprecht fancier_bkpt = self.target.BreakpointCreateBySourceRegex( 522238dcc3SJonas Devlieghere "Set break point at this line.", self.main_source_spec 532238dcc3SJonas Devlieghere ) 5499451b44SJordan Rupprecht self.assertTrue(fancier_bkpt, VALID_BREAKPOINT) 5599451b44SJordan Rupprecht 569a2e9c5dSJim Ingham # Also test the list version of this: 579a2e9c5dSJim Ingham file_list = lldb.SBFileSpecList() 589a2e9c5dSJim Ingham file_list.Append(self.main_source_spec) 599a2e9c5dSJim Ingham module_list = lldb.SBFileSpecList() 609a2e9c5dSJim Ingham module_list.Append(self.target.GetExecutable()) 619a2e9c5dSJim Ingham 629a2e9c5dSJim Ingham list_bkpt = self.target.BreakpointCreateBySourceRegex( 632238dcc3SJonas Devlieghere "Set break point at this line.", module_list, file_list 642238dcc3SJonas Devlieghere ) 659a2e9c5dSJim Ingham self.assertTrue(list_bkpt, VALID_BREAKPOINT) 669a2e9c5dSJim Ingham 6799451b44SJordan Rupprecht not_so_fancy_bkpt = self.target.BreakpointCreateBySourceRegex( 682238dcc3SJonas Devlieghere "Set break point at this line.", self.main_source_spec 692238dcc3SJonas Devlieghere ) 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( 752238dcc3SJonas Devlieghere "Set a breakpoint here", lldb.SBFileSpecList(), lldb.SBFileSpecList() 762238dcc3SJonas Devlieghere ) 7799451b44SJordan Rupprecht self.assertTrue(no_files_bkpt, VALID_BREAKPOINT) 7899451b44SJordan Rupprecht num_locations = no_files_bkpt.GetNumLocations() 79*9c246882SJordan Rupprecht self.assertGreaterEqual( 80*9c246882SJordan Rupprecht num_locations, 2, "Got at least two breakpoint locations" 81*9c246882SJordan Rupprecht ) 8299451b44SJordan Rupprecht got_one_in_A = False 8399451b44SJordan Rupprecht got_one_in_B = False 8499451b44SJordan Rupprecht for idx in range(0, num_locations): 852238dcc3SJonas Devlieghere comp_unit = ( 862238dcc3SJonas Devlieghere no_files_bkpt.GetLocationAtIndex(idx) 872238dcc3SJonas Devlieghere .GetAddress() 882238dcc3SJonas Devlieghere .GetSymbolContext(lldb.eSymbolContextCompUnit) 892238dcc3SJonas Devlieghere .GetCompileUnit() 902238dcc3SJonas Devlieghere .GetFileSpec() 912238dcc3SJonas Devlieghere ) 9299451b44SJordan Rupprecht print("Got comp unit: ", comp_unit.GetFilename()) 9399451b44SJordan Rupprecht if comp_unit.GetFilename() == "a.c": 9499451b44SJordan Rupprecht got_one_in_A = True 9599451b44SJordan Rupprecht elif comp_unit.GetFilename() == "b.c": 9699451b44SJordan Rupprecht got_one_in_B = True 9799451b44SJordan Rupprecht 9899451b44SJordan Rupprecht self.assertTrue(got_one_in_A, "Failed to match the pattern in A") 9999451b44SJordan Rupprecht self.assertTrue(got_one_in_B, "Failed to match the pattern in B") 10099451b44SJordan Rupprecht self.target.BreakpointDelete(no_files_bkpt.GetID()) 10199451b44SJordan Rupprecht 10299451b44SJordan Rupprecht error = lldb.SBError() 10399451b44SJordan Rupprecht error = body_bkpt.SetScriptCallbackBody( 1042238dcc3SJonas Devlieghere "import side_effect; side_effect.callback = 'callback was here'" 1052238dcc3SJonas Devlieghere ) 10699451b44SJordan Rupprecht self.assertTrue( 10799451b44SJordan Rupprecht error.Success(), 1082238dcc3SJonas Devlieghere "Failed to set the script callback body: %s." % (error.GetCString()), 1092238dcc3SJonas Devlieghere ) 11099451b44SJordan Rupprecht 11199451b44SJordan Rupprecht self.expect("command script import --allow-reload ./bktptcmd.py") 11299451b44SJordan Rupprecht 11399451b44SJordan Rupprecht func_bkpt.SetScriptCallbackFunction("bktptcmd.function") 11499451b44SJordan Rupprecht 11599451b44SJordan Rupprecht extra_args = lldb.SBStructuredData() 11699451b44SJordan Rupprecht stream = lldb.SBStream() 11799451b44SJordan Rupprecht stream.Print('{"side_effect" : "I am fancy"}') 11899451b44SJordan Rupprecht extra_args.SetFromJSON(stream) 1192238dcc3SJonas Devlieghere error = fancy_bkpt.SetScriptCallbackFunction( 1202238dcc3SJonas Devlieghere "bktptcmd.another_function", extra_args 1212238dcc3SJonas Devlieghere ) 122779bbbf2SDave Lee self.assertSuccess(error, "Failed to add callback") 12399451b44SJordan Rupprecht 12499451b44SJordan Rupprecht stream.Clear() 12599451b44SJordan Rupprecht stream.Print('{"side_effect" : "I am so much fancier"}') 12699451b44SJordan Rupprecht extra_args.SetFromJSON(stream) 12799451b44SJordan Rupprecht 12899451b44SJordan Rupprecht # Fancier's callback is set up from the command line 12999451b44SJordan Rupprecht id = fancier_bkpt.GetID() 1302238dcc3SJonas Devlieghere self.expect( 1312238dcc3SJonas Devlieghere "breakpoint command add -F bktptcmd.a_third_function -k side_effect -v 'I am fancier' %d" 1322238dcc3SJonas Devlieghere % (id) 1332238dcc3SJonas Devlieghere ) 13499451b44SJordan Rupprecht 13599451b44SJordan Rupprecht # Not so fancy gets an empty extra_args: 13699451b44SJordan Rupprecht empty_args = lldb.SBStructuredData() 1372238dcc3SJonas Devlieghere error = not_so_fancy_bkpt.SetScriptCallbackFunction( 1382238dcc3SJonas Devlieghere "bktptcmd.empty_extra_args", empty_args 1392238dcc3SJonas Devlieghere ) 140779bbbf2SDave Lee self.assertSuccess(error, "Failed to add callback") 14199451b44SJordan Rupprecht 1429a2e9c5dSJim Ingham # Do list breakpoint like fancy: 1439a2e9c5dSJim Ingham stream.Clear() 1449a2e9c5dSJim Ingham stream.Print('{"side_effect" : "I come from list input"}') 1459a2e9c5dSJim Ingham extra_args.SetFromJSON(stream) 1462238dcc3SJonas Devlieghere error = list_bkpt.SetScriptCallbackFunction( 1472238dcc3SJonas Devlieghere "bktptcmd.a_list_function", extra_args 1482238dcc3SJonas Devlieghere ) 149779bbbf2SDave Lee self.assertSuccess(error, "Failed to add callback") 1509a2e9c5dSJim Ingham 15199451b44SJordan Rupprecht # Clear out canary variables 15299451b44SJordan Rupprecht side_effect.bktptcmd = None 15399451b44SJordan Rupprecht side_effect.callback = None 15499451b44SJordan Rupprecht side_effect.fancy = None 15599451b44SJordan Rupprecht side_effect.fancier = None 15699451b44SJordan Rupprecht side_effect.not_so_fancy = None 1579a2e9c5dSJim Ingham side_effect.a_list_function = None 15899451b44SJordan Rupprecht 15999451b44SJordan Rupprecht # Now launch the process, and do not stop at entry point. 16099451b44SJordan Rupprecht self.process = self.target.LaunchSimple( 1612238dcc3SJonas Devlieghere None, None, self.get_process_working_directory() 1622238dcc3SJonas Devlieghere ) 16399451b44SJordan Rupprecht 16499451b44SJordan Rupprecht self.assertTrue(self.process, PROCESS_IS_VALID) 16599451b44SJordan Rupprecht 16699451b44SJordan Rupprecht # Now finish, and make sure the return value is correct. 1672238dcc3SJonas Devlieghere threads = lldbutil.get_threads_stopped_at_breakpoint(self.process, body_bkpt) 16880fcecb1SJonas Devlieghere self.assertEqual(len(threads), 1, "Stopped at inner breakpoint.") 16999451b44SJordan Rupprecht self.thread = threads[0] 17099451b44SJordan Rupprecht 1712238dcc3SJonas Devlieghere print( 1722238dcc3SJonas Devlieghere "* Num Locations: {0} ; Hit Count {1}".format( 1732238dcc3SJonas Devlieghere list_bkpt.GetNumLocations(), list_bkpt.GetHitCount() 1742238dcc3SJonas Devlieghere ) 1752238dcc3SJonas Devlieghere ) 17680fcecb1SJonas Devlieghere self.assertEqual("callback was here", side_effect.callback) 17780fcecb1SJonas Devlieghere self.assertEqual("function was here", side_effect.bktptcmd) 17880fcecb1SJonas Devlieghere self.assertEqual("I am fancy", side_effect.fancy) 17980fcecb1SJonas Devlieghere self.assertEqual("I am fancier", side_effect.fancier) 18080fcecb1SJonas Devlieghere self.assertEqual("Not so fancy", side_effect.not_so_fancy) 18180fcecb1SJonas Devlieghere self.assertEqual("I come from list input", side_effect.from_list) 18299451b44SJordan Rupprecht 18399451b44SJordan Rupprecht def do_bad_args_to_python_command(self): 18499451b44SJordan Rupprecht error = lldb.SBError() 18599451b44SJordan Rupprecht 18654c26872SRaphael Isemann self.target = self.createTestTarget() 18799451b44SJordan Rupprecht 18899451b44SJordan Rupprecht self.expect("command script import --allow-reload ./bktptcmd.py") 18999451b44SJordan Rupprecht 19099451b44SJordan Rupprecht bkpt = self.target.BreakpointCreateBySourceRegex( 1912238dcc3SJonas Devlieghere "Set break point at this line.", self.main_source_spec 1922238dcc3SJonas Devlieghere ) 19399451b44SJordan Rupprecht self.assertTrue(bkpt, VALID_BREAKPOINT) 19499451b44SJordan Rupprecht 19599451b44SJordan Rupprecht # Pass a breakpoint command function that doesn't take extra_args, 19699451b44SJordan Rupprecht # but pass it extra args: 19799451b44SJordan Rupprecht 19899451b44SJordan Rupprecht extra_args = lldb.SBStructuredData() 19999451b44SJordan Rupprecht stream = lldb.SBStream() 20099451b44SJordan Rupprecht stream.Print('{"side_effect" : "I am fancy"}') 20199451b44SJordan Rupprecht extra_args.SetFromJSON(stream) 20299451b44SJordan Rupprecht 20399451b44SJordan Rupprecht error = bkpt.SetScriptCallbackFunction("bktptcmd.function", extra_args) 2042238dcc3SJonas Devlieghere self.assertTrue( 2052238dcc3SJonas Devlieghere error.Fail(), "Can't pass extra args if the function doesn't take them" 2062238dcc3SJonas Devlieghere ) 20799451b44SJordan Rupprecht 20899451b44SJordan Rupprecht error = bkpt.SetScriptCallbackFunction("bktptcmd.useless_function", extra_args) 2092238dcc3SJonas Devlieghere self.assertTrue( 2102238dcc3SJonas Devlieghere error.Fail(), 2112238dcc3SJonas Devlieghere "Can't pass extra args if the function has wrong number of args.", 2122238dcc3SJonas Devlieghere ) 21399451b44SJordan Rupprecht 21499451b44SJordan Rupprecht error = bkpt.SetScriptCallbackFunction("bktptcmd.nosuch_function", extra_args) 2152238dcc3SJonas Devlieghere self.assertTrue( 2162238dcc3SJonas Devlieghere error.Fail(), "Can't pass extra args if the function doesn't exist." 2172238dcc3SJonas Devlieghere ) 218