xref: /llvm-project/lldb/test/API/functionalities/data-formatter/builtin-formats/TestBuiltinFormats.py (revision ce1fd9281707c2163728085d126ff83041e1db51)
1"""
2Tests the builtin formats of LLDB.
3"""
4
5import lldb
6from lldbsuite.test import lldbutil
7from lldbsuite.test.decorators import *
8from lldbsuite.test.lldbtest import *
9
10
11class TestCase(TestBase):
12    def getFormatted(self, format, expr):
13        """
14        Evaluates the expression and formats the result with the given format.
15        """
16        result = lldb.SBCommandReturnObject()
17        full_expr = "expr --format '" + format + "' -- " + expr
18        self.dbg.GetCommandInterpreter().HandleCommand(full_expr, result)
19        self.assertTrue(result.Succeeded(), result.GetError())
20        return result.GetOutput()
21
22    @skipIf(dwarf_version=["<", "3"])
23    @no_debug_info_test
24    @skipIfWindows
25    def testAllPlatforms(self):
26        self.build()
27        lldbutil.run_to_source_breakpoint(
28            self, "// break here", lldb.SBFileSpec("main.cpp")
29        )
30        # We can dump correctly non char* c-strings with explicit formatting.
31        self.assertIn(' = ""', self.getFormatted("c-string", "void_empty_cstring"))
32        self.assertIn(' = ""', self.getFormatted("c-string", "empty_cstring"))
33
34    # TODO: Move as many asserts as possible within this function to `testAllPlatforms`.
35    # Currently `arm` is being skipped even though many asserts would effectively
36    # pass.
37    @no_debug_info_test
38    @skipIfWindows
39    # uint128_t not available on arm.
40    @skipIf(archs=["arm"])
41    def test(self):
42        self.build()
43        lldbutil.run_to_source_breakpoint(
44            self, "// break here", lldb.SBFileSpec("main.cpp")
45        )
46
47        # void
48        self.assertEqual("", self.getFormatted("void", "1"))
49
50        # boolean
51        self.assertIn("= false\n", self.getFormatted("boolean", "0"))
52        self.assertIn("= true\n", self.getFormatted("boolean", "1"))
53        self.assertIn("= true\n", self.getFormatted("boolean", "2"))
54        self.assertIn(
55            "= error: unsupported byte size (16) for boolean format\n",
56            self.getFormatted("boolean", "(__uint128_t)0"),
57        )
58
59        # float
60        self.assertIn("= 0\n", self.getFormatted("float", "0"))
61        self.assertIn("= 2\n", self.getFormatted("float", "0x40000000"))
62        self.assertIn("= NaN\n", self.getFormatted("float", "-1"))
63        # Checks the float16 code.
64        self.assertIn("= 2\n", self.getFormatted("float", "(__UINT16_TYPE__)0x4000"))
65        self.assertIn(
66            "= error: unsupported byte size (1) for float format\n",
67            self.getFormatted("float", "'a'"),
68        )
69
70        # enumeration
71        self.assertIn("= 0\n", self.getFormatted("enumeration", "0"))
72        self.assertIn("= 1234567\n", self.getFormatted("enumeration", "1234567"))
73        self.assertIn("= -1234567\n", self.getFormatted("enumeration", "-1234567"))
74
75        # dec
76        self.assertIn("= 1234567\n", self.getFormatted("dec", "1234567"))
77        self.assertIn(
78            "= 123456789\n", self.getFormatted("dec", "(__uint128_t)123456789")
79        )
80
81        # unsigned decimal
82        self.assertIn("= 1234567\n", self.getFormatted("unsigned decimal", "1234567"))
83        self.assertIn(
84            "= 4293732729\n", self.getFormatted("unsigned decimal", "-1234567")
85        )
86        self.assertIn(
87            "= 123456789\n",
88            self.getFormatted("unsigned decimal", "(__uint128_t)123456789"),
89        )
90
91        # octal
92        self.assertIn("= 04553207\n", self.getFormatted("octal", "1234567"))
93        self.assertIn(
94            "= 0221505317046536757\n",
95            self.getFormatted("octal", "(__uint128_t)0x123456789ABDEFull"),
96        )
97
98        # complex float
99        self.assertIn(
100            "= error: unsupported byte size (1) for complex float format\n",
101            self.getFormatted("complex float", "'a'"),
102        )
103
104        # complex integer
105        self.assertIn(
106            "= error: unsupported byte size (1) for complex integer format\n",
107            self.getFormatted("complex integer", "'a'"),
108        )
109
110        # hex
111        self.assertIn("= 0x00abc123\n", self.getFormatted("hex", "0xABC123"))
112        self.assertIn(
113            "= 0x000000000000000000123456789abdef\n",
114            self.getFormatted("hex", "(__uint128_t)0x123456789ABDEFull"),
115        )
116
117        # hex float
118        self.assertIn("= 0x1p1\n", self.getFormatted("hex float", "2.0f"))
119        self.assertIn("= 0x1p1\n", self.getFormatted("hex float", "2.0"))
120        # FIXME: long double not supported.
121        self.assertIn(
122            "= error: unsupported byte size (16) for hex float format\n",
123            self.getFormatted("hex float", "2.0l"),
124        )
125
126        # uppercase hex
127        self.assertIn("= 0x00ABC123\n", self.getFormatted("uppercase hex", "0xABC123"))
128
129        # binary
130        self.assertIn(
131            "= 0b00000000000000000000000000000010\n", self.getFormatted("binary", "2")
132        )
133        self.assertIn("= 0b01100001\n", self.getFormatted("binary", "'a'"))
134        self.assertIn(
135            " = 0b10010001101000101011001111000\n",
136            self.getFormatted("binary", "(__uint128_t)0x12345678ll"),
137        )
138
139        # Different character arrays.
140        # FIXME: Passing a 'const char *' will ignore any given format,
141        self.assertIn(
142            r'= " \U0000001b\a\b\f\n\r\t\vaA09"',
143            self.getFormatted("character array", "cstring"),
144        )
145        self.assertIn(
146            r'= " \U0000001b\a\b\f\n\r\t\vaA09"',
147            self.getFormatted("c-string", "cstring"),
148        )
149        self.assertIn(
150            ' = " \\e\\a\\b\\f\\n\\r\\t\\vaA09" " \\U0000001b\\a\\b\\f\\n\\r\\t\\vaA09"\n',
151            self.getFormatted("c-string", "(char *)cstring"),
152        )
153        self.assertIn("=\n", self.getFormatted("c-string", "(__UINT64_TYPE__)0"))
154
155        # Build a uint128_t that contains a series of characters in each byte.
156        # First 8 byte of the uint128_t.
157        cstring_chars1 = " \a\b\f\n\r\t\v"
158        # Last 8 byte of the uint128_t.
159        cstring_chars2 = "AZaz09\033\0"
160
161        # Build a uint128_t value with the hex encoded characters.
162        string_expr = "((__uint128_t)0x"
163        for c in cstring_chars1:
164            string_expr += format(ord(c), "x").zfill(2)
165        string_expr += "ull << 64) | (__uint128_t)0x"
166        for c in cstring_chars2:
167            string_expr += format(ord(c), "x").zfill(2)
168        string_expr += "ull"
169
170        # Try to print that uint128_t with the different char formatters.
171        self.assertIn(
172            "= \\0\\e90zaZA\\v\\t\\r\\n\\f\\b\\a \n",
173            self.getFormatted("character array", string_expr),
174        )
175        self.assertIn(
176            "= \\0\\e90zaZA\\v\\t\\r\\n\\f\\b\\a \n",
177            self.getFormatted("character", string_expr),
178        )
179        self.assertIn(
180            "= ..90zaZA....... \n",
181            self.getFormatted("printable character", string_expr),
182        )
183        self.assertIn(
184            "= 0x00 0x1b 0x39 0x30 0x7a 0x61 0x5a 0x41 0x0b 0x09 0x0d 0x0a 0x0c 0x08 0x07 0x20\n",
185            self.getFormatted("unicode8", string_expr),
186        )
187
188        # OSType
189        ostype_expr = "(__UINT64_TYPE__)0x"
190        for c in cstring_chars1:
191            ostype_expr += format(ord(c), "x").zfill(2)
192        self.assertIn(
193            "= ' \\a\\b\\f\\n\\r\\t\\v'\n", self.getFormatted("OSType", ostype_expr)
194        )
195
196        ostype_expr = "(__UINT64_TYPE__)0x"
197        for c in cstring_chars2:
198            ostype_expr += format(ord(c), "x").zfill(2)
199        self.assertIn("= 'AZaz09\\e\\0'\n", self.getFormatted("OSType", ostype_expr))
200
201        self.assertIn(
202            "= 0x2007080c0a0d090b415a617a30391b00\n",
203            self.getFormatted("OSType", string_expr),
204        )
205
206        # bytes
207        self.assertIn(
208            r'= " \U0000001b\a\b\f\n\r\t\vaA09"', self.getFormatted("bytes", "cstring")
209        )
210
211        # bytes with ASCII
212        self.assertIn(
213            r'= " \U0000001b\a\b\f\n\r\t\vaA09"',
214            self.getFormatted("bytes with ASCII", "cstring"),
215        )
216
217        # unicode8
218        self.assertIn(
219            "= 0x78 0x56 0x34 0x12\n", self.getFormatted("unicode8", "0x12345678")
220        )
221
222        # unicode16
223        self.assertIn("= U+5678 U+1234\n", self.getFormatted("unicode16", "0x12345678"))
224
225        # unicode32
226        self.assertIn(
227            "= U+0x89abcdef U+0x01234567\n",
228            self.getFormatted("unicode32", "(__UINT64_TYPE__)0x123456789ABCDEFll"),
229        )
230
231        # address
232        self.assertIn("= 0x00000012\n", self.getFormatted("address", "0x12"))
233        self.assertIn("= 0x00000000\n", self.getFormatted("address", "0"))
234
235        # Different fixed-width integer type arrays (e.g. 'uint8_t[]').
236        self.assertIn(
237            "= {0xf8 0x56 0x34 0x12}\n", self.getFormatted("uint8_t[]", "0x123456f8")
238        )
239        self.assertIn("= {-8 86 52 18}\n", self.getFormatted("int8_t[]", "0x123456f8"))
240
241        self.assertIn(
242            "= {0x56f8 0x1234}\n", self.getFormatted("uint16_t[]", "0x123456f8")
243        )
244        self.assertIn("= {-2312 4660}\n", self.getFormatted("int16_t[]", "0x1234F6f8"))
245
246        self.assertIn(
247            "= {0x89abcdef 0x01234567}\n",
248            self.getFormatted("uint32_t[]", "(__UINT64_TYPE__)0x123456789ABCDEFll"),
249        )
250        self.assertIn(
251            "= {-1985229329 19088743}\n",
252            self.getFormatted("int32_t[]", "(__UINT64_TYPE__)0x123456789ABCDEFll"),
253        )
254
255        self.assertIn(
256            "= {0x89abcdef 0x01234567 0x00000000 0x00000000}\n",
257            self.getFormatted("uint32_t[]", "__uint128_t i = 0x123456789ABCDEF; i"),
258        )
259        self.assertIn(
260            "= {-1985229329 19088743 0 0}\n",
261            self.getFormatted("int32_t[]", "__uint128_t i = 0x123456789ABCDEF; i"),
262        )
263
264        self.assertIn(
265            "= {0x0123456789abcdef 0x0000000000000000}\n",
266            self.getFormatted("uint64_t[]", "__uint128_t i = 0x123456789ABCDEF; i"),
267        )
268        self.assertIn(
269            "= {-994074541749903617 0}\n",
270            self.getFormatted("int64_t[]", "__uint128_t i = 0xF23456789ABCDEFFll; i"),
271        )
272
273        # There is not int128_t[] style, so this only tests uint128_t[].
274        self.assertIn(
275            "= {0x00000000000000000123456789abcdef}\n",
276            self.getFormatted("uint128_t[]", "__uint128_t i = 0x123456789ABCDEF; i"),
277        )
278
279        # Different fixed-width float type arrays.
280        self.assertIn("{2 2}\n", self.getFormatted("float16[]", "0x40004000"))
281        self.assertIn("{2 2}\n", self.getFormatted("float32[]", "0x4000000040000000ll"))
282        self.assertIn(
283            "{2 0}\n",
284            self.getFormatted("float64[]", "__uint128_t i = 0x4000000000000000ll; i"),
285        )
286
287        # Invalid format string
288        self.expect(
289            "expr --format invalid_format_string -- 1",
290            error=True,
291            substrs=[
292                "error: Invalid format character or name 'invalid_format_string'. Valid values are:"
293            ],
294        )
295
296    # Extends to host target pointer width.
297    @skipIf(archs=no_match(["x86_64"]))
298    @no_debug_info_test
299    def test_pointer(self):
300        # pointer
301        self.assertIn("= 0x000000000012d687\n", self.getFormatted("pointer", "1234567"))
302        self.assertIn("= 0x0000000000000000\n", self.getFormatted("pointer", "0"))
303        # FIXME: Just ignores the input value as it's not pointer sized.
304        self.assertIn("= 0x0000000000000000\n", self.getFormatted("pointer", "'a'"))
305
306    # Depends on the host target for decoding.
307    @skipIf(archs=no_match(["x86_64"]))
308    @no_debug_info_test
309    def test_instruction(self):
310        self.assertIn(
311            "= addq   0xa(%rdi), %r8\n", self.getFormatted("instruction", "0x0a47034c")
312        )
313