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