13a870bffSDavid Spickett""" 23a870bffSDavid SpickettTest the 'memory read' command. 33a870bffSDavid Spickett""" 43a870bffSDavid Spickett 53a870bffSDavid Spickettimport lldb 63a870bffSDavid Spickettimport lldbsuite.test.lldbutil as lldbutil 73a870bffSDavid Spickett 83a870bffSDavid Spickettfrom lldbsuite.test.decorators import * 93a870bffSDavid Spickettfrom lldbsuite.test.lldbtest import * 103a870bffSDavid Spickett 113a870bffSDavid Spickett 125ce0f876SPavel Labathclass MemoryReadTestCase(TestBase): 135ce0f876SPavel Labath NO_DEBUG_INFO_TESTCASE = True 143a870bffSDavid Spickett 153a870bffSDavid Spickett def build_run_stop(self): 163a870bffSDavid Spickett self.build() 172238dcc3SJonas Devlieghere lldbutil.run_to_source_breakpoint( 182238dcc3SJonas Devlieghere self, "// break here", lldb.SBFileSpec("main.c") 192238dcc3SJonas Devlieghere ) 203a870bffSDavid Spickett 213a870bffSDavid Spickett def test_memory_read_c_string(self): 223a870bffSDavid Spickett """Test that reading memory as a c string respects the size limit given 233a870bffSDavid Spickett and warns if the null terminator is missing.""" 243a870bffSDavid Spickett self.build_run_stop() 253a870bffSDavid Spickett 263a870bffSDavid Spickett # The size here is the size in memory so it includes the null terminator. 272238dcc3SJonas Devlieghere cmd = 'memory read --format "c-string" --size {} &my_string' 283a870bffSDavid Spickett 293a870bffSDavid Spickett # Size matches the size of the array. 302238dcc3SJonas Devlieghere self.expect(cmd.format(8), substrs=['"abcdefg"']) 313a870bffSDavid Spickett 323a870bffSDavid Spickett # If size would take us past the terminator we stop at the terminator. 332238dcc3SJonas Devlieghere self.expect(cmd.format(10), substrs=['"abcdefg"']) 343a870bffSDavid Spickett 353a870bffSDavid Spickett # Size 3 means 2 chars and a terminator. So we print 2 chars but warn because 363a870bffSDavid Spickett # the third isn't 0 as expected. 372238dcc3SJonas Devlieghere self.expect(cmd.format(3), substrs=['"ab"']) 382238dcc3SJonas Devlieghere self.assertRegex( 392238dcc3SJonas Devlieghere self.res.GetError(), 400dfafa48SDavid Spickett "unable to find a NULL terminated string at 0x[0-9A-Fa-f]+." 412238dcc3SJonas Devlieghere " Consider increasing the maximum read length.", 422238dcc3SJonas Devlieghere ) 435ce0f876SPavel Labath 445ce0f876SPavel Labath def test_memory_read(self): 455ce0f876SPavel Labath """Test the 'memory read' command with plain and vector formats.""" 465ce0f876SPavel Labath self.build_run_stop() 475ce0f876SPavel Labath 485ce0f876SPavel Labath # (lldb) memory read -f d -c 1 `&argc` 495ce0f876SPavel Labath # 0x7fff5fbff9a0: 1 505ce0f876SPavel Labath self.runCmd("memory read -f d -c 1 `&argc`") 515ce0f876SPavel Labath 525ce0f876SPavel Labath # Find the starting address for variable 'argc' to verify later that the 535ce0f876SPavel Labath # '--format uint32_t[] --size 4 --count 4' option increments the address 545ce0f876SPavel Labath # correctly. 555ce0f876SPavel Labath line = self.res.GetOutput().splitlines()[0] 562238dcc3SJonas Devlieghere items = line.split(":") 575ce0f876SPavel Labath address = int(items[0], 0) 585ce0f876SPavel Labath argc = int(items[1], 0) 595ce0f876SPavel Labath self.assertGreater(address, 0) 60*80fcecb1SJonas Devlieghere self.assertEqual(argc, 1) 615ce0f876SPavel Labath 625ce0f876SPavel Labath # (lldb) memory read --format uint32_t[] --size 4 --count 4 `&argc` 635ce0f876SPavel Labath # 0x7fff5fbff9a0: {0x00000001} 645ce0f876SPavel Labath # 0x7fff5fbff9a4: {0x00000000} 655ce0f876SPavel Labath # 0x7fff5fbff9a8: {0x0ec0bf27} 665ce0f876SPavel Labath # 0x7fff5fbff9ac: {0x215db505} 672238dcc3SJonas Devlieghere self.runCmd("memory read --format uint32_t[] --size 4 --count 4 `&argc`") 685ce0f876SPavel Labath lines = self.res.GetOutput().splitlines() 695ce0f876SPavel Labath for i in range(4): 705ce0f876SPavel Labath if i == 0: 715ce0f876SPavel Labath # Verify that the printout for argc is correct. 722238dcc3SJonas Devlieghere self.assertEqual(argc, int(lines[i].split(":")[1].strip(" {}"), 0)) 732238dcc3SJonas Devlieghere addr = int(lines[i].split(":")[0], 0) 745ce0f876SPavel Labath # Verify that the printout for addr is incremented correctly. 755ce0f876SPavel Labath self.assertEqual(addr, (address + i * 4)) 765ce0f876SPavel Labath 775ce0f876SPavel Labath # (lldb) memory read --format char[] --size 7 --count 1 `&my_string` 785ce0f876SPavel Labath # 0x7fff5fbff990: {abcdefg} 795ce0f876SPavel Labath self.expect( 805ce0f876SPavel Labath "memory read --format char[] --size 7 --count 1 `&my_string`", 812238dcc3SJonas Devlieghere substrs=["abcdefg"], 822238dcc3SJonas Devlieghere ) 835ce0f876SPavel Labath 845ce0f876SPavel Labath # (lldb) memory read --format 'hex float' --size 16 `&argc` 855ce0f876SPavel Labath # 0x7fff5fbff5b0: error: unsupported byte size (16) for hex float 865ce0f876SPavel Labath # format 875ce0f876SPavel Labath self.expect( 885ce0f876SPavel Labath "memory read --format 'hex float' --size 16 `&argc`", 892238dcc3SJonas Devlieghere substrs=["unsupported byte size (16) for hex float format"], 902238dcc3SJonas Devlieghere ) 915ce0f876SPavel Labath 925ce0f876SPavel Labath self.expect( 935ce0f876SPavel Labath "memory read --format 'float' --count 1 --size 8 `&my_double`", 942238dcc3SJonas Devlieghere substrs=["1234."], 952238dcc3SJonas Devlieghere ) 965ce0f876SPavel Labath 975ce0f876SPavel Labath # (lldb) memory read --format 'float' --count 1 --size 20 `&my_double` 985ce0f876SPavel Labath # 0x7fff5fbff598: error: unsupported byte size (20) for float format 995ce0f876SPavel Labath self.expect( 1005ce0f876SPavel Labath "memory read --format 'float' --count 1 --size 20 `&my_double`", 1012238dcc3SJonas Devlieghere substrs=["unsupported byte size (20) for float format"], 1022238dcc3SJonas Devlieghere ) 1035ce0f876SPavel Labath 1045ce0f876SPavel Labath self.expect( 1052238dcc3SJonas Devlieghere "memory read --type int --count 5 `&my_ints[0]`", 1062238dcc3SJonas Devlieghere substrs=["(int) 0x", "2", "4", "6", "8", "10"], 1072238dcc3SJonas Devlieghere ) 1085ce0f876SPavel Labath 1095ce0f876SPavel Labath self.expect( 1102238dcc3SJonas Devlieghere "memory read --type int --count 5 --format hex `&my_ints[0]`", 1112238dcc3SJonas Devlieghere substrs=["(int) 0x", "0x", "0a"], 1122238dcc3SJonas Devlieghere ) 1132238dcc3SJonas Devlieghere 1142238dcc3SJonas Devlieghere self.expect( 1152238dcc3SJonas Devlieghere "memory read --type int --count 5 --offset 5 `&my_ints[0]`", 1162238dcc3SJonas Devlieghere substrs=["(int) 0x", "12", "14", "16", "18", "20"], 1172238dcc3SJonas Devlieghere ) 1185ce0f876SPavel Labath 1195ce0f876SPavel Labath # the gdb format specifier and the size in characters for 1205ce0f876SPavel Labath # the returned values including the 0x prefix. 1212238dcc3SJonas Devlieghere variations = [["b", 4], ["h", 6], ["w", 10], ["g", 18]] 1225ce0f876SPavel Labath for v in variations: 1235ce0f876SPavel Labath formatter = v[0] 1245ce0f876SPavel Labath expected_object_length = v[1] 1252238dcc3SJonas Devlieghere self.runCmd("memory read --gdb-format 4%s &my_uint64s" % formatter) 1265ce0f876SPavel Labath lines = self.res.GetOutput().splitlines() 1275ce0f876SPavel Labath objects_read = [] 1285ce0f876SPavel Labath for l in lines: 1292238dcc3SJonas Devlieghere objects_read.extend(l.split(":")[1].split()) 1305ce0f876SPavel Labath # Check that we got back 4 0x0000 etc bytes 1315ce0f876SPavel Labath for o in objects_read: 1325ce0f876SPavel Labath self.assertEqual(len(o), expected_object_length) 133*80fcecb1SJonas Devlieghere self.assertEqual(len(objects_read), 4) 1345ce0f876SPavel Labath 1355ce0f876SPavel Labath def test_memory_read_file(self): 1365ce0f876SPavel Labath self.build_run_stop() 1375ce0f876SPavel Labath res = lldb.SBCommandReturnObject() 1385ce0f876SPavel Labath self.ci.HandleCommand("memory read -f d -c 1 `&argc`", res) 1395ce0f876SPavel Labath self.assertTrue(res.Succeeded(), "memory read failed:" + res.GetError()) 1405ce0f876SPavel Labath 1415ce0f876SPavel Labath # Record golden output. 1425ce0f876SPavel Labath golden_output = res.GetOutput() 1435ce0f876SPavel Labath 1445ce0f876SPavel Labath memory_read_file = self.getBuildArtifact("memory-read-output") 1455ce0f876SPavel Labath 1465ce0f876SPavel Labath def check_file_content(expected): 1475ce0f876SPavel Labath with open(memory_read_file) as f: 1485ce0f876SPavel Labath lines = f.readlines() 1495ce0f876SPavel Labath lines = [s.strip() for s in lines] 1505ce0f876SPavel Labath expected = [s.strip() for s in expected] 1515ce0f876SPavel Labath self.assertEqual(lines, expected) 1525ce0f876SPavel Labath 1535ce0f876SPavel Labath # Sanity check. 1545ce0f876SPavel Labath self.runCmd("memory read -f d -c 1 -o '{}' `&argc`".format(memory_read_file)) 1555ce0f876SPavel Labath check_file_content([golden_output]) 1565ce0f876SPavel Labath 1575ce0f876SPavel Labath # Write some garbage to the file. 1582238dcc3SJonas Devlieghere with open(memory_read_file, "w") as f: 1595ce0f876SPavel Labath f.write("some garbage") 1605ce0f876SPavel Labath 1615ce0f876SPavel Labath # Make sure the file is truncated when we run the command again. 1625ce0f876SPavel Labath self.runCmd("memory read -f d -c 1 -o '{}' `&argc`".format(memory_read_file)) 1635ce0f876SPavel Labath check_file_content([golden_output]) 1645ce0f876SPavel Labath 1655ce0f876SPavel Labath # Make sure the file is appended when we run the command with --append-outfile. 1665ce0f876SPavel Labath self.runCmd( 1675ce0f876SPavel Labath "memory read -f d -c 1 -o '{}' --append-outfile `&argc`".format( 1682238dcc3SJonas Devlieghere memory_read_file 1692238dcc3SJonas Devlieghere ) 1702238dcc3SJonas Devlieghere ) 1715ce0f876SPavel Labath check_file_content([golden_output, golden_output]) 172