brintos

brintos / llvm-project-archived public Read only

0
0
Text · 11.4 KiB · e82cb2f Raw
347 lines · python
1"""2Set breakpoints on objective-c class and instance methods in foundation.3Also lookup objective-c data types and evaluate expressions.4"""5 6import os7import os.path8import lldb9from lldbsuite.test.decorators import *10from lldbsuite.test.lldbtest import *11from lldbsuite.test import lldbutil12 13file_index = 014 15 16class FoundationTestCase(TestBase):17    def setUp(self):18        # Call super's setUp().19        TestBase.setUp(self)20        # Find the line number to break inside main().21        self.main_source = "main.m"22        self.line = line_number(self.main_source, "// Set break point at this line.")23 24    def test_break(self):25        """Test setting objc breakpoints using '_regexp-break' and 'breakpoint set'."""26        self.build()27        exe = self.getBuildArtifact("a.out")28        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)29 30        # Stop at +[NSString stringWithFormat:].31        break_results = lldbutil.run_break_set_command(32            self, "_regexp-break +[NSString stringWithFormat:]"33        )34        lldbutil.check_breakpoint_result(35            self,36            break_results,37            symbol_name="+[NSString stringWithFormat:]",38            num_locations=1,39        )40 41        # Stop at -[MyString initWithNSString:].42        lldbutil.run_break_set_by_symbol(43            self,44            "-[MyString initWithNSString:]",45            num_expected_locations=1,46            sym_exact=True,47        )48 49        # Stop at the "description" selector.50        lldbutil.run_break_set_by_selector(51            self, "description", num_expected_locations=1, module_name="a.out"52        )53 54        # Stop at -[NSAutoreleasePool release].55        break_results = lldbutil.run_break_set_command(56            self, "_regexp-break -[NSAutoreleasePool release]"57        )58        lldbutil.check_breakpoint_result(59            self,60            break_results,61            symbol_name="-[NSAutoreleasePool release]",62            num_locations=1,63        )64 65        self.runCmd("run", RUN_SUCCEEDED)66 67        # First stop is +[NSString stringWithFormat:].68        self.expect(69            "thread backtrace",70            "Stop at +[NSString stringWithFormat:]",71            substrs=["Foundation`+[NSString stringWithFormat:]"],72        )73 74        self.runCmd("process continue")75 76        # Second stop is still +[NSString stringWithFormat:].77        self.expect(78            "thread backtrace",79            "Stop at +[NSString stringWithFormat:]",80            substrs=["Foundation`+[NSString stringWithFormat:]"],81        )82 83        self.runCmd("process continue")84 85        # Followed by a.out`-[MyString initWithNSString:].86        self.expect(87            "thread backtrace",88            "Stop at a.out`-[MyString initWithNSString:]",89            substrs=["a.out`-[MyString initWithNSString:]"],90        )91 92        self.runCmd("process continue")93 94        # Followed by -[MyString description].95        self.expect(96            "thread backtrace",97            "Stop at -[MyString description]",98            substrs=["a.out`-[MyString description]"],99        )100 101        self.runCmd("process continue")102 103        # Followed by the same -[MyString description].104        self.expect(105            "thread backtrace",106            "Stop at -[MyString description]",107            substrs=["a.out`-[MyString description]"],108        )109 110        self.runCmd("process continue")111 112        # Followed by -[NSAutoreleasePool release].113        self.expect(114            "thread backtrace",115            "Stop at -[NSAutoreleasePool release]",116            substrs=["Foundation`-[NSAutoreleasePool release]"],117        )118 119    # rdar://problem/8542091120    # rdar://problem/8492646121    def test_data_type_and_expr(self):122        """Lookup objective-c data types and evaluate expressions."""123        self.build()124        exe = self.getBuildArtifact("a.out")125        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)126 127        # Stop at -[MyString description].128        lldbutil.run_break_set_by_symbol(129            self, "-[MyString description]", num_expected_locations=1, sym_exact=True130        )131        #        self.expect("breakpoint set -n '-[MyString description]", BREAKPOINT_CREATED,132        # startstr = "Breakpoint created: 1: name = '-[MyString description]',133        # locations = 1")134 135        self.runCmd("run", RUN_SUCCEEDED)136 137        self.runCmd("settings set target.prefer-dynamic-value no-dynamic-values")138 139        # The backtrace should show we stop at -[MyString description].140        self.expect(141            "thread backtrace",142            "Stop at -[MyString description]",143            substrs=["a.out`-[MyString description]"],144        )145 146        # Lookup objc data type MyString and evaluate some expressions.147 148        self.expect(149            "image lookup -t NSString",150            DATA_TYPES_DISPLAYED_CORRECTLY,151            substrs=['name = "NSString"', 'compiler_type = "@interface NSString'],152        )153 154        self.expect(155            "image lookup -t MyString",156            DATA_TYPES_DISPLAYED_CORRECTLY,157            substrs=[158                'name = "MyString"',159                'compiler_type = "@interface MyString',160                "NSString * str;",161                "NSDate * date;",162            ],163        )164 165        self.expect(166            "frame variable --show-types --scope",167            VARIABLES_DISPLAYED_CORRECTLY,168            substrs=["ARG: (MyString *) self"],169            patterns=[r"ARG: \(SEL|objc_selector \*\) _cmd"],170        )171 172        # rdar://problem/8651752173        # don't crash trying to ask clang how many children an empty record has174        self.runCmd("frame variable *_cmd")175 176        # rdar://problem/8492646177        # test/foundation fails after updating to tot r115023178        # self->str displays nothing as output179        self.expect(180            "frame variable --show-types self->str",181            VARIABLES_DISPLAYED_CORRECTLY,182            startstr="(NSString *) self->str",183        )184 185        # rdar://problem/8447030186        # 'frame variable self->date' displays the wrong data member187        self.expect(188            "frame variable --show-types self->date",189            VARIABLES_DISPLAYED_CORRECTLY,190            startstr="(NSDate *) self->date",191        )192 193        # This should display the str and date member fields as well.194        self.expect(195            "frame variable --show-types *self",196            VARIABLES_DISPLAYED_CORRECTLY,197            substrs=["(MyString) *self", "(NSString *) str", "(NSDate *) date"],198        )199 200        # isa should be accessible.201        self.expect(202            "expression self->isa", VARIABLES_DISPLAYED_CORRECTLY, substrs=["Class)"]203        )204 205        # This should fail expectedly.206        self.expect(207            "expression self->non_existent_member",208            COMMAND_FAILED_AS_EXPECTED,209            error=True,210            substrs=[211                "error:",212                "'MyString' does not have a member named 'non_existent_member'",213            ],214        )215 216        # Use expression parser.217        self.runCmd("expression self->str")218        self.runCmd("expression self->date")219 220        # (lldb) expression self->str221        # error: instance variable 'str' is protected222        # error: 1 errors parsing expression223        #224        # (lldb) expression self->date225        # error: instance variable 'date' is protected226        # error: 1 errors parsing expression227        #228 229        self.runCmd("breakpoint delete 1")230        lldbutil.run_break_set_by_file_and_line(231            self, "main.m", self.line, num_expected_locations=1, loc_exact=True232        )233 234        self.runCmd("process continue")235 236        # rdar://problem/8542091237        # test/foundation: expr -o -- my not working?238        #239        # Test new feature with r115115:240        # Add "-o" option to "expression" which prints the object description241        # if available.242        self.expect(243            "expression --object-description -- my",244            "Object description displayed correctly",245            patterns=["Hello from.*a.out.*with timestamp: "],246        )247 248    @add_test_categories(["pyapi"])249    def test_print_ivars_correctly(self):250        self.build()251        # See: <rdar://problem/8717050> lldb needs to use the ObjC runtime symbols for ivar offsets252        # Only fails for the ObjC 2.0 runtime.253        exe = self.getBuildArtifact("a.out")254 255        target = self.dbg.CreateTarget(exe)256        self.assertTrue(target, VALID_TARGET)257 258        break1 = target.BreakpointCreateByLocation(self.main_source, self.line)259        self.assertTrue(break1, VALID_BREAKPOINT)260 261        # Now launch the process, and do not stop at entry point.262        process = target.LaunchSimple(None, None, self.get_process_working_directory())263 264        self.assertTrue(process, PROCESS_IS_VALID)265 266        # The stop reason of the thread should be breakpoint.267        thread = process.GetThreadAtIndex(0)268        if thread.GetStopReason() != lldb.eStopReasonBreakpoint:269            from lldbsuite.test.lldbutil import stop_reason_to_str270 271            self.fail(272                STOPPED_DUE_TO_BREAKPOINT_WITH_STOP_REASON_AS273                % stop_reason_to_str(thread.GetStopReason())274            )275 276        # Make sure we stopped at the first breakpoint.277 278        cur_frame = thread.GetFrameAtIndex(0)279 280        line_number = cur_frame.GetLineEntry().GetLine()281        self.assertEqual(line_number, self.line, "Hit the first breakpoint.")282 283        my_var = cur_frame.FindVariable("my")284        self.assertTrue(my_var, "Made a variable object for my")285 286        str_var = cur_frame.FindVariable("str")287        self.assertTrue(str_var, "Made a variable object for str")288 289        # Now make sure that the my->str == str:290 291        my_str_var = my_var.GetChildMemberWithName("str")292        self.assertTrue(my_str_var, "Found a str ivar in my")293 294        str_value = int(str_var.GetValue(), 0)295 296        my_str_value = int(my_str_var.GetValue(), 0)297 298        self.assertEqual(str_value, my_str_value, "Got the correct value for my->str")299 300    def test_expression_lookups_objc(self):301        """Test running an expression detect spurious debug info lookups (DWARF)."""302        self.build()303        exe = self.getBuildArtifact("a.out")304        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)305 306        # Stop at -[MyString initWithNSString:].307        lldbutil.run_break_set_by_symbol(308            self,309            "-[MyString initWithNSString:]",310            num_expected_locations=1,311            sym_exact=True,312        )313 314        self.runCmd("run", RUN_SUCCEEDED)315 316        global file_index317        # Log any DWARF lookups318        ++file_index319        logfile = os.path.join(320            self.getBuildDir(),321            "dwarf-lookups-" + self.getArchitecture() + "-" + str(file_index) + ".txt",322        )323        self.runCmd("log enable -f %s dwarf lookups" % (logfile))324        self.runCmd("expr self")325        self.runCmd("log disable dwarf lookups")326 327        def cleanup():328            if os.path.exists(logfile):329                os.unlink(logfile)330 331        self.addTearDownHook(cleanup)332 333        if os.path.exists(logfile):334            f = open(logfile)335            lines = f.readlines()336            num_errors = 0337            for line in lines:338                if "$__lldb" in line:339                    if num_errors == 0:340                        print(341                            "error: found spurious name lookups when evaluating an expression:"342                        )343                    num_errors += 1344                    print(line, end="")345            self.assertEqual(num_errors, 0, "Spurious lookups detected")346            f.close()347