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() 175ce0f876SPavel Labath lldbutil.run_to_source_breakpoint(self, "// break here", 185ce0f876SPavel Labath lldb.SBFileSpec("main.c")) 193a870bffSDavid Spickett 203a870bffSDavid Spickett def test_memory_read_c_string(self): 213a870bffSDavid Spickett """Test that reading memory as a c string respects the size limit given 223a870bffSDavid Spickett and warns if the null terminator is missing.""" 233a870bffSDavid Spickett self.build_run_stop() 243a870bffSDavid Spickett 253a870bffSDavid Spickett # The size here is the size in memory so it includes the null terminator. 265ce0f876SPavel Labath cmd = "memory read --format \"c-string\" --size {} &my_string" 273a870bffSDavid Spickett 283a870bffSDavid Spickett # Size matches the size of the array. 295ce0f876SPavel Labath self.expect(cmd.format(8), substrs=['\"abcdefg\"']) 303a870bffSDavid Spickett 313a870bffSDavid Spickett # If size would take us past the terminator we stop at the terminator. 325ce0f876SPavel Labath self.expect(cmd.format(10), substrs=['\"abcdefg\"']) 333a870bffSDavid Spickett 343a870bffSDavid Spickett # Size 3 means 2 chars and a terminator. So we print 2 chars but warn because 353a870bffSDavid Spickett # the third isn't 0 as expected. 363a870bffSDavid Spickett self.expect(cmd.format(3), substrs=['\"ab\"']) 373a870bffSDavid Spickett self.assertRegex(self.res.GetError(), 38*0dfafa48SDavid Spickett "unable to find a NULL terminated string at 0x[0-9A-Fa-f]+." 393a870bffSDavid Spickett " Consider increasing the maximum read length.") 405ce0f876SPavel Labath 415ce0f876SPavel Labath def test_memory_read(self): 425ce0f876SPavel Labath """Test the 'memory read' command with plain and vector formats.""" 435ce0f876SPavel Labath self.build_run_stop() 445ce0f876SPavel Labath 455ce0f876SPavel Labath # (lldb) memory read -f d -c 1 `&argc` 465ce0f876SPavel Labath # 0x7fff5fbff9a0: 1 475ce0f876SPavel Labath self.runCmd("memory read -f d -c 1 `&argc`") 485ce0f876SPavel Labath 495ce0f876SPavel Labath # Find the starting address for variable 'argc' to verify later that the 505ce0f876SPavel Labath # '--format uint32_t[] --size 4 --count 4' option increments the address 515ce0f876SPavel Labath # correctly. 525ce0f876SPavel Labath line = self.res.GetOutput().splitlines()[0] 535ce0f876SPavel Labath items = line.split(':') 545ce0f876SPavel Labath address = int(items[0], 0) 555ce0f876SPavel Labath argc = int(items[1], 0) 565ce0f876SPavel Labath self.assertGreater(address, 0) 575ce0f876SPavel Labath self.assertEquals(argc, 1) 585ce0f876SPavel Labath 595ce0f876SPavel Labath # (lldb) memory read --format uint32_t[] --size 4 --count 4 `&argc` 605ce0f876SPavel Labath # 0x7fff5fbff9a0: {0x00000001} 615ce0f876SPavel Labath # 0x7fff5fbff9a4: {0x00000000} 625ce0f876SPavel Labath # 0x7fff5fbff9a8: {0x0ec0bf27} 635ce0f876SPavel Labath # 0x7fff5fbff9ac: {0x215db505} 645ce0f876SPavel Labath self.runCmd( 655ce0f876SPavel Labath "memory read --format uint32_t[] --size 4 --count 4 `&argc`") 665ce0f876SPavel Labath lines = self.res.GetOutput().splitlines() 675ce0f876SPavel Labath for i in range(4): 685ce0f876SPavel Labath if i == 0: 695ce0f876SPavel Labath # Verify that the printout for argc is correct. 705ce0f876SPavel Labath self.assertEqual( 715ce0f876SPavel Labath argc, int(lines[i].split(':')[1].strip(' {}'), 0)) 725ce0f876SPavel Labath addr = int(lines[i].split(':')[0], 0) 735ce0f876SPavel Labath # Verify that the printout for addr is incremented correctly. 745ce0f876SPavel Labath self.assertEqual(addr, (address + i * 4)) 755ce0f876SPavel Labath 765ce0f876SPavel Labath # (lldb) memory read --format char[] --size 7 --count 1 `&my_string` 775ce0f876SPavel Labath # 0x7fff5fbff990: {abcdefg} 785ce0f876SPavel Labath self.expect( 795ce0f876SPavel Labath "memory read --format char[] --size 7 --count 1 `&my_string`", 805ce0f876SPavel Labath substrs=['abcdefg']) 815ce0f876SPavel Labath 825ce0f876SPavel Labath # (lldb) memory read --format 'hex float' --size 16 `&argc` 835ce0f876SPavel Labath # 0x7fff5fbff5b0: error: unsupported byte size (16) for hex float 845ce0f876SPavel Labath # format 855ce0f876SPavel Labath self.expect( 865ce0f876SPavel Labath "memory read --format 'hex float' --size 16 `&argc`", 875ce0f876SPavel Labath substrs=['unsupported byte size (16) for hex float format']) 885ce0f876SPavel Labath 895ce0f876SPavel Labath self.expect( 905ce0f876SPavel Labath "memory read --format 'float' --count 1 --size 8 `&my_double`", 915ce0f876SPavel Labath substrs=['1234.']) 925ce0f876SPavel Labath 935ce0f876SPavel Labath # (lldb) memory read --format 'float' --count 1 --size 20 `&my_double` 945ce0f876SPavel Labath # 0x7fff5fbff598: error: unsupported byte size (20) for float format 955ce0f876SPavel Labath self.expect( 965ce0f876SPavel Labath "memory read --format 'float' --count 1 --size 20 `&my_double`", 975ce0f876SPavel Labath substrs=['unsupported byte size (20) for float format']) 985ce0f876SPavel Labath 995ce0f876SPavel Labath self.expect('memory read --type int --count 5 `&my_ints[0]`', 1005ce0f876SPavel Labath substrs=['(int) 0x', '2', '4', '6', '8', '10']) 1015ce0f876SPavel Labath 1025ce0f876SPavel Labath self.expect( 1035ce0f876SPavel Labath 'memory read --type int --count 5 --format hex `&my_ints[0]`', 1045ce0f876SPavel Labath substrs=[ 1055ce0f876SPavel Labath '(int) 0x', 1065ce0f876SPavel Labath '0x', 1075ce0f876SPavel Labath '0a']) 1085ce0f876SPavel Labath 1095ce0f876SPavel Labath self.expect( 1105ce0f876SPavel Labath 'memory read --type int --count 5 --offset 5 `&my_ints[0]`', 1115ce0f876SPavel Labath substrs=[ 1125ce0f876SPavel Labath '(int) 0x', 1135ce0f876SPavel Labath '12', 1145ce0f876SPavel Labath '14', 1155ce0f876SPavel Labath '16', 1165ce0f876SPavel Labath '18', 1175ce0f876SPavel Labath '20']) 1185ce0f876SPavel Labath 1195ce0f876SPavel Labath # the gdb format specifier and the size in characters for 1205ce0f876SPavel Labath # the returned values including the 0x prefix. 1215ce0f876SPavel Labath 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] 1255ce0f876SPavel Labath self.runCmd( 1265ce0f876SPavel Labath "memory read --gdb-format 4%s &my_uint64s" % formatter) 1275ce0f876SPavel Labath lines = self.res.GetOutput().splitlines() 1285ce0f876SPavel Labath objects_read = [] 1295ce0f876SPavel Labath for l in lines: 1305ce0f876SPavel Labath objects_read.extend(l.split(':')[1].split()) 1315ce0f876SPavel Labath # Check that we got back 4 0x0000 etc bytes 1325ce0f876SPavel Labath for o in objects_read: 1335ce0f876SPavel Labath self.assertEqual(len(o), expected_object_length) 1345ce0f876SPavel Labath self.assertEquals(len(objects_read), 4) 1355ce0f876SPavel Labath 1365ce0f876SPavel Labath def test_memory_read_file(self): 1375ce0f876SPavel Labath self.build_run_stop() 1385ce0f876SPavel Labath res = lldb.SBCommandReturnObject() 1395ce0f876SPavel Labath self.ci.HandleCommand("memory read -f d -c 1 `&argc`", res) 1405ce0f876SPavel Labath self.assertTrue(res.Succeeded(), "memory read failed:" + res.GetError()) 1415ce0f876SPavel Labath 1425ce0f876SPavel Labath # Record golden output. 1435ce0f876SPavel Labath golden_output = res.GetOutput() 1445ce0f876SPavel Labath 1455ce0f876SPavel Labath memory_read_file = self.getBuildArtifact("memory-read-output") 1465ce0f876SPavel Labath 1475ce0f876SPavel Labath def check_file_content(expected): 1485ce0f876SPavel Labath with open(memory_read_file) as f: 1495ce0f876SPavel Labath lines = f.readlines() 1505ce0f876SPavel Labath lines = [s.strip() for s in lines] 1515ce0f876SPavel Labath expected = [s.strip() for s in expected] 1525ce0f876SPavel Labath self.assertEqual(lines, expected) 1535ce0f876SPavel Labath 1545ce0f876SPavel Labath # Sanity check. 1555ce0f876SPavel Labath self.runCmd("memory read -f d -c 1 -o '{}' `&argc`".format(memory_read_file)) 1565ce0f876SPavel Labath check_file_content([golden_output]) 1575ce0f876SPavel Labath 1585ce0f876SPavel Labath # Write some garbage to the file. 1595ce0f876SPavel Labath with open(memory_read_file, 'w') as f: 1605ce0f876SPavel Labath f.write("some garbage") 1615ce0f876SPavel Labath 1625ce0f876SPavel Labath # Make sure the file is truncated when we run the command again. 1635ce0f876SPavel Labath self.runCmd("memory read -f d -c 1 -o '{}' `&argc`".format(memory_read_file)) 1645ce0f876SPavel Labath check_file_content([golden_output]) 1655ce0f876SPavel Labath 1665ce0f876SPavel Labath # Make sure the file is appended when we run the command with --append-outfile. 1675ce0f876SPavel Labath self.runCmd( 1685ce0f876SPavel Labath "memory read -f d -c 1 -o '{}' --append-outfile `&argc`".format( 1695ce0f876SPavel Labath memory_read_file)) 1705ce0f876SPavel Labath check_file_content([golden_output, golden_output]) 171