315 lines · python
1"""2Tests the builtin formats of LLDB.3"""4 5import lldb6from lldbsuite.test import lldbutil7from 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 + "' -- " + expr18 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_test24 @skipIfWindows25 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 effectively36 # pass.37 @no_debug_info_test38 @skipIfWindows39 # 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 # void48 self.assertEqual("", self.getFormatted("void", "1"))49 50 # boolean51 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 # float60 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 # enumeration71 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 # dec76 self.assertIn("= 1234567\n", self.getFormatted("dec", "1234567"))77 self.assertIn(78 "= 123456789\n", self.getFormatted("dec", "(__uint128_t)123456789")79 )80 81 # unsigned decimal82 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 # octal92 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 float99 self.assertIn(100 "= error: unsupported byte size (1) for complex float format\n",101 self.getFormatted("complex float", "'a'"),102 )103 104 # complex integer105 self.assertIn(106 "= error: unsupported byte size (1) for complex integer format\n",107 self.getFormatted("complex integer", "'a'"),108 )109 110 # hex111 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 float118 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 # on Darwin arm64, long double is 8 bytes, same as long.122 if self.getArchitecture() != "arm64":123 self.assertIn(124 "= error: unsupported byte size (16) for hex float format\n",125 self.getFormatted("hex float", "2.0l"),126 )127 128 # uppercase hex129 self.assertIn("= 0x00ABC123\n", self.getFormatted("uppercase hex", "0xABC123"))130 131 # binary132 self.assertIn(133 "= 0b00000000000000000000000000000010\n", self.getFormatted("binary", "2")134 )135 self.assertIn("= 0b01100001\n", self.getFormatted("binary", "'a'"))136 self.assertIn(137 " = 0b10010001101000101011001111000\n",138 self.getFormatted("binary", "(__uint128_t)0x12345678ll"),139 )140 141 # Different character arrays.142 # FIXME: Passing a 'const char *' will ignore any given format,143 self.assertIn(144 r'= " \U0000001b\a\b\f\n\r\t\vaA09"',145 self.getFormatted("character array", "cstring"),146 )147 self.assertIn(148 r'= " \U0000001b\a\b\f\n\r\t\vaA09"',149 self.getFormatted("c-string", "cstring"),150 )151 self.assertIn(152 ' = " \\e\\a\\b\\f\\n\\r\\t\\vaA09" " \\U0000001b\\a\\b\\f\\n\\r\\t\\vaA09"\n',153 self.getFormatted("c-string", "(char *)cstring"),154 )155 self.assertIn("=\n", self.getFormatted("c-string", "(__UINT64_TYPE__)0"))156 157 # Build a uint128_t that contains a series of characters in each byte.158 # First 8 byte of the uint128_t.159 cstring_chars1 = " \a\b\f\n\r\t\v"160 # Last 8 byte of the uint128_t.161 cstring_chars2 = "AZaz09\033\0"162 163 # Build a uint128_t value with the hex encoded characters.164 string_expr = "((__uint128_t)0x"165 for c in cstring_chars1:166 string_expr += format(ord(c), "x").zfill(2)167 string_expr += "ull << 64) | (__uint128_t)0x"168 for c in cstring_chars2:169 string_expr += format(ord(c), "x").zfill(2)170 string_expr += "ull"171 172 # Try to print that uint128_t with the different char formatters.173 self.assertIn(174 "= \\0\\e90zaZA\\v\\t\\r\\n\\f\\b\\a \n",175 self.getFormatted("character array", string_expr),176 )177 self.assertIn(178 "= \\0\\e90zaZA\\v\\t\\r\\n\\f\\b\\a \n",179 self.getFormatted("character", string_expr),180 )181 self.assertIn(182 "= ..90zaZA....... \n",183 self.getFormatted("printable character", string_expr),184 )185 self.assertIn(186 "= 0x00 0x1b 0x39 0x30 0x7a 0x61 0x5a 0x41 0x0b 0x09 0x0d 0x0a 0x0c 0x08 0x07 0x20\n",187 self.getFormatted("unicode8", string_expr),188 )189 190 # OSType191 ostype_expr = "(__UINT64_TYPE__)0x"192 for c in cstring_chars1:193 ostype_expr += format(ord(c), "x").zfill(2)194 self.assertIn(195 "= ' \\a\\b\\f\\n\\r\\t\\v'\n", self.getFormatted("OSType", ostype_expr)196 )197 198 ostype_expr = "(__UINT64_TYPE__)0x"199 for c in cstring_chars2:200 ostype_expr += format(ord(c), "x").zfill(2)201 self.assertIn("= 'AZaz09\\e\\0'\n", self.getFormatted("OSType", ostype_expr))202 203 self.assertIn(204 "= 0x2007080c0a0d090b415a617a30391b00\n",205 self.getFormatted("OSType", string_expr),206 )207 208 # bytes209 self.assertIn(210 r'= " \U0000001b\a\b\f\n\r\t\vaA09"', self.getFormatted("bytes", "cstring")211 )212 213 # bytes with ASCII214 self.assertIn(215 r'= " \U0000001b\a\b\f\n\r\t\vaA09"',216 self.getFormatted("bytes with ASCII", "cstring"),217 )218 219 # unicode8220 self.assertIn(221 "= 0x78 0x56 0x34 0x12\n", self.getFormatted("unicode8", "0x12345678")222 )223 224 # unicode16225 self.assertIn("= U+5678 U+1234\n", self.getFormatted("unicode16", "0x12345678"))226 227 # unicode32228 self.assertIn(229 "= U+0x89abcdef U+0x01234567\n",230 self.getFormatted("unicode32", "(__UINT64_TYPE__)0x123456789ABCDEFll"),231 )232 233 # address234 self.assertIn("= 0x00000012\n", self.getFormatted("address", "0x12"))235 self.assertIn("= 0x00000000\n", self.getFormatted("address", "0"))236 237 # Different fixed-width integer type arrays (e.g. 'uint8_t[]').238 self.assertIn(239 "= {0xf8 0x56 0x34 0x12}\n", self.getFormatted("uint8_t[]", "0x123456f8")240 )241 self.assertIn("= {-8 86 52 18}\n", self.getFormatted("int8_t[]", "0x123456f8"))242 243 self.assertIn(244 "= {0x56f8 0x1234}\n", self.getFormatted("uint16_t[]", "0x123456f8")245 )246 self.assertIn("= {-2312 4660}\n", self.getFormatted("int16_t[]", "0x1234F6f8"))247 248 self.assertIn(249 "= {0x89abcdef 0x01234567}\n",250 self.getFormatted("uint32_t[]", "(__UINT64_TYPE__)0x123456789ABCDEFll"),251 )252 self.assertIn(253 "= {-1985229329 19088743}\n",254 self.getFormatted("int32_t[]", "(__UINT64_TYPE__)0x123456789ABCDEFll"),255 )256 257 self.assertIn(258 "= {0x89abcdef 0x01234567 0x00000000 0x00000000}\n",259 self.getFormatted("uint32_t[]", "__uint128_t i = 0x123456789ABCDEF; i"),260 )261 self.assertIn(262 "= {-1985229329 19088743 0 0}\n",263 self.getFormatted("int32_t[]", "__uint128_t i = 0x123456789ABCDEF; i"),264 )265 266 self.assertIn(267 "= {0x0123456789abcdef 0x0000000000000000}\n",268 self.getFormatted("uint64_t[]", "__uint128_t i = 0x123456789ABCDEF; i"),269 )270 self.assertIn(271 "= {-994074541749903617 0}\n",272 self.getFormatted("int64_t[]", "__uint128_t i = 0xF23456789ABCDEFFll; i"),273 )274 275 # There is not int128_t[] style, so this only tests uint128_t[].276 self.assertIn(277 "= {0x00000000000000000123456789abcdef}\n",278 self.getFormatted("uint128_t[]", "__uint128_t i = 0x123456789ABCDEF; i"),279 )280 281 # Different fixed-width float type arrays.282 self.assertIn("{2 2}\n", self.getFormatted("float16[]", "0x40004000"))283 self.assertIn("{2 2}\n", self.getFormatted("float32[]", "0x4000000040000000ll"))284 self.assertIn(285 "{2 0}\n",286 self.getFormatted("float64[]", "__uint128_t i = 0x4000000000000000ll; i"),287 )288 289 # Invalid format string290 self.expect(291 "expr --format invalid_format_string -- 1",292 error=True,293 substrs=[294 "error: Invalid format character or name 'invalid_format_string'. Valid values are:"295 ],296 )297 298 # Extends to host target pointer width.299 @skipIf(archs=no_match(["x86_64"]))300 @no_debug_info_test301 def test_pointer(self):302 # pointer303 self.assertIn("= 0x000000000012d687\n", self.getFormatted("pointer", "1234567"))304 self.assertIn("= 0x0000000000000000\n", self.getFormatted("pointer", "0"))305 # FIXME: Just ignores the input value as it's not pointer sized.306 self.assertIn("= 0x0000000000000000\n", self.getFormatted("pointer", "'a'"))307 308 # Depends on the host target for decoding.309 @skipIf(archs=no_match(["x86_64"]))310 @no_debug_info_test311 def test_instruction(self):312 self.assertIn(313 "= addq 0xa(%rdi), %r8\n", self.getFormatted("instruction", "0x0a47034c")314 )315