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']) 21e7c91e31SJonas Devlieghere @skipIfReproducer # side_effect bypasses reproducer 2299451b44SJordan Rupprecht def test_step_out_python(self): 2399451b44SJordan Rupprecht """Test stepping out using a python breakpoint command.""" 2499451b44SJordan Rupprecht self.build() 2599451b44SJordan Rupprecht self.do_set_python_command_from_python() 2699451b44SJordan Rupprecht 27e7c91e31SJonas Devlieghere @skipIfReproducer # side_effect bypasses reproducer 2899451b44SJordan Rupprecht def test_bkpt_cmd_bad_arguments(self): 2999451b44SJordan Rupprecht """Test what happens when pass structured data to a command:""" 3099451b44SJordan Rupprecht self.build() 3199451b44SJordan Rupprecht self.do_bad_args_to_python_command() 3299451b44SJordan Rupprecht 3399451b44SJordan Rupprecht def setUp(self): 3499451b44SJordan Rupprecht TestBase.setUp(self) 3599451b44SJordan Rupprecht self.main_source = "main.c" 3699451b44SJordan Rupprecht self.main_source_spec = lldb.SBFileSpec(self.main_source) 3799451b44SJordan Rupprecht 3899451b44SJordan Rupprecht def do_set_python_command_from_python(self): 3999451b44SJordan Rupprecht error = lldb.SBError() 4099451b44SJordan Rupprecht 41*54c26872SRaphael Isemann self.target = self.createTestTarget() 4299451b44SJordan Rupprecht 4399451b44SJordan Rupprecht body_bkpt = self.target.BreakpointCreateBySourceRegex( 4499451b44SJordan Rupprecht "Set break point at this line.", self.main_source_spec) 4599451b44SJordan Rupprecht self.assertTrue(body_bkpt, VALID_BREAKPOINT) 4699451b44SJordan Rupprecht 4799451b44SJordan Rupprecht func_bkpt = self.target.BreakpointCreateBySourceRegex( 4899451b44SJordan Rupprecht "Set break point at this line.", self.main_source_spec) 4999451b44SJordan Rupprecht self.assertTrue(func_bkpt, VALID_BREAKPOINT) 5099451b44SJordan Rupprecht 5199451b44SJordan Rupprecht fancy_bkpt = self.target.BreakpointCreateBySourceRegex( 5299451b44SJordan Rupprecht "Set break point at this line.", self.main_source_spec) 5399451b44SJordan Rupprecht self.assertTrue(fancy_bkpt, VALID_BREAKPOINT) 5499451b44SJordan Rupprecht 5599451b44SJordan Rupprecht fancier_bkpt = self.target.BreakpointCreateBySourceRegex( 5699451b44SJordan Rupprecht "Set break point at this line.", self.main_source_spec) 5799451b44SJordan Rupprecht self.assertTrue(fancier_bkpt, VALID_BREAKPOINT) 5899451b44SJordan Rupprecht 5999451b44SJordan Rupprecht not_so_fancy_bkpt = self.target.BreakpointCreateBySourceRegex( 6099451b44SJordan Rupprecht "Set break point at this line.", self.main_source_spec) 6199451b44SJordan Rupprecht self.assertTrue(not_so_fancy_bkpt, VALID_BREAKPOINT) 6299451b44SJordan Rupprecht 6399451b44SJordan Rupprecht # Also test that setting a source regex breakpoint with an empty file 6499451b44SJordan Rupprecht # spec list sets it on all files: 6599451b44SJordan Rupprecht no_files_bkpt = self.target.BreakpointCreateBySourceRegex( 6699451b44SJordan Rupprecht "Set a breakpoint here", lldb.SBFileSpecList(), lldb.SBFileSpecList()) 6799451b44SJordan Rupprecht self.assertTrue(no_files_bkpt, VALID_BREAKPOINT) 6899451b44SJordan Rupprecht num_locations = no_files_bkpt.GetNumLocations() 6999451b44SJordan Rupprecht self.assertTrue( 7099451b44SJordan Rupprecht num_locations >= 2, 7199451b44SJordan Rupprecht "Got at least two breakpoint locations") 7299451b44SJordan Rupprecht got_one_in_A = False 7399451b44SJordan Rupprecht got_one_in_B = False 7499451b44SJordan Rupprecht for idx in range(0, num_locations): 7599451b44SJordan Rupprecht comp_unit = no_files_bkpt.GetLocationAtIndex(idx).GetAddress().GetSymbolContext( 7699451b44SJordan Rupprecht lldb.eSymbolContextCompUnit).GetCompileUnit().GetFileSpec() 7799451b44SJordan Rupprecht print("Got comp unit: ", comp_unit.GetFilename()) 7899451b44SJordan Rupprecht if comp_unit.GetFilename() == "a.c": 7999451b44SJordan Rupprecht got_one_in_A = True 8099451b44SJordan Rupprecht elif comp_unit.GetFilename() == "b.c": 8199451b44SJordan Rupprecht got_one_in_B = True 8299451b44SJordan Rupprecht 8399451b44SJordan Rupprecht self.assertTrue(got_one_in_A, "Failed to match the pattern in A") 8499451b44SJordan Rupprecht self.assertTrue(got_one_in_B, "Failed to match the pattern in B") 8599451b44SJordan Rupprecht self.target.BreakpointDelete(no_files_bkpt.GetID()) 8699451b44SJordan Rupprecht 8799451b44SJordan Rupprecht error = lldb.SBError() 8899451b44SJordan Rupprecht error = body_bkpt.SetScriptCallbackBody( 8999451b44SJordan Rupprecht "import side_effect; side_effect.callback = 'callback was here'") 9099451b44SJordan Rupprecht self.assertTrue( 9199451b44SJordan Rupprecht error.Success(), 9299451b44SJordan Rupprecht "Failed to set the script callback body: %s." % 9399451b44SJordan Rupprecht (error.GetCString())) 9499451b44SJordan Rupprecht 9599451b44SJordan Rupprecht self.expect("command script import --allow-reload ./bktptcmd.py") 9699451b44SJordan Rupprecht 9799451b44SJordan Rupprecht func_bkpt.SetScriptCallbackFunction("bktptcmd.function") 9899451b44SJordan Rupprecht 9999451b44SJordan Rupprecht extra_args = lldb.SBStructuredData() 10099451b44SJordan Rupprecht stream = lldb.SBStream() 10199451b44SJordan Rupprecht stream.Print('{"side_effect" : "I am fancy"}') 10299451b44SJordan Rupprecht extra_args.SetFromJSON(stream) 10399451b44SJordan Rupprecht error = fancy_bkpt.SetScriptCallbackFunction("bktptcmd.another_function", extra_args) 10499451b44SJordan Rupprecht self.assertTrue(error.Success(), "Failed to add callback %s"%(error.GetCString())) 10599451b44SJordan Rupprecht 10699451b44SJordan Rupprecht stream.Clear() 10799451b44SJordan Rupprecht stream.Print('{"side_effect" : "I am so much fancier"}') 10899451b44SJordan Rupprecht extra_args.SetFromJSON(stream) 10999451b44SJordan Rupprecht 11099451b44SJordan Rupprecht # Fancier's callback is set up from the command line 11199451b44SJordan Rupprecht id = fancier_bkpt.GetID() 11299451b44SJordan Rupprecht self.expect("breakpoint command add -F bktptcmd.a_third_function -k side_effect -v 'I am fancier' %d"%(id)) 11399451b44SJordan Rupprecht 11499451b44SJordan Rupprecht # Not so fancy gets an empty extra_args: 11599451b44SJordan Rupprecht empty_args = lldb.SBStructuredData() 11699451b44SJordan Rupprecht error = not_so_fancy_bkpt.SetScriptCallbackFunction("bktptcmd.empty_extra_args", empty_args) 11799451b44SJordan Rupprecht self.assertTrue(error.Success(), "Failed to add callback %s"%(error.GetCString())) 11899451b44SJordan Rupprecht 11999451b44SJordan Rupprecht # Clear out canary variables 12099451b44SJordan Rupprecht side_effect.bktptcmd = None 12199451b44SJordan Rupprecht side_effect.callback = None 12299451b44SJordan Rupprecht side_effect.fancy = None 12399451b44SJordan Rupprecht side_effect.fancier = None 12499451b44SJordan Rupprecht side_effect.not_so_fancy = None 12599451b44SJordan Rupprecht 12699451b44SJordan Rupprecht # Now launch the process, and do not stop at entry point. 12799451b44SJordan Rupprecht self.process = self.target.LaunchSimple( 12899451b44SJordan Rupprecht None, None, self.get_process_working_directory()) 12999451b44SJordan Rupprecht 13099451b44SJordan Rupprecht self.assertTrue(self.process, PROCESS_IS_VALID) 13199451b44SJordan Rupprecht 13299451b44SJordan Rupprecht # Now finish, and make sure the return value is correct. 13399451b44SJordan Rupprecht threads = lldbutil.get_threads_stopped_at_breakpoint( 13499451b44SJordan Rupprecht self.process, body_bkpt) 13599451b44SJordan Rupprecht self.assertEquals(len(threads), 1, "Stopped at inner breakpoint.") 13699451b44SJordan Rupprecht self.thread = threads[0] 13799451b44SJordan Rupprecht 13899451b44SJordan Rupprecht self.assertEquals("callback was here", side_effect.callback) 13999451b44SJordan Rupprecht self.assertEquals("function was here", side_effect.bktptcmd) 14099451b44SJordan Rupprecht self.assertEquals("I am fancy", side_effect.fancy) 14199451b44SJordan Rupprecht self.assertEquals("I am fancier", side_effect.fancier) 14299451b44SJordan Rupprecht self.assertEquals("Not so fancy", side_effect.not_so_fancy) 14399451b44SJordan Rupprecht 14499451b44SJordan Rupprecht def do_bad_args_to_python_command(self): 14599451b44SJordan Rupprecht error = lldb.SBError() 14699451b44SJordan Rupprecht 147*54c26872SRaphael Isemann self.target = self.createTestTarget() 14899451b44SJordan Rupprecht 14999451b44SJordan Rupprecht self.expect("command script import --allow-reload ./bktptcmd.py") 15099451b44SJordan Rupprecht 15199451b44SJordan Rupprecht bkpt = self.target.BreakpointCreateBySourceRegex( 15299451b44SJordan Rupprecht "Set break point at this line.", self.main_source_spec) 15399451b44SJordan Rupprecht self.assertTrue(bkpt, VALID_BREAKPOINT) 15499451b44SJordan Rupprecht 15599451b44SJordan Rupprecht # Pass a breakpoint command function that doesn't take extra_args, 15699451b44SJordan Rupprecht # but pass it extra args: 15799451b44SJordan Rupprecht 15899451b44SJordan Rupprecht extra_args = lldb.SBStructuredData() 15999451b44SJordan Rupprecht stream = lldb.SBStream() 16099451b44SJordan Rupprecht stream.Print('{"side_effect" : "I am fancy"}') 16199451b44SJordan Rupprecht extra_args.SetFromJSON(stream) 16299451b44SJordan Rupprecht 16399451b44SJordan Rupprecht error = bkpt.SetScriptCallbackFunction("bktptcmd.function", extra_args) 16499451b44SJordan Rupprecht self.assertTrue(error.Fail(), "Can't pass extra args if the function doesn't take them") 16599451b44SJordan Rupprecht 16699451b44SJordan Rupprecht error = bkpt.SetScriptCallbackFunction("bktptcmd.useless_function", extra_args) 16799451b44SJordan Rupprecht self.assertTrue(error.Fail(), "Can't pass extra args if the function has wrong number of args.") 16899451b44SJordan Rupprecht 16999451b44SJordan Rupprecht error = bkpt.SetScriptCallbackFunction("bktptcmd.nosuch_function", extra_args) 17099451b44SJordan Rupprecht self.assertTrue(error.Fail(), "Can't pass extra args if the function doesn't exist.") 17199451b44SJordan Rupprecht 172