xref: /llvm-project/lldb/test/API/lang/c/bitfields/TestBitfields.py (revision 2238dcc39358353cac21df75c3c3286ab20b8f53)
1"""Test C bitfields."""
2
3
4import lldb
5from lldbsuite.test.decorators import *
6from lldbsuite.test.lldbtest import *
7from lldbsuite.test import lldbutil
8
9
10class TestCase(TestBase):
11    def run_to_main(self):
12        self.build()
13        lldbutil.run_to_source_breakpoint(
14            self, "// break here", lldb.SBFileSpec("main.c")
15        )
16
17    # BitFields exhibit crashes in record layout on Windows
18    # (http://llvm.org/pr21800)
19    @skipIfWindows
20    def test_bits(self):
21        self.run_to_main()
22
23        # Check each field of Bits.
24        bits_children = [
25            ValueCheck(type="int:1"),  # Unnamed and uninitialized
26            ValueCheck(type="uint32_t:1", name="b1", value="1"),
27            ValueCheck(type="uint32_t:2", name="b2", value="3"),
28            ValueCheck(type="int:2"),  # Unnamed and uninitialized
29            ValueCheck(type="uint32_t:3", name="b3", value="7"),
30            ValueCheck(type="uint32_t", name="b4", value="15"),
31            ValueCheck(type="uint32_t:5", name="b5", value="31"),
32            ValueCheck(type="uint32_t:6", name="b6", value="63"),
33            ValueCheck(type="uint32_t:7", name="b7", value="127"),
34            ValueCheck(type="uint32_t:4", name="four", value="15"),
35        ]
36        self.expect_var_path("bits", type="Bits", children=bits_children)
37        self.expect_expr("bits", result_children=bits_children)
38
39        # Try accessing the different fields using the expression evaluator.
40        self.expect_expr("bits.b1", result_type="uint32_t", result_value="1")
41        self.expect_expr("bits.b2", result_type="uint32_t", result_value="3")
42        self.expect_expr("bits.b3", result_type="uint32_t", result_value="7")
43        self.expect_expr("bits.b4", result_type="uint32_t", result_value="15")
44        self.expect_expr("bits.b5", result_type="uint32_t", result_value="31")
45        self.expect_expr("bits.b6", result_type="uint32_t", result_value="63")
46        self.expect_expr("bits.b7", result_type="uint32_t", result_value="127")
47        self.expect_expr("bits.four", result_type="uint32_t", result_value="15")
48
49        # Try accessing the different fields using variable paths.
50        self.expect_var_path("bits.b1", type="uint32_t:1", value="1")
51        self.expect_var_path("bits.b2", type="uint32_t:2", value="3")
52        self.expect_var_path("bits.b4", type="uint32_t", value="15")
53        self.expect_var_path("bits.b5", type="uint32_t:5", value="31")
54        self.expect_var_path("bits.b7", type="uint32_t:7", value="127")
55
56        # Check each field of MoreBits.
57        more_bits_children = [
58            ValueCheck(type="uint32_t:3", name="a", value="3"),
59            ValueCheck(type="int:1", value="0"),
60            ValueCheck(type="uint8_t:1", name="b", value="'\\0'"),
61            ValueCheck(type="uint8_t:1", name="c", value="'\\x01'"),
62            ValueCheck(type="uint8_t:1", name="d", value="'\\0'"),
63        ]
64        self.expect_var_path("more_bits", type="MoreBits", children=more_bits_children)
65        self.expect_expr("more_bits", result_children=more_bits_children)
66
67        self.expect_expr("more_bits.a", result_type="uint32_t", result_value="3")
68        self.expect_expr("more_bits.b", result_type="uint8_t", result_value="'\\0'")
69        self.expect_expr("more_bits.c", result_type="uint8_t", result_value="'\\x01'")
70        self.expect_expr("more_bits.d", result_type="uint8_t", result_value="'\\0'")
71
72        # Test a struct with several single bit fields.
73        many_single_bits_children = [
74            ValueCheck(type="uint16_t:1", name="b1", value="1"),
75            ValueCheck(type="uint16_t:1", name="b2", value="0"),
76            ValueCheck(type="uint16_t:1", name="b3", value="0"),
77            ValueCheck(type="uint16_t:1", name="b4", value="0"),
78            ValueCheck(type="uint16_t:1", name="b5", value="1"),
79            ValueCheck(type="uint16_t:1", name="b6", value="0"),
80            ValueCheck(type="uint16_t:1", name="b7", value="1"),
81            ValueCheck(type="uint16_t:1", name="b8", value="0"),
82            ValueCheck(type="uint16_t:1", name="b9", value="0"),
83            ValueCheck(type="uint16_t:1", name="b10", value="0"),
84            ValueCheck(type="uint16_t:1", name="b11", value="0"),
85            ValueCheck(type="uint16_t:1", name="b12", value="0"),
86            ValueCheck(type="uint16_t:1", name="b13", value="1"),
87            ValueCheck(type="uint16_t:1", name="b14", value="0"),
88            ValueCheck(type="uint16_t:1", name="b15", value="0"),
89            ValueCheck(type="uint16_t:1", name="b16", value="0"),
90            ValueCheck(type="uint16_t:1", name="b17", value="0"),
91        ]
92        self.expect_var_path(
93            "many_single_bits",
94            type="ManySingleBits",
95            children=many_single_bits_children,
96        )
97        self.expect_expr(
98            "many_single_bits",
99            result_type="ManySingleBits",
100            result_children=many_single_bits_children,
101        )
102
103        # Check a packed struct.
104        self.expect_expr("packed.a", result_type="char", result_value="'a'")
105        self.expect_expr("packed.b", result_type="uint32_t", result_value="10")
106        self.expect_expr(
107            "packed.c", result_type="uint32_t", result_value=str(int("7112233", 16))
108        )
109
110        # A packed struct with bitfield size > 32.
111        self.expect(
112            "v/x large_packed",
113            VARIABLES_DISPLAYED_CORRECTLY,
114            substrs=["a = 0x0000000cbbbbaaaa", "b = 0x0000000dffffeee"],
115        )
116
117        # Check reading a bitfield through a pointer in various ways (PR47743)
118        self.expect(
119            "v/x large_packed_ptr->b",
120            substrs=["large_packed_ptr->b = 0x0000000dffffeeee"],
121        )
122        self.expect(
123            "v/x large_packed_ptr[0].b",
124            substrs=["large_packed_ptr[0].b = 0x0000000dffffeeee"],
125        )
126
127    # BitFields exhibit crashes in record layout on Windows
128    # (http://llvm.org/pr21800)
129    @skipIfWindows
130    def test_expression_bug(self):
131        # Ensure evaluating (emulating) an expression does not break bitfield
132        # values for already parsed variables. The expression is run twice
133        # because the very first expression can resume a target (to allocate
134        # memory, etc.) even if it is not being jitted.
135        self.run_to_main()
136
137        self.expect(
138            "v/x large_packed",
139            VARIABLES_DISPLAYED_CORRECTLY,
140            substrs=["a = 0x0000000cbbbbaaaa", "b = 0x0000000dffffeee"],
141        )
142        self.expect(
143            "expr --allow-jit false  -- more_bits.a",
144            VARIABLES_DISPLAYED_CORRECTLY,
145            substrs=["uint32_t", "3"],
146        )
147        self.expect(
148            "v/x large_packed",
149            VARIABLES_DISPLAYED_CORRECTLY,
150            substrs=["a = 0x0000000cbbbbaaaa", "b = 0x0000000dffffeee"],
151        )
152        self.expect(
153            "expr --allow-jit false  -- more_bits.a",
154            VARIABLES_DISPLAYED_CORRECTLY,
155            substrs=["uint32_t", "3"],
156        )
157        self.expect(
158            "v/x large_packed",
159            VARIABLES_DISPLAYED_CORRECTLY,
160            substrs=["a = 0x0000000cbbbbaaaa", "b = 0x0000000dffffeee"],
161        )
162
163    @add_test_categories(["pyapi"])
164    # BitFields exhibit crashes in record layout on Windows
165    # (http://llvm.org/pr21800)
166    @skipIfWindows
167    def test_and_python_api(self):
168        """Use Python APIs to inspect a bitfields variable."""
169        self.run_to_main()
170
171        # Lookup the "bits" variable which contains 8 bitfields.
172        bits = self.frame().FindVariable("bits")
173        self.DebugSBValue(bits)
174        self.assertEqual(bits.GetTypeName(), "Bits")
175        self.assertEqual(bits.GetNumChildren(), 10)
176        self.assertEqual(bits.GetByteSize(), 32)
177
178        # Notice the pattern of int(b1.GetValue(), 0).  We pass a base of 0
179        # so that the proper radix is determined based on the contents of the
180        # string.
181        b1 = bits.GetChildMemberWithName("b1")
182        self.DebugSBValue(b1)
183        self.assertEqual(b1.GetName(), "b1")
184        self.assertEqual(b1.GetTypeName(), "uint32_t:1")
185        self.assertTrue(b1.IsInScope())
186        self.assertEqual(int(b1.GetValue(), 0), 1)
187
188        b7 = bits.GetChildMemberWithName("b7")
189        self.assertEqual(b7.GetName(), "b7")
190        self.assertEqual(b7.GetTypeName(), "uint32_t:7")
191        self.assertTrue(b7.IsInScope())
192        self.assertEqual(int(b7.GetValue(), 0), 127)
193
194        four = bits.GetChildMemberWithName("four")
195        self.assertEqual(four.GetName(), "four")
196        self.assertEqual(four.GetTypeName(), "uint32_t:4")
197        self.assertTrue(four.IsInScope())
198        self.assertEqual(int(four.GetValue(), 0), 15)
199