| import lldb |
| from lldbsuite.test.decorators import * |
| from lldbsuite.test.lldbtest import * |
| from lldbsuite.test import configuration |
| |
| |
| class MockAcceleratorAddressSpacesTestCase(TestBase): |
| NO_DEBUG_INFO_TESTCASE = True |
| |
| def setUp(self): |
| super().setUp() |
| if "mock-accelerator" not in configuration.enabled_plugins: |
| self.skipTest("mock-accelerator plugin is not enabled") |
| |
| def accelerator_target(self, native_target): |
| for candidate in self.dbg: |
| if candidate != native_target: |
| return candidate |
| return None |
| |
| @skipIfRemote |
| @add_test_categories(["llgs"]) |
| def test_address_spaces_from_process_plugin(self): |
| """The accelerator process reports its address spaces to the client.""" |
| self.build() |
| target = self.dbg.CreateTarget(self.getBuildArtifact("a.out")) |
| self.assertTrue(target, VALID_TARGET) |
| |
| # Launch stops at the plugin's initialize breakpoint; continuing reaches |
| # the connection hook that creates the accelerator target. |
| process = target.LaunchSimple(None, None, self.get_process_working_directory()) |
| self.assertTrue(process, PROCESS_IS_VALID) |
| self.assertState(process.GetState(), lldb.eStateStopped) |
| process.Continue() |
| self.assertState(process.GetState(), lldb.eStateStopped) |
| |
| self.assertEqual(self.dbg.GetNumTargets(), 2) |
| accelerator_process = self.accelerator_target(target).GetProcess() |
| self.assertTrue(accelerator_process.IsValid()) |
| |
| # ProcessMockAccelerator reports "global" (id 1) and "local" (id 2). |
| error = lldb.SBError() |
| self.assertEqual(accelerator_process.GetAddressSpaceID("global", error), 1) |
| self.assertSuccess(error) |
| self.assertEqual(accelerator_process.GetAddressSpaceID("local", error), 2) |
| self.assertSuccess(error) |
| |
| # An unknown name is an error rather than a silent default. |
| accelerator_process.GetAddressSpaceID("nonexistent", error) |
| self.assertTrue(error.Fail()) |
| |
| # The native process has no address spaces, so the same lookup fails |
| # there even though both targets talk to an lldb-server. |
| process.GetAddressSpaceID("global", error) |
| self.assertTrue(error.Fail()) |
| |
| # Read the same numeric address from both spaces. The mock process |
| # answers with the address space in byte 0 and the thread in byte 1, so |
| # these show what actually reached the far side of the connection. |
| thread = accelerator_process.GetThreadAtIndex(0) |
| self.assertTrue(thread.IsValid()) |
| tid = thread.GetThreadID() |
| |
| # "global" is not thread specific, so no thread is sent. |
| global_bytes = accelerator_process.ReadMemory( |
| lldb.SBProcessAddress(0x1000, 1), 4, error |
| ) |
| self.assertSuccess(error) |
| self.assertEqual(global_bytes, bytes([1, 0, 0, 0])) |
| |
| # "local" is thread specific, so the thread rides along with the read. |
| local_bytes = accelerator_process.ReadMemory( |
| lldb.SBProcessAddress(0x1000, 2, thread), 4, error |
| ) |
| self.assertSuccess(error) |
| self.assertEqual(local_bytes, bytes([2, tid & 0xFF, 0, 0])) |
| |
| self.assertNotEqual(global_bytes, local_bytes) |
| |
| # Reading a thread specific space without a thread never reaches the |
| # server. |
| accelerator_process.ReadMemory(lldb.SBProcessAddress(0x1000, 2), 4, error) |
| self.assertTrue(error.Fail()) |
| self.assertIn("thread specific", error.GetCString()) |