1""" 2Test that objective-c constant strings are generated correctly by the expression 3parser. 4""" 5 6 7 8import shutil 9import subprocess 10import lldb 11from lldbsuite.test.decorators import * 12from lldbsuite.test.lldbtest import * 13from lldbsuite.test import lldbutil 14 15 16class TestObjCBreakpoints(TestBase): 17 18 mydir = TestBase.compute_mydir(__file__) 19 20 @add_test_categories(["objc"]) 21 def test_break(self): 22 """Test setting Objective-C specific breakpoints (DWARF in .o files).""" 23 self.build() 24 self.setTearDownCleanup() 25 self.check_objc_breakpoints(False) 26 27 def setUp(self): 28 # Call super's setUp(). 29 TestBase.setUp(self) 30 # Find the line number to break inside main(). 31 self.main_source = "main.m" 32 self.line = line_number(self.main_source, '// Set breakpoint here') 33 34 def check_category_breakpoints(self): 35 name_bp = self.target.BreakpointCreateByName("myCategoryFunction") 36 selector_bp = self.target.BreakpointCreateByName( 37 "myCategoryFunction", 38 lldb.eFunctionNameTypeSelector, 39 lldb.SBFileSpecList(), 40 lldb.SBFileSpecList()) 41 self.assertEqual( 42 name_bp.GetNumLocations(), selector_bp.GetNumLocations(), 43 'Make sure setting a breakpoint by name "myCategoryFunction" sets a breakpoint even though it is in a category') 44 for bp_loc in selector_bp: 45 function_name = bp_loc.GetAddress().GetSymbol().GetName() 46 self.assertTrue( 47 " myCategoryFunction]" in function_name, 48 'Make sure all function names have " myCategoryFunction]" in their names') 49 50 category_bp = self.target.BreakpointCreateByName( 51 "-[MyClass(MyCategory) myCategoryFunction]") 52 stripped_bp = self.target.BreakpointCreateByName( 53 "-[MyClass myCategoryFunction]") 54 stripped2_bp = self.target.BreakpointCreateByName( 55 "[MyClass myCategoryFunction]") 56 self.assertEqual( 57 category_bp.GetNumLocations(), 1, 58 "Make sure we can set a breakpoint using a full objective C function name with the category included (-[MyClass(MyCategory) myCategoryFunction])") 59 self.assertEqual( 60 stripped_bp.GetNumLocations(), 1, 61 "Make sure we can set a breakpoint using a full objective C function name without the category included (-[MyClass myCategoryFunction])") 62 self.assertEqual( 63 stripped2_bp.GetNumLocations(), 1, 64 "Make sure we can set a breakpoint using a full objective C function name without the category included ([MyClass myCategoryFunction])") 65 66 def check_objc_breakpoints(self, have_dsym): 67 """Test constant string generation amd comparison by the expression parser.""" 68 69 # Set debugger into synchronous mode 70 self.dbg.SetAsync(False) 71 72 # Create a target by the debugger. 73 exe = self.getBuildArtifact("a.out") 74 self.target = self.dbg.CreateTarget(exe) 75 self.assertTrue(self.target, VALID_TARGET) 76 77 #---------------------------------------------------------------------- 78 # Set breakpoints on all selectors whose name is "count". This should 79 # catch breakpoints that are both C functions _and_ anything whose 80 # selector is "count" because just looking at "count" we can't tell 81 # definitively if the name is a selector or a C function 82 #---------------------------------------------------------------------- 83 name_bp = self.target.BreakpointCreateByName("count") 84 selector_bp = self.target.BreakpointCreateByName( 85 "count", 86 lldb.eFunctionNameTypeSelector, 87 lldb.SBFileSpecList(), 88 lldb.SBFileSpecList()) 89 self.assertGreaterEqual( 90 name_bp.GetNumLocations(), selector_bp.GetNumLocations(), 91 'Make sure we get at least the same amount of breakpoints if not more when setting by name "count"') 92 self.assertGreater( 93 selector_bp.GetNumLocations(), 50, 94 'Make sure we find a lot of "count" selectors') # There are 93 on the latest MacOSX 95 for bp_loc in selector_bp: 96 function_name = bp_loc.GetAddress().GetSymbol().GetName() 97 self.assertTrue( 98 " count]" in function_name, 99 'Make sure all function names have " count]" in their names') 100 101 #---------------------------------------------------------------------- 102 # Set breakpoints on all selectors whose name is "isEqual:". This should 103 # catch breakpoints that are only ObjC selectors because no C function 104 # can end with a : 105 #---------------------------------------------------------------------- 106 name_bp = self.target.BreakpointCreateByName("isEqual:") 107 selector_bp = self.target.BreakpointCreateByName( 108 "isEqual:", 109 lldb.eFunctionNameTypeSelector, 110 lldb.SBFileSpecList(), 111 lldb.SBFileSpecList()) 112 self.assertEqual( 113 name_bp.GetNumLocations(), selector_bp.GetNumLocations(), 114 'Make sure setting a breakpoint by name "isEqual:" only sets selector breakpoints') 115 for bp_loc in selector_bp: 116 function_name = bp_loc.GetAddress().GetSymbol().GetName() 117 self.assertTrue( 118 " isEqual:]" in function_name, 119 'Make sure all function names have " isEqual:]" in their names') 120 121 self.check_category_breakpoints() 122 123 # Stop here for reproducers. They don't capture file system changes. 124 if configuration.is_reproducer(): 125 return 126 127 if have_dsym: 128 shutil.rmtree(exe + ".dSYM") 129 self.assertEqual(subprocess.call( 130 ['/usr/bin/strip', '-Sx', exe]), 0, 'stripping dylib succeeded') 131 132 # Check breakpoints again, this time using the symbol table only 133 self.check_category_breakpoints() 134