1 """Check that compiler-generated register values work correctly"""
5 from lldbsuite
.test
.decorators
import *
6 from lldbsuite
.test
.lldbtest
import *
7 from lldbsuite
.test
import lldbutil
10 def re_expr_equals(val_type
, val
):
11 # Match ({val_type}) ${sum_digits} = {val}
12 return re
.compile(r
"\(" + val_type
+ "\) \$\d+ = " + str(val
))
15 class RegisterVariableTestCase(TestBase
):
16 @expectedFailureAll(compiler
="clang", compiler_version
=["<", "3.5"])
18 compiler
="gcc", compiler_version
=[">=", "4.8.2"], archs
=["i386"]
20 @expectedFailureAll(compiler
="gcc", compiler_version
=["<", "4.9"], archs
=["x86_64"])
21 def test_and_run_command(self
):
22 """Test expressions on register values."""
24 # This test now ensures that each probable
25 # register variable location is actually a register, and
26 # if so, whether we can print out the variable there.
27 # It only requires one of them to be handled in a non-error
29 register_variables_count
= 0
32 exe
= self
.getBuildArtifact("a.out")
33 self
.runCmd("file " + exe
, CURRENT_EXECUTABLE_SET
)
35 # Break inside the main.
36 lldbutil
.run_break_set_by_source_regexp(self
, "break", num_expected_locations
=3)
41 self
.runCmd("run", RUN_SUCCEEDED
)
43 # The stop reason of the thread should be breakpoint.
46 STOPPED_DUE_TO_BREAKPOINT
,
47 substrs
=["stopped", "stop reason = breakpoint"],
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
=1
55 # Try some variables that should be visible
57 self
.dbg
.GetSelectedTarget()
62 if self
.is_variable_in_register(frame
, "a"):
63 register_variables_count
+= 1
66 VARIABLES_DISPLAYED_CORRECTLY
,
67 patterns
=[re_expr_equals("int", 2)],
70 if self
.is_struct_pointer_in_register(frame
, "b", self
.TraceOn()):
71 register_variables_count
+= 1
74 VARIABLES_DISPLAYED_CORRECTLY
,
75 patterns
=[re_expr_equals("int", 3)],
81 self
.runCmd("continue")
83 # The stop reason of the thread should be breakpoint.
86 STOPPED_DUE_TO_BREAKPOINT
,
87 substrs
=["stopped", "stop reason = breakpoint"],
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
=1
95 # Try some variables that should be visible
97 self
.dbg
.GetSelectedTarget()
102 if self
.is_struct_pointer_in_register(frame
, "b", self
.TraceOn()):
103 register_variables_count
+= 1
106 VARIABLES_DISPLAYED_CORRECTLY
,
107 patterns
=[re_expr_equals("int", 5)],
110 if self
.is_variable_in_register(frame
, "c"):
111 register_variables_count
+= 1
114 VARIABLES_DISPLAYED_CORRECTLY
,
115 patterns
=[re_expr_equals("int", 5)],
118 #####################
121 self
.runCmd("continue")
123 # The stop reason of the thread should be breakpoint.
126 STOPPED_DUE_TO_BREAKPOINT
,
127 substrs
=["stopped", "stop reason = breakpoint"],
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
=1
135 # Try some variables that should be visible
137 self
.dbg
.GetSelectedTarget()
142 if self
.is_variable_in_register(frame
, "f"):
143 register_variables_count
+= 1
146 VARIABLES_DISPLAYED_CORRECTLY
,
147 patterns
=[re_expr_equals("float", "3.1")],
150 # Validate that we verified at least one register variable
152 register_variables_count
> 0,
153 "expected to verify at least one variable in a register",
156 "executed {} expressions with values in registers".format(
157 register_variables_count
163 def is_variable_in_register(self
, frame
, var_name
):
164 # Ensure we can lookup the variable.
165 var
= frame
.FindVariable(var_name
)
166 self
.trace("\nchecking {}...".format(var_name
))
167 if var
is None or not var
.IsValid():
168 self
.trace("{} cannot be found".format(var_name
))
171 # Check that we can get its value. If not, this
172 # may be a variable that is just out of scope at this point.
173 value
= var
.GetValue()
174 self
.trace("checking value...")
176 self
.trace("value is invalid")
179 self
.trace("value is {}".format(value
))
181 # We have a variable and we can get its value. The variable is in a
182 # register if we cannot get an address for it, assuming it is not a
183 # struct pointer. (This is an approximation - compilers can do other
184 # things with spitting up a value into multiple parts of multiple
185 # registers, but what we're verifying here is much more than it was
187 var_addr
= var
.GetAddress()
188 self
.trace("checking address...")
189 if var_addr
.IsValid():
190 # We have an address, it must not be in a register.
192 "var {} is not in a register: has a valid address {}".format(
198 # We don't have an address but we can read the value.
199 # It is likely stored in a register.
201 "var {} is in a register (we don't have an address for it)".format(
207 def is_struct_pointer_in_register(self
, frame
, var_name
, trace
):
208 # Ensure we can lookup the variable.
209 var
= frame
.FindVariable(var_name
)
211 print("\nchecking {}...".format(var_name
))
213 if var
is None or not var
.IsValid():
214 self
.trace("{} cannot be found".format(var_name
))
217 # Check that we can get its value. If not, this
218 # may be a variable that is just out of scope at this point.
219 value
= var
.GetValue()
220 self
.trace("checking value...")
223 print("value is invalid")
227 print("value is {}".format(value
))
229 var_loc
= var
.GetLocation()
231 print("checking location: {}".format(var_loc
))
232 if var_loc
is None or var_loc
.startswith("0x"):
233 # The frame var is not in a register but rather a memory location.
234 self
.trace("frame var {} is not in a register".format(var_name
))
237 self
.trace("frame var {} is in a register".format(var_name
))