xref: /llvm-project/lldb/test/API/tools/lldb-dap/memory/TestDAP_memory.py (revision 786dc5a2da9bb55d98c65d018de25d9bd31485ff)
1"""
2Test lldb-dap memory support
3"""
4
5from base64 import b64decode
6import dap_server
7from lldbsuite.test.decorators import *
8from lldbsuite.test.lldbtest import *
9from lldbsuite.test import lldbutil
10import lldbdap_testcase
11import os
12
13
14class TestDAP_memory(lldbdap_testcase.DAPTestCaseBase):
15    def test_memory_refs_variables(self):
16        """
17        Tests memory references for evaluate
18        """
19        program = self.getBuildArtifact("a.out")
20        self.build_and_launch(program)
21        source = "main.cpp"
22        self.source_path = os.path.join(os.getcwd(), source)
23        self.set_source_breakpoints(
24            source,
25            [line_number(source, "// Breakpoint")],
26        )
27        self.continue_to_next_stop()
28
29        locals = {l["name"]: l for l in self.dap_server.get_local_variables()}
30
31        # Pointers should have memory-references
32        self.assertIn("memoryReference", locals["rawptr"].keys())
33        # Non-pointers should also have memory-references
34        self.assertIn("memoryReference", locals["not_a_ptr"].keys())
35
36    def test_memory_refs_evaluate(self):
37        """
38        Tests memory references for evaluate
39        """
40        program = self.getBuildArtifact("a.out")
41        self.build_and_launch(program)
42        source = "main.cpp"
43        self.source_path = os.path.join(os.getcwd(), source)
44        self.set_source_breakpoints(
45            source,
46            [line_number(source, "// Breakpoint")],
47        )
48        self.continue_to_next_stop()
49
50        self.assertIn(
51            "memoryReference",
52            self.dap_server.request_evaluate("rawptr")["body"].keys(),
53        )
54
55    def test_memory_refs_set_variable(self):
56        """
57        Tests memory references for `setVariable`
58        """
59        program = self.getBuildArtifact("a.out")
60        self.build_and_launch(program)
61        source = "main.cpp"
62        self.source_path = os.path.join(os.getcwd(), source)
63        self.set_source_breakpoints(
64            source,
65            [line_number(source, "// Breakpoint")],
66        )
67        self.continue_to_next_stop()
68
69        ptr_value = self.get_local_as_int("rawptr")
70        self.assertIn(
71            "memoryReference",
72            self.dap_server.request_setVariable(1, "rawptr", ptr_value + 2)[
73                "body"
74            ].keys(),
75        )
76
77    def test_readMemory(self):
78        """
79        Tests the 'readMemory' request
80        """
81        program = self.getBuildArtifact("a.out")
82        self.build_and_launch(program)
83        source = "main.cpp"
84        self.source_path = os.path.join(os.getcwd(), source)
85        self.set_source_breakpoints(
86            source,
87            [line_number(source, "// Breakpoint")],
88        )
89        self.continue_to_next_stop()
90
91        ptr_deref = self.dap_server.request_evaluate("*rawptr")["body"]
92        memref = ptr_deref["memoryReference"]
93
94        # We can read the complete string
95        mem = self.dap_server.request_readMemory(memref, 0, 5)["body"]
96        self.assertEqual(b64decode(mem["data"]), b"dead\0")
97
98        # We can read large chunks, potentially returning partial results
99        mem = self.dap_server.request_readMemory(memref, 0, 4096)["body"]
100        self.assertEqual(b64decode(mem["data"])[0:5], b"dead\0")
101
102        # Use an offset
103        mem = self.dap_server.request_readMemory(memref, 2, 3)["body"]
104        self.assertEqual(b64decode(mem["data"]), b"ad\0")
105
106        # Reads of size 0 are successful
107        # VS Code sends those in order to check if a `memoryReference` can actually be dereferenced.
108        mem = self.dap_server.request_readMemory(memref, 0, 0)
109        self.assertEqual(mem["success"], True)
110        self.assertEqual(mem["body"]["data"], "")
111
112        # Reads at offset 0x0 fail
113        mem = self.dap_server.request_readMemory("0x0", 0, 6)
114        self.assertEqual(mem["success"], False)
115