brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.7 KiB · 7c9ad0c Raw
210 lines · python
1"""2Test lldb-dap memory support3"""4 5from base64 import b64decode6import dap_server7from lldbsuite.test.decorators import *8from lldbsuite.test.lldbtest import *9from lldbsuite.test import lldbutil10import lldbdap_testcase11import os12 13 14class TestDAP_memory(lldbdap_testcase.DAPTestCaseBase):15    @skipIfWindows16    def test_memory_refs_variables(self):17        """18        Tests memory references for evaluate19        """20        program = self.getBuildArtifact("a.out")21        self.build_and_launch(program)22        source = "main.cpp"23        self.source_path = os.path.join(os.getcwd(), source)24        self.set_source_breakpoints(25            source,26            [line_number(source, "// Breakpoint")],27        )28        self.continue_to_next_stop()29 30        locals = {l["name"]: l for l in self.dap_server.get_local_variables()}31 32        # Pointers should have memory-references33        self.assertIn("memoryReference", locals["rawptr"].keys())34        # Non-pointers should also have memory-references35        self.assertIn("memoryReference", locals["not_a_ptr"].keys())36 37    @skipIfWindows38    def test_memory_refs_evaluate(self):39        """40        Tests memory references for evaluate41        """42        program = self.getBuildArtifact("a.out")43        self.build_and_launch(program)44        source = "main.cpp"45        self.source_path = os.path.join(os.getcwd(), source)46        self.set_source_breakpoints(47            source,48            [line_number(source, "// Breakpoint")],49        )50        self.continue_to_next_stop()51 52        self.assertIn(53            "memoryReference",54            self.dap_server.request_evaluate("rawptr")["body"].keys(),55        )56 57    @skipIfWindows58    def test_memory_refs_set_variable(self):59        """60        Tests memory references for `setVariable`61        """62        program = self.getBuildArtifact("a.out")63        self.build_and_launch(program)64        source = "main.cpp"65        self.source_path = os.path.join(os.getcwd(), source)66        self.set_source_breakpoints(67            source,68            [line_number(source, "// Breakpoint")],69        )70        self.continue_to_next_stop()71 72        ptr_value = self.get_local_as_int("rawptr")73        self.assertIn(74            "memoryReference",75            self.set_local("rawptr", ptr_value + 2)["body"].keys(),76        )77 78    @skipIfWindows79    def test_readMemory(self):80        """81        Tests the 'readMemory' request82        """83        program = self.getBuildArtifact("a.out")84        self.build_and_launch(program)85        source = "main.cpp"86        self.source_path = os.path.join(os.getcwd(), source)87        self.set_source_breakpoints(88            source,89            [line_number(source, "// Breakpoint")],90        )91        self.continue_to_next_stop()92 93        ptr_deref = self.dap_server.request_evaluate("*rawptr")["body"]94        memref = ptr_deref["memoryReference"]95 96        # We can read the complete string97        mem = self.dap_server.request_readMemory(memref, 0, 5)["body"]98        self.assertEqual(b64decode(mem["data"]), b"dead\0")99 100        # We can read large chunks, potentially returning partial results101        mem = self.dap_server.request_readMemory(memref, 0, 4096)["body"]102        self.assertEqual(b64decode(mem["data"])[0:5], b"dead\0")103 104        # Use an offset105        mem = self.dap_server.request_readMemory(memref, 2, 3)["body"]106        self.assertEqual(b64decode(mem["data"]), b"ad\0")107 108        # Reads of size 0 are successful109        # VS Code sends those in order to check if a `memoryReference` can actually be dereferenced.110        mem = self.dap_server.request_readMemory(memref, 0, 0)111        self.assertEqual(mem["success"], True)112        self.assertNotIn(113            "data", mem["body"], f"expects no data key in response: {mem!r}"114        )115 116        # Reads at offset 0x0 return unreadable bytes117        bytes_to_read = 6118        mem = self.dap_server.request_readMemory("0x0", 0, bytes_to_read)119        self.assertEqual(mem["body"]["unreadableBytes"], bytes_to_read)120 121        # Reads with invalid address fails.122        mem = self.dap_server.request_readMemory("-3204", 0, 10)123        self.assertFalse(mem["success"], "expect fail on reading memory.")124 125        self.continue_to_exit()126 127    # Flakey on 32-bit Arm Linux.128    @skipIf(oslist=["linux"], archs=["arm$"])129    def test_writeMemory(self):130        """131        Tests the 'writeMemory' request132        """133        program = self.getBuildArtifact("a.out")134        self.build_and_launch(program)135        source = "main.cpp"136        self.source_path = os.path.join(os.getcwd(), source)137        self.set_source_breakpoints(138            source,139            [line_number(source, "// Breakpoint")],140        )141        self.continue_to_next_stop()142 143        # Get the 'not_a_ptr' writable variable reference address.144        ptr_deref = self.dap_server.request_evaluate("not_a_ptr")["body"]145        memref = ptr_deref["memoryReference"]146 147        # Write the decimal value 50 (0x32 in hexadecimal) to memory.148        # This corresponds to the ASCII character '2' and encodes to Base64 as "Mg==".149        mem_response = self.writeMemory(memref, 50, 0, True)150        self.assertEqual(mem_response["success"], True)151        self.assertEqual(mem_response["body"]["bytesWritten"], 1)152 153        # Read back the modified memory and verify that the written data matches154        # the expected result.155        mem_response = self.dap_server.request_readMemory(memref, 0, 1)156        self.assertEqual(mem_response["success"], True)157        self.assertEqual(mem_response["body"]["data"], "Mg==")158 159        # Write the decimal value 100 (0x64 in hexadecimal) to memory.160        # This corresponds to the ASCII character 'd' and encodes to Base64 as "ZA==".161        # allowPartial=False162        mem_response = self.writeMemory(memref, 100, 0, False)163        self.assertEqual(mem_response["success"], True)164        self.assertEqual(mem_response["body"]["bytesWritten"], 1)165 166        # Read back the modified memory and verify that the written data matches167        # the expected result.168        mem_response = self.dap_server.request_readMemory(memref, 0, 1)169        self.assertEqual(mem_response["success"], True)170        self.assertEqual(mem_response["body"]["data"], "ZA==")171 172        # Memory write failed for 0x0.173        mem_response = self.writeMemory("0x0", 50, 0, True)174        self.assertEqual(mem_response["success"], False)175 176        # Malformed memory reference.177        mem_response = self.writeMemory("12345", 50, 0, True)178        self.assertEqual(mem_response["success"], False)179 180        ptr_deref = self.dap_server.request_evaluate("nonWritable")["body"]181        memref = ptr_deref["memoryReference"]182 183        # Writing to non-writable region should return an appropriate error.184        mem_response = self.writeMemory(memref, 50, 0, False)185        self.assertEqual(mem_response["success"], False)186        self.assertRegex(187            mem_response["body"]["error"]["format"],188            r"Memory " + memref + " region is not writable",189        )190 191        # Trying to write empty value; data=""192        mem_response = self.writeMemory(memref)193        self.assertEqual(mem_response["success"], False)194        self.assertRegex(195            mem_response["body"]["error"]["format"],196            r"Data cannot be empty value. Provide valid data",197        )198 199        # Verify that large memory writes fail if the range spans non-writable200        # or non -contiguous regions.201        data = bytes([0xFF] * 8192)202        mem_response = self.writeMemory(203            memref, int.from_bytes(data, byteorder="little"), 0, False204        )205        self.assertEqual(mem_response["success"], False)206        self.assertRegex(207            mem_response["body"]["error"]["format"],208            r"Memory " + memref + " region is not writable",209        )210