brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.0 KiB · bcdd590 Raw
240 lines · python
1"""Check that compiler-generated register values work correctly"""2 3import re4import lldb5from lldbsuite.test.decorators import *6from lldbsuite.test.lldbtest import *7from lldbsuite.test import lldbutil8 9 10def re_expr_equals(val_type, val):11    # Match ({val_type}) ${sum_digits} = {val}12    return re.compile(r"\(" + val_type + r"\) \$\d+ = " + str(val))13 14 15class RegisterVariableTestCase(TestBase):16    @expectedFailureAll(compiler="clang", compiler_version=["<", "3.5"])17    @expectedFailureAll(18        compiler="gcc", compiler_version=[">=", "4.8.2"], archs=["i386"]19    )20    @expectedFailureAll(compiler="gcc", compiler_version=["<", "4.9"], archs=["x86_64"])21    def test_and_run_command(self):22        """Test expressions on register values."""23 24        # This test now ensures that each probable25        # register variable location is actually a register, and26        # if so, whether we can print out the variable there.27        # It only requires one of them to be handled in a non-error28        # way.29        register_variables_count = 030 31        self.build()32        exe = self.getBuildArtifact("a.out")33        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)34 35        # Break inside the main.36        lldbutil.run_break_set_by_source_regexp(self, "break", num_expected_locations=3)37 38        ####################39        # First breakpoint40 41        self.runCmd("run", RUN_SUCCEEDED)42 43        # The stop reason of the thread should be breakpoint.44        self.expect(45            "thread list",46            STOPPED_DUE_TO_BREAKPOINT,47            substrs=["stopped", "stop reason = breakpoint"],48        )49 50        # The breakpoint should have a hit count of 1.51        lldbutil.check_breakpoint(52            self, bpno=1, location_id=1, expected_location_hit_count=153        )54 55        # Try some variables that should be visible56        frame = (57            self.dbg.GetSelectedTarget()58            .GetProcess()59            .GetSelectedThread()60            .GetSelectedFrame()61        )62        if self.is_variable_in_register(frame, "a"):63            register_variables_count += 164            self.expect(65                "expr a",66                VARIABLES_DISPLAYED_CORRECTLY,67                patterns=[re_expr_equals("int", 2)],68            )69 70        if self.is_struct_pointer_in_register(frame, "b", self.TraceOn()):71            register_variables_count += 172            self.expect(73                "expr b->m1",74                VARIABLES_DISPLAYED_CORRECTLY,75                patterns=[re_expr_equals("int", 3)],76            )77 78        #####################79        # Second breakpoint80 81        self.runCmd("continue")82 83        # The stop reason of the thread should be breakpoint.84        self.expect(85            "thread list",86            STOPPED_DUE_TO_BREAKPOINT,87            substrs=["stopped", "stop reason = breakpoint"],88        )89 90        # The breakpoint should have a hit count of 1.91        lldbutil.check_breakpoint(92            self, bpno=1, location_id=2, expected_location_hit_count=193        )94 95        # Try some variables that should be visible96        frame = (97            self.dbg.GetSelectedTarget()98            .GetProcess()99            .GetSelectedThread()100            .GetSelectedFrame()101        )102        if self.is_struct_pointer_in_register(frame, "b", self.TraceOn()):103            register_variables_count += 1104            self.expect(105                "expr b->m2",106                VARIABLES_DISPLAYED_CORRECTLY,107                patterns=[re_expr_equals("int", 5)],108            )109 110        if self.is_variable_in_register(frame, "c"):111            register_variables_count += 1112            self.expect(113                "expr c",114                VARIABLES_DISPLAYED_CORRECTLY,115                patterns=[re_expr_equals("int", 5)],116            )117 118        #####################119        # Third breakpoint120 121        self.runCmd("continue")122 123        # The stop reason of the thread should be breakpoint.124        self.expect(125            "thread list",126            STOPPED_DUE_TO_BREAKPOINT,127            substrs=["stopped", "stop reason = breakpoint"],128        )129 130        # The breakpoint should have a hit count of 1.131        lldbutil.check_breakpoint(132            self, bpno=1, location_id=3, expected_location_hit_count=1133        )134 135        # Try some variables that should be visible136        frame = (137            self.dbg.GetSelectedTarget()138            .GetProcess()139            .GetSelectedThread()140            .GetSelectedFrame()141        )142        if self.is_variable_in_register(frame, "f"):143            register_variables_count += 1144            self.expect(145                "expr f",146                VARIABLES_DISPLAYED_CORRECTLY,147                patterns=[re_expr_equals("float", "3.1")],148            )149 150        # Validate that we verified at least one register variable151        self.assertGreater(152            register_variables_count,153            0,154            "expected to verify at least one variable in a register",155        )156        self.trace(157            "executed {} expressions with values in registers".format(158                register_variables_count159            )160        )161 162        self.runCmd("kill")163 164    def is_variable_in_register(self, frame, var_name):165        # Ensure we can lookup the variable.166        var = frame.FindVariable(var_name)167        self.trace("\nchecking {}...".format(var_name))168        if var is None or not var.IsValid():169            self.trace("{} cannot be found".format(var_name))170            return False171 172        # Check that we can get its value.  If not, this173        # may be a variable that is just out of scope at this point.174        value = var.GetValue()175        self.trace("checking value...")176        if value is None:177            self.trace("value is invalid")178            return False179        else:180            self.trace("value is {}".format(value))181 182        # We have a variable and we can get its value.  The variable is in a183        # register if we cannot get an address for it, assuming it is not a184        # struct pointer.  (This is an approximation - compilers can do other185        # things with spitting up a value into multiple parts of multiple186        # registers, but what we're verifying here is much more than it was187        # doing before).188        var_addr = var.GetAddress()189        self.trace("checking address...")190        if var_addr.IsValid():191            # We have an address, it must not be in a register.192            self.trace(193                "var {} is not in a register: has a valid address {}".format(194                    var_name, var_addr195                )196            )197            return False198        else:199            # We don't have an address but we can read the value.200            # It is likely stored in a register.201            self.trace(202                "var {} is in a register (we don't have an address for it)".format(203                    var_name204                )205            )206            return True207 208    def is_struct_pointer_in_register(self, frame, var_name, trace):209        # Ensure we can lookup the variable.210        var = frame.FindVariable(var_name)211        if trace:212            print("\nchecking {}...".format(var_name))213 214        if var is None or not var.IsValid():215            self.trace("{} cannot be found".format(var_name))216            return False217 218        # Check that we can get its value.  If not, this219        # may be a variable that is just out of scope at this point.220        value = var.GetValue()221        self.trace("checking value...")222        if value is None:223            if trace:224                print("value is invalid")225            return False226        else:227            if trace:228                print("value is {}".format(value))229 230        var_loc = var.GetLocation()231        if trace:232            print("checking location: {}".format(var_loc))233        if var_loc is None or var_loc.startswith("0x"):234            # The frame var is not in a register but rather a memory location.235            self.trace("frame var {} is not in a register".format(var_name))236            return False237        else:238            self.trace("frame var {} is in a register".format(var_name))239            return True240