""" Test that objective-c constant strings are generated correctly by the expression parser. """ import shutil import subprocess import lldb from lldbsuite.test.decorators import * from lldbsuite.test.lldbtest import * from lldbsuite.test import lldbutil class TestObjCBreakpoints(TestBase): @add_test_categories(["objc"]) def test_break(self): """Test setting Objective-C specific breakpoints (DWARF in .o files).""" self.build() self.setTearDownCleanup() self.check_objc_breakpoints(False) def setUp(self): # Call super's setUp(). TestBase.setUp(self) # Find the line number to break inside main(). self.main_source = "main.m" self.line = line_number(self.main_source, "// Set breakpoint here") def check_category_breakpoints(self): name_bp = self.target.BreakpointCreateByName("myCategoryFunction") selector_bp = self.target.BreakpointCreateByName( "myCategoryFunction", lldb.eFunctionNameTypeSelector, lldb.SBFileSpecList(), lldb.SBFileSpecList(), ) self.assertEqual( 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.assertEqual( 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.assertEqual( 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.assertEqual( 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 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 = self.getBuildArtifact("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.assertGreaterEqual( 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.assertGreater( 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.assertEqual( 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.assertEqual( 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()