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