199451b44SJordan Rupprecht""" 299451b44SJordan RupprechtTest the 'memory region' command. 399451b44SJordan Rupprecht""" 499451b44SJordan Rupprecht 599451b44SJordan Rupprecht 699451b44SJordan Rupprecht 799451b44SJordan Rupprechtimport lldb 899451b44SJordan Rupprechtfrom lldbsuite.test.decorators import * 999451b44SJordan Rupprechtfrom lldbsuite.test.lldbtest import * 1099451b44SJordan Rupprechtfrom lldbsuite.test import lldbutil 1199451b44SJordan Rupprecht 1299451b44SJordan Rupprecht 1399451b44SJordan Rupprechtclass MemoryCommandRegion(TestBase): 1499451b44SJordan Rupprecht 1599451b44SJordan Rupprecht NO_DEBUG_INFO_TESTCASE = True 1699451b44SJordan Rupprecht 1799451b44SJordan Rupprecht def setUp(self): 1899451b44SJordan Rupprecht TestBase.setUp(self) 1999451b44SJordan Rupprecht # Find the line number to break for main.c. 2099451b44SJordan Rupprecht self.line = line_number( 2199451b44SJordan Rupprecht 'main.cpp', 2299451b44SJordan Rupprecht '// Run here before printing memory regions') 2399451b44SJordan Rupprecht 2413e1cf80SDavid Spickett def test_help(self): 2513e1cf80SDavid Spickett """ Test that help shows you must have one of address or --all, not both.""" 2613e1cf80SDavid Spickett self.expect("help memory region", 2713e1cf80SDavid Spickett substrs=["memory region <address-expression>", 2813e1cf80SDavid Spickett "memory region -a"]) 2913e1cf80SDavid Spickett 301ca8a978SDavid Spickett def setup_program(self): 3199451b44SJordan Rupprecht self.build() 3299451b44SJordan Rupprecht 3399451b44SJordan Rupprecht # Set breakpoint in main and run 3499451b44SJordan Rupprecht self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) 3599451b44SJordan Rupprecht lldbutil.run_break_set_by_file_and_line( 3699451b44SJordan Rupprecht self, "main.cpp", self.line, num_expected_locations=-1, loc_exact=True) 3799451b44SJordan Rupprecht 3899451b44SJordan Rupprecht self.runCmd("run", RUN_SUCCEEDED) 3999451b44SJordan Rupprecht 401ca8a978SDavid Spickett def test_command(self): 411ca8a978SDavid Spickett self.setup_program() 421ca8a978SDavid Spickett 4399451b44SJordan Rupprecht interp = self.dbg.GetCommandInterpreter() 4499451b44SJordan Rupprecht result = lldb.SBCommandReturnObject() 4599451b44SJordan Rupprecht 4699451b44SJordan Rupprecht # Test that the first 'memory region' command prints the usage. 4799451b44SJordan Rupprecht interp.HandleCommand("memory region", result) 4899451b44SJordan Rupprecht self.assertFalse(result.Succeeded()) 4913e1cf80SDavid Spickett self.assertEqual(result.GetError(), 5013e1cf80SDavid Spickett "error: 'memory region' takes one argument or \"--all\" option:\n" 5113e1cf80SDavid Spickett "Usage: memory region <address-expression> (or --all)\n") 5213e1cf80SDavid Spickett 5313e1cf80SDavid Spickett # We allow --all or an address argument, not both 5413e1cf80SDavid Spickett interp.HandleCommand("memory region --all 0", result) 5513e1cf80SDavid Spickett self.assertFalse(result.Succeeded()) 5613e1cf80SDavid Spickett self.assertRegexpMatches(result.GetError(), 5713e1cf80SDavid Spickett "The \"--all\" option cannot be used when an address argument is given") 5899451b44SJordan Rupprecht 5971cf97e9SDavid Spickett # Test that when the address fails to parse, we show an error and do not continue 6071cf97e9SDavid Spickett interp.HandleCommand("memory region not_an_address", result) 6171cf97e9SDavid Spickett self.assertFalse(result.Succeeded()) 6271cf97e9SDavid Spickett self.assertEqual(result.GetError(), 6371cf97e9SDavid Spickett "error: invalid address argument \"not_an_address\": address expression \"not_an_address\" evaluation failed\n") 6471cf97e9SDavid Spickett 6513e1cf80SDavid Spickett # Accumulate the results to compare with the --all output 6613e1cf80SDavid Spickett all_regions = "" 6713e1cf80SDavid Spickett 6899451b44SJordan Rupprecht # Now let's print the memory region starting at 0 which should always work. 6999451b44SJordan Rupprecht interp.HandleCommand("memory region 0x0", result) 7099451b44SJordan Rupprecht self.assertTrue(result.Succeeded()) 7199451b44SJordan Rupprecht self.assertRegexpMatches(result.GetOutput(), "\\[0x0+-") 7213e1cf80SDavid Spickett all_regions += result.GetOutput() 7399451b44SJordan Rupprecht 7499451b44SJordan Rupprecht # Keep printing memory regions until we printed all of them. 7599451b44SJordan Rupprecht while True: 7699451b44SJordan Rupprecht interp.HandleCommand("memory region", result) 7799451b44SJordan Rupprecht if not result.Succeeded(): 7899451b44SJordan Rupprecht break 7913e1cf80SDavid Spickett all_regions += result.GetOutput() 8099451b44SJordan Rupprecht 8199451b44SJordan Rupprecht # Now that we reached the end, 'memory region' should again print the usage. 8299451b44SJordan Rupprecht interp.HandleCommand("memory region", result) 8399451b44SJordan Rupprecht self.assertFalse(result.Succeeded()) 8413e1cf80SDavid Spickett self.assertRegexpMatches(result.GetError(), "Usage: memory region <address\-expression> \(or \-\-all\)") 8513e1cf80SDavid Spickett 8613e1cf80SDavid Spickett # --all should match what repeating the command gives you 8713e1cf80SDavid Spickett interp.HandleCommand("memory region --all", result) 8813e1cf80SDavid Spickett self.assertTrue(result.Succeeded()) 8913e1cf80SDavid Spickett self.assertEqual(result.GetOutput(), all_regions) 901ca8a978SDavid Spickett 91*f3d43ecaSDavid Spickett def test_no_overlapping_regions(self): 921ca8a978SDavid Spickett # In the past on Windows we were recording AllocationBase as the base address 931ca8a978SDavid Spickett # of the current region, not BaseAddress. So if a range of pages was split 941ca8a978SDavid Spickett # into regions you would see several regions with the same base address. 951ca8a978SDavid Spickett # This checks that this no longer happens (and it shouldn't happen on any 961ca8a978SDavid Spickett # other OS either). 971ca8a978SDavid Spickett self.setup_program() 981ca8a978SDavid Spickett 991ca8a978SDavid Spickett regions = self.process().GetMemoryRegions() 1001ca8a978SDavid Spickett num_regions = regions.GetSize() 1011ca8a978SDavid Spickett 1021ca8a978SDavid Spickett if num_regions: 1031ca8a978SDavid Spickett region = lldb.SBMemoryRegionInfo() 1041ca8a978SDavid Spickett regions.GetMemoryRegionAtIndex(0, region) 1051ca8a978SDavid Spickett previous_base = region.GetRegionBase() 1061ca8a978SDavid Spickett previous_end = region.GetRegionEnd() 1071ca8a978SDavid Spickett 1081ca8a978SDavid Spickett for idx in range(1, regions.GetSize()): 1091ca8a978SDavid Spickett regions.GetMemoryRegionAtIndex(idx, region) 1101ca8a978SDavid Spickett 1111ca8a978SDavid Spickett # Check that it does not overlap the previous region. 1121ca8a978SDavid Spickett # This could happen if we got the base addresses or size wrong. 1131ca8a978SDavid Spickett # Also catches the base addresses being the same. 1141ca8a978SDavid Spickett region_base = region.GetRegionBase() 1151ca8a978SDavid Spickett region_end = region.GetRegionEnd() 1161ca8a978SDavid Spickett 117*f3d43ecaSDavid Spickett self.assertFalse( 118*f3d43ecaSDavid Spickett (region_base < previous_end) and (previous_base < region_end), 1191ca8a978SDavid Spickett "Unexpected overlapping memory region found.") 1201ca8a978SDavid Spickett 1211ca8a978SDavid Spickett previous_base = region_base 1221ca8a978SDavid Spickett previous_end = region_end