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