def source_regex_locations(self): """ Test that restricting source expressions to files & to functions. """ # Create a target by the debugger. exe = self.getBuildArtifact("a.out") target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) # First look just in main: target_files = lldb.SBFileSpecList() target_files.Append(lldb.SBFileSpec("a.c")) func_names = lldb.SBStringList() func_names.AppendString("a_func") source_regex = "Set . breakpoint here" main_break = target.BreakpointCreateBySourceRegex( source_regex, lldb.SBFileSpecList(), target_files, func_names) num_locations = main_break.GetNumLocations() self.assertTrue( num_locations == 1, "a.c in a_func should give one breakpoint, got %d." % (num_locations)) loc = main_break.GetLocationAtIndex(0) self.assertTrue(loc.IsValid(), "Got a valid location.") address = loc.GetAddress() self.assertTrue(address.IsValid(), "Got a valid address from the location.") a_func_line = line_number("a.c", "Set A breakpoint here") line_entry = address.GetLineEntry() self.assertTrue(line_entry.IsValid(), "Got a valid line entry.") self.assertEquals(line_entry.line, a_func_line, "Our line number matches the one lldbtest found.")
def __init__(self, callback = None, callback_owner = None, name = None, module = None, file = None, line = None, breakpoint = None): Action.__init__(self, callback, callback_owner) self.modules = lldb.SBFileSpecList() self.files = lldb.SBFileSpecList() self.breakpoints = list() # "module" can be a list or a string if breakpoint: self.breakpoints.append(breakpoint) else: if module: if isinstance(module, types.ListType): for module_path in module: self.modules.Append(lldb.SBFileSpec(module_path, False)) elif isinstance(module, types.StringTypes): self.modules.Append(lldb.SBFileSpec(module, False)) if name: # "file" can be a list or a string if file: if isinstance(file, types.ListType): self.files = lldb.SBFileSpecList() for f in file: self.files.Append(lldb.SBFileSpec(f, False)) elif isinstance(file, types.StringTypes): self.files.Append(lldb.SBFileSpec(file, False)) self.breakpoints.append (self.target.BreakpointCreateByName(name, self.modules, self.files)) elif file and line: self.breakpoints.append (self.target.BreakpointCreateByLocation(file, line))
def do_check_filters(self): """Use Python APIs to check serialization of breakpoint filters.""" module_list = lldb.SBFileSpecList() module_list.Append(lldb.SBFileSpec("SomeBinary")) module_list.Append(lldb.SBFileSpec("SomeOtherBinary")) cu_list = lldb.SBFileSpecList() cu_list.Append(lldb.SBFileSpec("SomeCU.c")) cu_list.Append(lldb.SBFileSpec("AnotherCU.c")) cu_list.Append(lldb.SBFileSpec("ThirdCU.c")) blubby_file_spec = lldb.SBFileSpec(os.path.join(self.getSourceDir(), "blubby.c")) # It isn't actually important for these purposes that these breakpoint # actually have locations. source_bps = lldb.SBBreakpointList(self.orig_target) bkpt = self.orig_target.BreakpointCreateByLocation(blubby_file_spec, 666, 0, module_list) source_bps.Append(bkpt) # Make sure we do one right: self.check_equivalence(source_bps) source_bps.Clear() bkpt = self.orig_target.BreakpointCreateByName("blubby", lldb.eFunctionNameTypeAuto, module_list, cu_list) source_bps.Append(bkpt) bkpt = self.orig_target.BreakpointCreateByName("blubby", lldb.eFunctionNameTypeFull, module_list, cu_list) source_bps.Append(bkpt) bkpt = self.orig_target.BreakpointCreateBySourceRegex("dont really care", blubby_file_spec) source_bps.Append(bkpt) # And some number greater than one: self.check_equivalence(source_bps)
def test_breakpoints_func_auto(self): """Test that we can set breakpoints correctly by basename to find all functions whose basename is "func".""" self.build() names = [ "func()", "func(int)", "A::B::func()", "A::func()", "A::func(int)" ] # Create a target by the debugger. exe = self.getBuildArtifact("a.out") target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) module_list = lldb.SBFileSpecList() module_list.Append(lldb.SBFileSpec(exe, False)) cu_list = lldb.SBFileSpecList() # Set a breakpoint by name "func" which should pick up all functions # whose basename is "func" bp = target.BreakpointCreateByName("func", lldb.eFunctionNameTypeAuto, module_list, cu_list) for bp_loc in bp: name = bp_loc.GetAddress().GetFunction().GetName() self.assertTrue( name in names, "make sure breakpoint locations are correct for 'func' with eFunctionNameTypeAuto" )
def test_breakpoints_a_func_full(self): """Test that we can set breakpoints correctly by fullname to find all functions whose fully qualified name is "A::func".""" self.build() names = ["A::func()", "A::func(int)"] # Create a target by the debugger. exe = self.getBuildArtifact("a.out") target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) module_list = lldb.SBFileSpecList() module_list.Append(lldb.SBFileSpec(exe, False)) cu_list = lldb.SBFileSpecList() # Set a breakpoint by name "A::func" whose fullly qualified named matches "A::func" which # should pick up only functions whose basename is "func" and is # contained in the "A" namespace bp = target.BreakpointCreateByName("A::func", lldb.eFunctionNameTypeFull, module_list, cu_list) for bp_loc in bp: name = bp_loc.GetAddress().GetFunction().GetName() self.assertTrue( name in names, "make sure breakpoint locations are correct for 'A::func' with eFunctionNameTypeFull" )
def check_category_breakpoints(self): name_bp = self.target.BreakpointCreateByName("myCategoryFunction") selector_bp = self.target.BreakpointCreateByName( "myCategoryFunction", lldb.eFunctionNameTypeSelector, lldb.SBFileSpecList(), lldb.SBFileSpecList()) self.assertTrue( name_bp.GetNumLocations() == selector_bp.GetNumLocations(), 'Make sure setting a breakpoint by name "myCategoryFunction" sets a breakpoint even though it is in a category' ) for bp_loc in selector_bp: function_name = bp_loc.GetAddress().GetSymbol().GetName() self.assertTrue( " myCategoryFunction]" in function_name, 'Make sure all function names have " myCategoryFunction]" in their names' ) category_bp = self.target.BreakpointCreateByName( "-[MyClass(MyCategory) myCategoryFunction]") stripped_bp = self.target.BreakpointCreateByName( "-[MyClass myCategoryFunction]") stripped2_bp = self.target.BreakpointCreateByName( "[MyClass myCategoryFunction]") self.assertTrue( category_bp.GetNumLocations() == 1, "Make sure we can set a breakpoint using a full objective C function name with the category included (-[MyClass(MyCategory) myCategoryFunction])" ) self.assertTrue( stripped_bp.GetNumLocations() == 1, "Make sure we can set a breakpoint using a full objective C function name without the category included (-[MyClass myCategoryFunction])" ) self.assertTrue( stripped2_bp.GetNumLocations() == 1, "Make sure we can set a breakpoint using a full objective C function name without the category included ([MyClass myCategoryFunction])" )
def test_break_in_dlopen_dylib_using_target(self): self.common_setup() target, process, _, _ = lldbutil.run_to_source_breakpoint( self, "Break here before we dlopen", self.main_spec, extra_images=[self.lib_shortname]) # Now set some breakpoints that won't take till the library is loaded: # This one is currently how lldbutils does it but test here in case that changes: bkpt1 = target.BreakpointCreateBySourceRegex("Break here in dylib", self.b_spec, self.lib_fullname) # Try the file list API as well. Put in some bogus entries too, to make sure those # don't trip us up: files_list = lldb.SBFileSpecList() files_list.Append(self.b_spec) files_list.Append(self.main_spec) files_list.Append(lldb.SBFileSpec("I_bet_nobody_has_this_file.cpp")) modules_list = lldb.SBFileSpecList() modules_list.Append(self.lib_spec) modules_list.Append( lldb.SBFileSpec("libI_bet_not_this_one_either.dylib")) bkpt2 = target.BreakpointCreateBySourceRegex("Break here in dylib", modules_list, files_list) lldbutil.continue_to_breakpoint(process, bkpt1) self.assertEqual(bkpt1.GetHitCount(), 1, "Hit breakpoint 1") self.assertEqual(bkpt2.GetHitCount(), 1, "Hit breakpoint 2")
def do_test_depths(self): """This test uses a class variable in resolver.Resolver which gets set to 1 if we saw compile unit and 2 if we only saw modules. If the search depth is module, you get passed just the modules with no comp_unit. If the depth is comp_unit you get comp_units. So we can use this to test that our callback gets called at the right depth.""" target = self.make_target_and_import() extra_args = self.make_extra_args() file_list = lldb.SBFileSpecList() module_list = lldb.SBFileSpecList() module_list.Append(lldb.SBFileSpec("a.out")) # Make a breakpoint that has no __get_depth__, check that that is converted to eSearchDepthModule: bkpt = target.BreakpointCreateFromScript("resolver.Resolver", extra_args, module_list, file_list) self.assertTrue(bkpt.GetNumLocations() > 0, "Resolver got no locations.") self.expect("script print resolver.Resolver.got_files", substrs=["2"], msg="Was only passed modules") # Make a breakpoint that asks for modules, check that we didn't get any files: bkpt = target.BreakpointCreateFromScript("resolver.ResolverModuleDepth", extra_args, module_list, file_list) self.assertTrue(bkpt.GetNumLocations() > 0, "ResolverModuleDepth got no locations.") self.expect("script print resolver.Resolver.got_files", substrs=["2"], msg="Was only passed modules") # Make a breakpoint that asks for compile units, check that we didn't get any files: bkpt = target.BreakpointCreateFromScript("resolver.ResolverCUDepth", extra_args, module_list, file_list) self.assertTrue(bkpt.GetNumLocations() > 0, "ResolverCUDepth got no locations.") self.expect("script print resolver.Resolver.got_files", substrs=["1"], msg="Was passed compile units") # Make a breakpoint that returns a bad value - we should convert that to "modules" so check that: bkpt = target.BreakpointCreateFromScript("resolver.ResolverBadDepth", extra_args, module_list, file_list) self.assertTrue(bkpt.GetNumLocations() > 0, "ResolverBadDepth got no locations.") self.expect("script print resolver.Resolver.got_files", substrs=["2"], msg="Was only passed modules")
def do_check_resolvers(self): """Use Python APIs to check serialization of breakpoint resolvers""" empty_module_list = lldb.SBFileSpecList() empty_cu_list = lldb.SBFileSpecList() blubby_file_spec = lldb.SBFileSpec( os.path.join(self.getSourceDir(), "blubby.c")) # It isn't actually important for these purposes that these breakpoint # actually have locations. source_bps = lldb.SBBreakpointList(self.orig_target) source_bps.Append( self.orig_target.BreakpointCreateByLocation("blubby.c", 666)) # Make sure we do one breakpoint right: self.check_equivalence(source_bps) source_bps.Clear() source_bps.Append( self.orig_target.BreakpointCreateByName("blubby", lldb.eFunctionNameTypeAuto, empty_module_list, empty_cu_list)) source_bps.Append( self.orig_target.BreakpointCreateByName("blubby", lldb.eFunctionNameTypeFull, empty_module_list, empty_cu_list)) source_bps.Append( self.orig_target.BreakpointCreateBySourceRegex( "dont really care", blubby_file_spec)) # And some number greater than one: self.check_equivalence(source_bps)
def do_check_options(self): """Use Python APIs to check serialization of breakpoint options.""" empty_module_list = lldb.SBFileSpecList() empty_cu_list = lldb.SBFileSpecList() blubby_file_spec = lldb.SBFileSpec( os.path.join(self.getSourceDir(), "blubby.c")) # It isn't actually important for these purposes that these breakpoint # actually have locations. source_bps = lldb.SBBreakpointList(self.orig_target) bkpt = self.orig_target.BreakpointCreateByLocation( lldb.SBFileSpec("blubby.c"), 666, 333, 0, lldb.SBFileSpecList()) bkpt.SetEnabled(False) bkpt.SetOneShot(True) bkpt.SetThreadID(10) source_bps.Append(bkpt) # Make sure we get one right: self.check_equivalence(source_bps) source_bps.Clear() bkpt = self.orig_target.BreakpointCreateByName( "blubby", lldb.eFunctionNameTypeAuto, empty_module_list, empty_cu_list) bkpt.SetIgnoreCount(10) bkpt.SetThreadName("grubby") source_bps.Append(bkpt) bkpt = self.orig_target.BreakpointCreateByName( "blubby", lldb.eFunctionNameTypeAuto, empty_module_list, empty_cu_list) bkpt.SetCondition("gonna remove this") bkpt.SetCondition("") source_bps.Append(bkpt) bkpt = self.orig_target.BreakpointCreateByName( "blubby", lldb.eFunctionNameTypeFull, empty_module_list, empty_cu_list) bkpt.SetCondition("something != something_else") bkpt.SetQueueName("grubby") bkpt.AddName("FirstName") bkpt.AddName("SecondName") bkpt.SetScriptCallbackBody( '\tprint("I am a function that prints.")\n\tprint("I don\'t do anything else")\n' ) source_bps.Append(bkpt) bkpt = self.orig_target.BreakpointCreateBySourceRegex( "dont really care", blubby_file_spec) cmd_list = lldb.SBStringList() cmd_list.AppendString("frame var") cmd_list.AppendString("thread backtrace") bkpt.SetCommandLineCommands(cmd_list) source_bps.Append(bkpt) self.check_equivalence(source_bps)
def do_check_appending(self): """Use Python APIs to check appending to already serialized options.""" empty_module_list = lldb.SBFileSpecList() empty_cu_list = lldb.SBFileSpecList() blubby_file_spec = lldb.SBFileSpec( os.path.join(self.getSourceDir(), "blubby.c")) # It isn't actually important for these purposes that these breakpoint # actually have locations. all_bps = lldb.SBBreakpointList(self.orig_target) source_bps = lldb.SBBreakpointList(self.orig_target) bkpt = self.orig_target.BreakpointCreateByLocation( lldb.SBFileSpec("blubby.c"), 666, 333, 0, lldb.SBFileSpecList()) bkpt.SetEnabled(False) bkpt.SetOneShot(True) bkpt.SetThreadID(10) source_bps.Append(bkpt) all_bps.Append(bkpt) error = lldb.SBError() error = self.orig_target.BreakpointsWriteToFile( self.bkpts_file_spec, source_bps) self.assertTrue( error.Success(), "Failed writing breakpoints to file: %s." % (error.GetCString())) source_bps.Clear() bkpt = self.orig_target.BreakpointCreateByName( "blubby", lldb.eFunctionNameTypeAuto, empty_module_list, empty_cu_list) bkpt.SetIgnoreCount(10) bkpt.SetThreadName("grubby") source_bps.Append(bkpt) all_bps.Append(bkpt) bkpt = self.orig_target.BreakpointCreateByName( "blubby", lldb.eFunctionNameTypeFull, empty_module_list, empty_cu_list) bkpt.SetCondition("something != something_else") bkpt.SetQueueName("grubby") bkpt.AddName("FirstName") bkpt.AddName("SecondName") source_bps.Append(bkpt) all_bps.Append(bkpt) error = self.orig_target.BreakpointsWriteToFile( self.bkpts_file_spec, source_bps, True) self.assertTrue( error.Success(), "Failed appending breakpoints to file: %s." % (error.GetCString())) self.check_equivalence(all_bps)
def test_cpp_breakpoint_cmds(self): """Test a sequence of breakpoint command add, list, and delete.""" self.build() exe = self.getBuildArtifact("a.out") # Create a target from the debugger. self.target = self.dbg.CreateTarget(exe) self.assertTrue(self.target, VALID_TARGET) self.a_out_module = lldb.SBFileSpecList() self.a_out_module.Append(lldb.SBFileSpec(exe)) self.nested_comp_unit = lldb.SBFileSpecList() self.nested_comp_unit.Append(lldb.SBFileSpec("nested.cpp")) # First provide ONLY the method name. This should get everybody... self.make_breakpoint("Function", lldb.eFunctionNameTypeAuto, 5) # Now add the Baz class specifier. This should get the version contained in Bar, # AND the one contained in :: self.make_breakpoint("Baz::Function", lldb.eFunctionNameTypeAuto, 2) # Then add the Bar::Baz specifier. This should get the version # contained in Bar only self.make_breakpoint("Bar::Baz::Function", lldb.eFunctionNameTypeAuto, 1) self.make_breakpoint("Function", lldb.eFunctionNameTypeMethod, 3) self.make_breakpoint("Baz::Function", lldb.eFunctionNameTypeMethod, 2) self.make_breakpoint("Bar::Baz::Function", lldb.eFunctionNameTypeMethod, 1) self.make_breakpoint("Function", lldb.eFunctionNameTypeBase, 2) self.make_breakpoint("Bar::Function", lldb.eFunctionNameTypeBase, 1)
def test_by_name_breakpoint_language(self): """Test that the name regex breakpoint commands obey the language filter.""" self.build() # Load symbols on-demand self.runCmd("settings set symbols.load-on-demand true") # Create a target by the debugger. exe = self.getBuildArtifact("a.out") error = lldb.SBError() # Don't read in dependencies so we don't come across false matches that # add unwanted breakpoint hits. self.target = self.dbg.CreateTarget(exe, None, None, False, error) self.assertTrue(self.target, VALID_TARGET) cpp_bp = self.target.BreakpointCreateByName( "func_from_cpp", lldb.eFunctionNameTypeAuto, lldb.eLanguageTypeC_plus_plus, lldb.SBFileSpecList(), lldb.SBFileSpecList()) self.assertEqual(cpp_bp.GetNumLocations(), 1, "Only one C++ symbol matches") self.assertTrue(self.check_location_file(cpp_bp, 0, "cpp_lang.cpp")) no_cpp_bp = self.target.BreakpointCreateByName( "func_from_c", lldb.eFunctionNameTypeAuto, lldb.eLanguageTypeC_plus_plus, lldb.SBFileSpecList(), lldb.SBFileSpecList()) self.assertEqual(no_cpp_bp.GetNumLocations(), 0, "And the C one doesn't match") c_bp = self.target.BreakpointCreateByName("func_from_c", lldb.eFunctionNameTypeAuto, lldb.eLanguageTypeC, lldb.SBFileSpecList(), lldb.SBFileSpecList()) self.assertEqual(c_bp.GetNumLocations(), 1, "Only one C symbol matches") self.assertTrue(self.check_location_file(c_bp, 0, "c_lang.c")) no_c_bp = self.target.BreakpointCreateByName( "func_from_cpp", lldb.eFunctionNameTypeAuto, lldb.eLanguageTypeC, lldb.SBFileSpecList(), lldb.SBFileSpecList()) self.assertEqual(no_c_bp.GetNumLocations(), 0, "And the C++ one doesn't match") objc_bp = self.target.BreakpointCreateByName( "func_from_cpp", lldb.eFunctionNameTypeAuto, lldb.eLanguageTypeObjC, lldb.SBFileSpecList(), lldb.SBFileSpecList()) self.assertEqual(objc_bp.GetNumLocations(), 0, "No ObjC symbol matches")
def do_check_names(self): bkpt = self.orig_target.BreakpointCreateByLocation( lldb.SBFileSpec("blubby.c"), 666, 333, 0, lldb.SBFileSpecList()) good_bkpt_name = "GoodBreakpoint" write_bps = lldb.SBBreakpointList(self.orig_target) bkpt.AddName(good_bkpt_name) write_bps.Append(bkpt) error = lldb.SBError() error = self.orig_target.BreakpointsWriteToFile( self.bkpts_file_spec, write_bps) self.assertTrue( error.Success(), "Failed writing breakpoints to file: %s." % (error.GetCString())) copy_bps = lldb.SBBreakpointList(self.copy_target) names_list = lldb.SBStringList() names_list.AppendString("NoSuchName") error = self.copy_target.BreakpointsCreateFromFile( self.bkpts_file_spec, names_list, copy_bps) self.assertTrue( error.Success(), "Failed reading breakpoints from file: %s" % (error.GetCString())) self.assertTrue(copy_bps.GetSize() == 0, "Found breakpoints with a nonexistent name.") names_list.AppendString(good_bkpt_name) error = self.copy_target.BreakpointsCreateFromFile( self.bkpts_file_spec, names_list, copy_bps) self.assertTrue( error.Success(), "Failed reading breakpoints from file: %s" % (error.GetCString())) self.assertTrue(copy_bps.GetSize() == 1, "Found the matching breakpoint.")
def run_to_line_breakpoint(test, source_spec, line_number, column=0, launch_info=None, exe_name="a.out", bkpt_module=None, in_cwd=True): """Start up a target, using exe_name as the executable, and run it to a breakpoint set by (source_spec, line_number(, column)). The rest of the behavior is the same as run_to_name_breakpoint. """ target = run_to_breakpoint_make_target(test, exe_name, in_cwd) # Set the breakpoints breakpoint = target.BreakpointCreateByLocation(source_spec, line_number, column, 0, lldb.SBFileSpecList()) test.assertTrue( breakpoint.GetNumLocations() > 0, 'No locations found for line breakpoint: "%s:%d(:%d)", dir: "%s"' % (source_spec.GetFilename(), line_number, column, source_spec.GetDirectory())) return run_to_breakpoint_do_run(test, target, breakpoint, launch_info)
def source_regex_restrictions(self): """ Test that restricting source expressions to files & to functions. """ # Create a target by the debugger. exe = self.getBuildArtifact("a.out") target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) # First look just in main: target_files = lldb.SBFileSpecList() target_files.Append(lldb.SBFileSpec("main.c")) source_regex = "Set . breakpoint here" main_break = target.BreakpointCreateBySourceRegex( source_regex, lldb.SBFileSpecList(), target_files, lldb.SBStringList()) num_locations = main_break.GetNumLocations() self.assertTrue( num_locations == 2, "main.c should have 2 matches, got %d." % (num_locations)) # Now look in both files: target_files.Append(lldb.SBFileSpec("a.c")) main_break = target.BreakpointCreateBySourceRegex( source_regex, lldb.SBFileSpecList(), target_files, lldb.SBStringList()) num_locations = main_break.GetNumLocations() self.assertTrue( num_locations == 4, "main.c and a.c should have 4 matches, got %d." % (num_locations)) # Now restrict it to functions: func_names = lldb.SBStringList() func_names.AppendString("main_func") main_break = target.BreakpointCreateBySourceRegex( source_regex, lldb.SBFileSpecList(), target_files, func_names) num_locations = main_break.GetNumLocations() self.assertTrue( num_locations == 2, "main_func in main.c and a.c should have 2 matches, got %d." % (num_locations))
def test_regex_breakpoint_language(self): """Test that the name regex breakpoint commands obey the language filter.""" self.build() # Create a target by the debugger. exe = self.getBuildArtifact("a.out") error = lldb.SBError() # Don't read in dependencies so we don't come across false matches that # add unwanted breakpoint hits. self.target = self.dbg.CreateTarget(exe, None, None, False, error) self.assertTrue(self.target, VALID_TARGET) cpp_bp = self.target.BreakpointCreateByRegex( "func_from", lldb.eLanguageTypeC_plus_plus, lldb.SBFileSpecList(), lldb.SBFileSpecList()) self.assertEqual(cpp_bp.GetNumLocations(), 1, "Only one C++ symbol matches") self.assertTrue(self.check_location_file(cpp_bp, 0, "b.cpp")) c_bp = self.target.BreakpointCreateByRegex("func_from", lldb.eLanguageTypeC, lldb.SBFileSpecList(), lldb.SBFileSpecList()) self.assertEqual(c_bp.GetNumLocations(), 1, "Only one C symbol matches") self.assertTrue(self.check_location_file(c_bp, 0, "a.c")) objc_bp = self.target.BreakpointCreateByRegex("func_from", lldb.eLanguageTypeObjC, lldb.SBFileSpecList(), lldb.SBFileSpecList()) self.assertEqual(objc_bp.GetNumLocations(), 0, "No ObjC symbol matches")
def testBreakpointByLineAndColumnNearestCode(self): self.build() exe = self.getBuildArtifact("a.out") main_c = lldb.SBFileSpec("main.c") line = line_number("main.c", "// Line 20.") column = len("// Line 20") # should stop at the period. indent = 2 module_list = lldb.SBFileSpecList() # Create a target from the debugger. target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) valid_bpt = target.BreakpointCreateByLocation(main_c, line, column, indent, module_list, True) self.assertTrue(valid_bpt, VALID_BREAKPOINT) self.assertEqual(valid_bpt.GetNumLocations(), 1) invalid_bpt = target.BreakpointCreateByLocation(main_c, line, column, indent, module_list, False) self.assertTrue(invalid_bpt, VALID_BREAKPOINT) self.assertEqual(invalid_bpt.GetNumLocations(), 0)
def testBreakpointByLineAndColumnNearestCode(self): self.build() patterns = [ "In the middle of a function name (col:42)", "In the middle of the lambda declaration argument (col:23)", "Inside the lambda (col:26)" ] source_loc = [] for pattern in patterns: line = line_number("main.cpp", pattern) + 1 column = int(re.search('\(col:([0-9]+)\)', pattern).group(1)) source_loc.append({'line':line, 'column':column}) target = self.createTestTarget() for loc in source_loc: src_file = lldb.SBFileSpec("main.cpp") line = loc['line'] column = loc['column'] indent = 0 module_list = lldb.SBFileSpecList() valid_bpkt = target.BreakpointCreateByLocation(src_file, line, column, indent, module_list, True) self.assertTrue(valid_bpkt, VALID_BREAKPOINT) self.assertEqual(valid_bpkt.GetNumLocations(), 1) process = target.LaunchSimple( None, None, self.get_process_working_directory()) self.assertTrue(process, PROCESS_IS_VALID) nearest_column = [7, 17, 26] for idx,loc in enumerate(source_loc): bpkt = target.GetBreakpointAtIndex(idx) bpkt_loc = bpkt.GetLocationAtIndex(0) self.assertEqual(bpkt_loc.GetHitCount(), 1) self.assertSuccess(process.Continue()) bpkt_loc_desc = lldb.SBStream() self.assertTrue(bpkt_loc.GetDescription(bpkt_loc_desc, lldb.eDescriptionLevelVerbose)) self.assertIn("main.cpp:{}:{}".format(loc['line'], nearest_column[idx]), bpkt_loc_desc.GetData()) bpkt_loc_addr = bpkt_loc.GetAddress() self.assertTrue(bpkt_loc_addr) list = target.FindCompileUnits(lldb.SBFileSpec("main.cpp", False)) # Executable has been built just from one source file 'main.cpp', # so we may check only the first element of list. compile_unit = list[0].GetCompileUnit() found = False for line_entry in compile_unit: if line_entry.GetStartAddress() == bpkt_loc_addr: self.assertEqual(line_entry.GetFileSpec().GetFilename(), "main.cpp") self.assertEqual(line_entry.GetLine(), loc['line']) self.assertEqual(line_entry.GetColumn(), nearest_column[idx]) found = True break self.assertTrue(found) line = line_number("main.cpp", "// This is a random comment.") column = len("// This is a random comment.") indent = 2 invalid_bpkt = target.BreakpointCreateByLocation(src_file, line, column, indent, module_list, False) self.assertTrue(invalid_bpkt, VALID_BREAKPOINT) self.assertEqual(invalid_bpkt.GetNumLocations(), 0)
def check_objc_breakpoints(self, have_dsym): """Test constant string generation amd comparison by the expression parser.""" # Set debugger into synchronous mode self.dbg.SetAsync(False) # Create a target by the debugger. exe = os.path.join(os.getcwd(), "a.out") self.target = self.dbg.CreateTarget(exe) self.assertTrue(self.target, VALID_TARGET) #---------------------------------------------------------------------- # Set breakpoints on all selectors whose name is "count". This should # catch breakpoints that are both C functions _and_ anything whose # selector is "count" because just looking at "count" we can't tell # definitively if the name is a selector or a C function #---------------------------------------------------------------------- name_bp = self.target.BreakpointCreateByName("count") selector_bp = self.target.BreakpointCreateByName( "count", lldb.eFunctionNameTypeSelector, lldb.SBFileSpecList(), lldb.SBFileSpecList()) self.assertTrue( name_bp.GetNumLocations() >= selector_bp.GetNumLocations(), 'Make sure we get at least the same amount of breakpoints if not more when setting by name "count"' ) self.assertTrue(selector_bp.GetNumLocations() > 50, 'Make sure we find a lot of "count" selectors' ) # There are 93 on the latest MacOSX for bp_loc in selector_bp: function_name = bp_loc.GetAddress().GetSymbol().GetName() self.assertTrue( " count]" in function_name, 'Make sure all function names have " count]" in their names') #---------------------------------------------------------------------- # Set breakpoints on all selectors whose name is "isEqual:". This should # catch breakpoints that are only ObjC selectors because no C function # can end with a : #---------------------------------------------------------------------- name_bp = self.target.BreakpointCreateByName("isEqual:") selector_bp = self.target.BreakpointCreateByName( "isEqual:", lldb.eFunctionNameTypeSelector, lldb.SBFileSpecList(), lldb.SBFileSpecList()) self.assertTrue( name_bp.GetNumLocations() == selector_bp.GetNumLocations(), 'Make sure setting a breakpoint by name "isEqual:" only sets selector breakpoints' ) for bp_loc in selector_bp: function_name = bp_loc.GetAddress().GetSymbol().GetName() self.assertTrue( " isEqual:]" in function_name, 'Make sure all function names have " isEqual:]" in their names' ) self.check_category_breakpoints() if have_dsym: shutil.rmtree(exe + ".dSYM") self.assertTrue( subprocess.call(['/usr/bin/strip', '-Sx', exe]) == 0, 'stripping dylib succeeded') # Check breakpoints again, this time using the symbol table only self.check_category_breakpoints()
def cpp_breakpoints(self): """Test a sequence of breakpoint command add, list, and delete.""" exe = os.path.join(os.getcwd(), "a.out") # Create a target from the debugger. target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) a_out_module = lldb.SBFileSpecList() a_out_module.Append(lldb.SBFileSpec(exe)) nested_comp_unit = lldb.SBFileSpecList() nested_comp_unit.Append(lldb.SBFileSpec("nested.cpp")) # First provide ONLY the method name. This should get everybody... auto_break = target.BreakpointCreateByName("Function", lldb.eFunctionNameTypeAuto, a_out_module, nested_comp_unit) self.assertTrue(auto_break.GetNumLocations() == 5) # Now add the Baz class specifier. This should get the version contained in Bar, # AND the one contained in :: auto_break = target.BreakpointCreateByName("Baz::Function", lldb.eFunctionNameTypeAuto, a_out_module, nested_comp_unit) self.assertTrue(auto_break.GetNumLocations() == 2) # Then add the Bar::Baz specifier. This should get the version contained in Bar only auto_break = target.BreakpointCreateByName("Bar::Baz::Function", lldb.eFunctionNameTypeAuto, a_out_module, nested_comp_unit) self.assertTrue(auto_break.GetNumLocations() == 1) plain_method_break = target.BreakpointCreateByName( "Function", lldb.eFunctionNameTypeMethod, a_out_module, nested_comp_unit) self.assertTrue(plain_method_break.GetNumLocations() == 3) plain_method_break = target.BreakpointCreateByName( "Baz::Function", lldb.eFunctionNameTypeMethod, a_out_module, nested_comp_unit) self.assertTrue(plain_method_break.GetNumLocations() == 2) plain_method_break = target.BreakpointCreateByName( "Bar::Baz::Function", lldb.eFunctionNameTypeMethod, a_out_module, nested_comp_unit) self.assertTrue(plain_method_break.GetNumLocations() == 1) plain_method_break = target.BreakpointCreateByName( "Function", lldb.eFunctionNameTypeBase, a_out_module, nested_comp_unit) self.assertTrue(plain_method_break.GetNumLocations() == 2) plain_method_break = target.BreakpointCreateByName( "Bar::Function", lldb.eFunctionNameTypeBase, a_out_module, nested_comp_unit) self.assertTrue(plain_method_break.GetNumLocations() == 1)
def do_set_python_command_from_python(self): exe = self.getBuildArtifact("a.out") error = lldb.SBError() self.target = self.dbg.CreateTarget(exe) self.assertTrue(self.target, VALID_TARGET) body_bkpt = self.target.BreakpointCreateBySourceRegex( "Set break point at this line.", self.main_source_spec) self.assertTrue(body_bkpt, VALID_BREAKPOINT) func_bkpt = self.target.BreakpointCreateBySourceRegex( "Set break point at this line.", self.main_source_spec) self.assertTrue(func_bkpt, VALID_BREAKPOINT) fancy_bkpt = self.target.BreakpointCreateBySourceRegex( "Set break point at this line.", self.main_source_spec) self.assertTrue(fancy_bkpt, VALID_BREAKPOINT) fancier_bkpt = self.target.BreakpointCreateBySourceRegex( "Set break point at this line.", self.main_source_spec) self.assertTrue(fancier_bkpt, VALID_BREAKPOINT) not_so_fancy_bkpt = self.target.BreakpointCreateBySourceRegex( "Set break point at this line.", self.main_source_spec) self.assertTrue(not_so_fancy_bkpt, VALID_BREAKPOINT) # Also test that setting a source regex breakpoint with an empty file # spec list sets it on all files: no_files_bkpt = self.target.BreakpointCreateBySourceRegex( "Set a breakpoint here", lldb.SBFileSpecList(), lldb.SBFileSpecList()) self.assertTrue(no_files_bkpt, VALID_BREAKPOINT) num_locations = no_files_bkpt.GetNumLocations() self.assertTrue(num_locations >= 2, "Got at least two breakpoint locations") got_one_in_A = False got_one_in_B = False for idx in range(0, num_locations): comp_unit = no_files_bkpt.GetLocationAtIndex(idx).GetAddress( ).GetSymbolContext( lldb.eSymbolContextCompUnit).GetCompileUnit().GetFileSpec() print("Got comp unit: ", comp_unit.GetFilename()) if comp_unit.GetFilename() == "a.c": got_one_in_A = True elif comp_unit.GetFilename() == "b.c": got_one_in_B = True self.assertTrue(got_one_in_A, "Failed to match the pattern in A") self.assertTrue(got_one_in_B, "Failed to match the pattern in B") self.target.BreakpointDelete(no_files_bkpt.GetID()) error = lldb.SBError() error = body_bkpt.SetScriptCallbackBody( "import side_effect; side_effect.callback = 'callback was here'") self.assertTrue( error.Success(), "Failed to set the script callback body: %s." % (error.GetCString())) self.expect("command script import --allow-reload ./bktptcmd.py") func_bkpt.SetScriptCallbackFunction("bktptcmd.function") extra_args = lldb.SBStructuredData() stream = lldb.SBStream() stream.Print('{"side_effect" : "I am fancy"}') extra_args.SetFromJSON(stream) error = fancy_bkpt.SetScriptCallbackFunction( "bktptcmd.another_function", extra_args) self.assertTrue(error.Success(), "Failed to add callback %s" % (error.GetCString())) stream.Clear() stream.Print('{"side_effect" : "I am so much fancier"}') extra_args.SetFromJSON(stream) # Fancier's callback is set up from the command line id = fancier_bkpt.GetID() self.expect( "breakpoint command add -F bktptcmd.a_third_function -k side_effect -v 'I am fancier' %d" % (id)) # Not so fancy gets an empty extra_args: empty_args = lldb.SBStructuredData() error = not_so_fancy_bkpt.SetScriptCallbackFunction( "bktptcmd.empty_extra_args", empty_args) self.assertTrue(error.Success(), "Failed to add callback %s" % (error.GetCString())) # Clear out canary variables side_effect.bktptcmd = None side_effect.callback = None side_effect.fancy = None side_effect.fancier = None side_effect.not_so_fancy = None # Now launch the process, and do not stop at entry point. self.process = self.target.LaunchSimple( None, None, self.get_process_working_directory()) self.assertTrue(self.process, PROCESS_IS_VALID) # Now finish, and make sure the return value is correct. threads = lldbutil.get_threads_stopped_at_breakpoint( self.process, body_bkpt) self.assertEquals(len(threads), 1, "Stopped at inner breakpoint.") self.thread = threads[0] self.assertEquals("callback was here", side_effect.callback) self.assertEquals("function was here", side_effect.bktptcmd) self.assertEquals("I am fancy", side_effect.fancy) self.assertEquals("I am fancier", side_effect.fancier) self.assertEquals("Not so fancy", side_effect.not_so_fancy)
def do_check_extra_args(self): import side_effect interp = self.dbg.GetCommandInterpreter() error = lldb.SBError() script_name = os.path.join(self.getSourceDir(), "resolver.py") command = "command script import " + script_name result = lldb.SBCommandReturnObject() interp.HandleCommand(command, result) self.assertTrue(result.Succeeded(), "com scr imp failed: %s"%(result.GetError())) # First make sure a scripted breakpoint with no args works: bkpt = self.orig_target.BreakpointCreateFromScript("resolver.Resolver", lldb.SBStructuredData(), lldb.SBFileSpecList(), lldb.SBFileSpecList()) self.assertTrue(bkpt.IsValid(), "Bkpt is valid") write_bps = lldb.SBBreakpointList(self.orig_target) error = self.orig_target.BreakpointsWriteToFile(self.bkpts_file_spec, write_bps) self.assertSuccess(error, "Failed writing breakpoints") side_effect.g_extra_args = None copy_bps = lldb.SBBreakpointList(self.copy_target) error = self.copy_target.BreakpointsCreateFromFile(self.bkpts_file_spec, copy_bps) self.assertSuccess(error, "Failed reading breakpoints") self.assertEqual(copy_bps.GetSize(), 1, "Got one breakpoint from file.") no_keys = lldb.SBStringList() side_effect.g_extra_args.GetKeys(no_keys) self.assertEqual(no_keys.GetSize(), 0, "Should have no keys") self.orig_target.DeleteAllBreakpoints() self.copy_target.DeleteAllBreakpoints() # Now try one with extra args: extra_args = lldb.SBStructuredData() stream = lldb.SBStream() stream.Print('{"first_arg" : "first_value", "second_arg" : "second_value"}') extra_args.SetFromJSON(stream) self.assertTrue(extra_args.IsValid(), "SBStructuredData is valid.") bkpt = self.orig_target.BreakpointCreateFromScript("resolver.Resolver", extra_args, lldb.SBFileSpecList(), lldb.SBFileSpecList()) self.assertTrue(bkpt.IsValid(), "Bkpt is valid") write_bps = lldb.SBBreakpointList(self.orig_target) error = self.orig_target.BreakpointsWriteToFile(self.bkpts_file_spec, write_bps) self.assertSuccess(error, "Failed writing breakpoints") orig_extra_args = side_effect.g_extra_args self.assertTrue(orig_extra_args.IsValid(), "Extra args originally valid") orig_keys = lldb.SBStringList() orig_extra_args.GetKeys(orig_keys) self.assertEqual(2, orig_keys.GetSize(), "Should have two keys") side_effect.g_extra_args = None copy_bps = lldb.SBBreakpointList(self.copy_target) error = self.copy_target.BreakpointsCreateFromFile(self.bkpts_file_spec, copy_bps) self.assertSuccess(error, "Failed reading breakpoints") self.assertEqual(copy_bps.GetSize(), 1, "Got one breakpoint from file.") copy_extra_args = side_effect.g_extra_args copy_keys = lldb.SBStringList() copy_extra_args.GetKeys(copy_keys) self.assertEqual(2, copy_keys.GetSize(), "Copy should have two keys") for idx in range(0, orig_keys.GetSize()): key = orig_keys.GetStringAtIndex(idx) copy_value = copy_extra_args.GetValueForKey(key).GetStringValue(100) if key == "first_arg": self.assertEqual(copy_value, "first_value") elif key == "second_arg": self.assertEqual(copy_value, "second_value") else: self.Fail("Unknown key: %s"%(key))
def do_set_python_command_from_python(self): exe = os.path.join(os.getcwd(), "a.out") error = lldb.SBError() self.target = self.dbg.CreateTarget(exe) self.assertTrue(self.target, VALID_TARGET) body_bkpt = self.target.BreakpointCreateBySourceRegex( "Set break point at this line.", self.main_source_spec) self.assertTrue(body_bkpt, VALID_BREAKPOINT) func_bkpt = self.target.BreakpointCreateBySourceRegex( "Set break point at this line.", self.main_source_spec) self.assertTrue(func_bkpt, VALID_BREAKPOINT) # Also test that setting a source regex breakpoint with an empty file # spec list sets it on all files: no_files_bkpt = self.target.BreakpointCreateBySourceRegex( "Set a breakpoint here", lldb.SBFileSpecList(), lldb.SBFileSpecList()) self.assertTrue(no_files_bkpt, VALID_BREAKPOINT) num_locations = no_files_bkpt.GetNumLocations() self.assertTrue(num_locations >= 2, "Got at least two breakpoint locations") got_one_in_A = False got_one_in_B = False for idx in range(0, num_locations): comp_unit = no_files_bkpt.GetLocationAtIndex(idx).GetAddress( ).GetSymbolContext( lldb.eSymbolContextCompUnit).GetCompileUnit().GetFileSpec() print("Got comp unit: ", comp_unit.GetFilename()) if comp_unit.GetFilename() == "a.c": got_one_in_A = True elif comp_unit.GetFilename() == "b.c": got_one_in_B = True self.assertTrue(got_one_in_A, "Failed to match the pattern in A") self.assertTrue(got_one_in_B, "Failed to match the pattern in B") self.target.BreakpointDelete(no_files_bkpt.GetID()) PythonBreakpointCommandSettingTestCase.my_var = 10 error = lldb.SBError() error = body_bkpt.SetScriptCallbackBody("\ import TestBreakpointCommandsFromPython\n\ TestBreakpointCommandsFromPython.PythonBreakpointCommandSettingTestCase.my_var = 20\n\ print('Hit breakpoint')") self.assertTrue( error.Success(), "Failed to set the script callback body: %s." % (error.GetCString())) self.dbg.HandleCommand( "command script import --allow-reload ./bktptcmd.py") func_bkpt.SetScriptCallbackFunction("bktptcmd.function") # We will use the function that touches a text file, so remove it # first: self.RemoveTempFile("output2.txt") # Now launch the process, and do not stop at entry point. self.process = self.target.LaunchSimple( None, None, self.get_process_working_directory()) self.assertTrue(self.process, PROCESS_IS_VALID) # Now finish, and make sure the return value is correct. threads = lldbutil.get_threads_stopped_at_breakpoint( self.process, body_bkpt) self.assertTrue(len(threads) == 1, "Stopped at inner breakpoint.") self.thread = threads[0] self.assertTrue(PythonBreakpointCommandSettingTestCase.my_var == 20) # Check for the function version as well, which produced this file: # Remember to clean up after ourselves... self.assertTrue( os.path.isfile("output2.txt"), "'output2.txt' exists due to breakpoint command for breakpoint function." ) self.RemoveTempFile("output2.txt")
def do_test(self): """This reads in a python file and sets a breakpoint using it.""" target = self.make_target_and_import() extra_args = self.make_extra_args() file_list = lldb.SBFileSpecList() module_list = lldb.SBFileSpecList() # Make breakpoints with this resolver using different filters, first ones that will take: right = [] # one with no file or module spec - this one should fire: right.append(target.BreakpointCreateFromScript("resolver.Resolver", extra_args, module_list, file_list)) # one with the right source file and no module - should also fire: file_list.Append(lldb.SBFileSpec("main.c")) right.append(target.BreakpointCreateFromScript("resolver.Resolver", extra_args, module_list, file_list)) # Make sure the help text shows up in the "break list" output: self.expect("break list", substrs=["I am a python breakpoint resolver"], msg="Help is listed in break list") # one with the right source file and right module - should also fire: module_list.Append(lldb.SBFileSpec("a.out")) right.append(target.BreakpointCreateFromScript("resolver.Resolver", extra_args, module_list, file_list)) # And one with no source file but the right module: file_list.Clear() right.append(target.BreakpointCreateFromScript("resolver.Resolver", extra_args, module_list, file_list)) # Make sure these all got locations: for i in range (0, len(right)): self.assertTrue(right[i].GetNumLocations() >= 1, "Breakpoint %d has no locations."%(i)) # Now some ones that won't take: module_list.Clear() file_list.Clear() wrong = [] # one with the wrong module - should not fire: module_list.Append(lldb.SBFileSpec("noSuchModule")) wrong.append(target.BreakpointCreateFromScript("resolver.Resolver", extra_args, module_list, file_list)) # one with the wrong file - also should not fire: file_list.Clear() module_list.Clear() file_list.Append(lldb.SBFileSpec("noFileOfThisName.xxx")) wrong.append(target.BreakpointCreateFromScript("resolver.Resolver", extra_args, module_list, file_list)) # Now make sure the CU level iteration obeys the file filters: file_list.Clear() module_list.Clear() file_list.Append(lldb.SBFileSpec("no_such_file.xxx")) wrong.append(target.BreakpointCreateFromScript("resolver.ResolverCUDepth", extra_args, module_list, file_list)) # And the Module filters: file_list.Clear() module_list.Clear() module_list.Append(lldb.SBFileSpec("NoSuchModule.dylib")) wrong.append(target.BreakpointCreateFromScript("resolver.ResolverCUDepth", extra_args, module_list, file_list)) # Now make sure the Function level iteration obeys the file filters: file_list.Clear() module_list.Clear() file_list.Append(lldb.SBFileSpec("no_such_file.xxx")) wrong.append(target.BreakpointCreateFromScript("resolver.ResolverFuncDepth", extra_args, module_list, file_list)) # And the Module filters: file_list.Clear() module_list.Clear() module_list.Append(lldb.SBFileSpec("NoSuchModule.dylib")) wrong.append(target.BreakpointCreateFromScript("resolver.ResolverFuncDepth", extra_args, module_list, file_list)) # Make sure these didn't get locations: for i in range(0, len(wrong)): self.assertEqual(wrong[i].GetNumLocations(), 0, "Breakpoint %d has locations."%(i)) # Now run to main and ensure we hit the breakpoints we should have: lldbutil.run_to_breakpoint_do_run(self, target, right[0]) # Test the hit counts: for i in range(0, len(right)): self.assertEqual(right[i].GetHitCount(), 1, "Breakpoint %d has the wrong hit count"%(i)) for i in range(0, len(wrong)): self.assertEqual(wrong[i].GetHitCount(), 0, "Breakpoint %d has the wrong hit count"%(i))