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