| """ | |
| Test that objective-c constant strings are generated correctly by the expression | |
| parser. | |
| """ | |
| from __future__ import print_function | |
| import shutil | |
| import subprocess | |
| import lldb | |
| from lldbsuite.test.decorators import * | |
| from lldbsuite.test.lldbtest import * | |
| from lldbsuite.test import lldbutil | |
| @skipUnlessDarwin | |
| class TestObjCBreakpoints(TestBase): | |
| mydir = TestBase.compute_mydir(__file__) | |
| 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.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 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.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() |