From 6833b6c99838c0eb96c6df347616363bd75ad516 Mon Sep 17 00:00:00 2001 From: Dave Lee Date: Wed, 10 Sep 2025 09:53:54 -0700 Subject: [PATCH 1/2] [lldb] Pass execution context to CompilerType::GetByteSize - in CommandObjectMemoryRead (NFC) Some type systems require an execution context be available when working with types (ex: Swift). This fixes `memory read --type` to support such type systems, by passing in an execution context to `GetByteSize()`, instead of passing null. rdar://158968545 (cherry picked from commit b574e63f9fd1adb52786f9dc03ec6f479229e1a7) --- lldb/source/Commands/CommandObjectMemory.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lldb/source/Commands/CommandObjectMemory.cpp b/lldb/source/Commands/CommandObjectMemory.cpp index 5792c13373c1e..eb2530bb51724 100644 --- a/lldb/source/Commands/CommandObjectMemory.cpp +++ b/lldb/source/Commands/CommandObjectMemory.cpp @@ -364,6 +364,8 @@ class CommandObjectMemoryRead : public CommandObjectParsed { return; } + ExecutionContextScope *exe_scope = m_exe_ctx.GetBestExecutionContextScope(); + CompilerType compiler_type; Status error; @@ -519,7 +521,7 @@ class CommandObjectMemoryRead : public CommandObjectParsed { --pointer_count; } - auto size_or_err = compiler_type.GetByteSize(nullptr); + auto size_or_err = compiler_type.GetByteSize(exe_scope); if (!size_or_err) { result.AppendErrorWithFormat( "unable to get the byte size of the type '%s'\n%s", @@ -639,7 +641,7 @@ class CommandObjectMemoryRead : public CommandObjectParsed { if (!m_format_options.GetFormatValue().OptionWasSet()) m_format_options.GetFormatValue().SetCurrentValue(eFormatDefault); - auto size_or_err = compiler_type.GetByteSize(nullptr); + auto size_or_err = compiler_type.GetByteSize(exe_scope); if (!size_or_err) { result.AppendError(llvm::toString(size_or_err.takeError())); return; @@ -799,7 +801,6 @@ class CommandObjectMemoryRead : public CommandObjectParsed { output_stream_p = &result.GetOutputStream(); } - ExecutionContextScope *exe_scope = m_exe_ctx.GetBestExecutionContextScope(); if (compiler_type.GetOpaqueQualType()) { for (uint32_t i = 0; i < item_count; ++i) { addr_t item_addr = addr + (i * item_byte_size); From d6f9d81c15125ceae9068ba9aab3dc47617791ef Mon Sep 17 00:00:00 2001 From: Dave Lee Date: Thu, 11 Sep 2025 15:53:15 -0700 Subject: [PATCH 2/2] Add Swift tests for memory read -t --- .../lang/swift/command_memory_read/Makefile | 3 + .../TestSwiftMemoryRead.py | 58 +++++++++++++++++++ .../lang/swift/command_memory_read/main.swift | 10 ++++ 3 files changed, 71 insertions(+) create mode 100644 lldb/test/API/lang/swift/command_memory_read/Makefile create mode 100644 lldb/test/API/lang/swift/command_memory_read/TestSwiftMemoryRead.py create mode 100644 lldb/test/API/lang/swift/command_memory_read/main.swift diff --git a/lldb/test/API/lang/swift/command_memory_read/Makefile b/lldb/test/API/lang/swift/command_memory_read/Makefile new file mode 100644 index 0000000000000..cca30b939e652 --- /dev/null +++ b/lldb/test/API/lang/swift/command_memory_read/Makefile @@ -0,0 +1,3 @@ +SWIFT_SOURCES := main.swift +SWIFTFLAGS_EXTRAS := -parse-as-library +include Makefile.rules diff --git a/lldb/test/API/lang/swift/command_memory_read/TestSwiftMemoryRead.py b/lldb/test/API/lang/swift/command_memory_read/TestSwiftMemoryRead.py new file mode 100644 index 0000000000000..ad607398664ee --- /dev/null +++ b/lldb/test/API/lang/swift/command_memory_read/TestSwiftMemoryRead.py @@ -0,0 +1,58 @@ +import lldb +from lldbsuite.test.lldbtest import * +from lldbsuite.test.decorators import * +import lldbsuite.test.lldbutil as lldbutil + + +class TestCase(TestBase): + @swiftTest + def test_scalar_types(self): + self.build() + _, _, thread, _ = lldbutil.run_to_source_breakpoint( + self, "break here", lldb.SBFileSpec("main.swift") + ) + frame = thread.selected_frame + + child = frame.var("name") + for t in ("String", "$sSSD"): + self.expect( + f"memory read -t {t} {child.load_addr}", + substrs=[f'(String) 0x{child.load_addr:x} = "dirk"'], + ) + + child = frame.var("number") + for t in ("Int", "$sSiD"): + self.expect( + f"memory read -t {t} {child.load_addr}", + substrs=[f"(Int) 0x{child.load_addr:x} = 41"], + ) + + child = frame.var("fact") + for t in ("Bool", "$sSbD"): + self.expect( + f"memory read -t {t} {child.load_addr}", + substrs=[f"(Bool) 0x{child.load_addr:x} = true"], + ) + + @swiftTest + @expectedFailureAll + def test_generic_types(self): + self.build() + _, _, thread, _ = lldbutil.run_to_source_breakpoint( + self, "break here", lldb.SBFileSpec("main.swift") + ) + frame = thread.selected_frame + + child = frame.var("maybe") + for t in ("UInt64?", "$ss6UInt64VSgD"): + self.expect( + f"memory read -t {t} {child.load_addr}", + substrs=[f"(UInt64?) 0x{child.load_addr:x} = nil"], + ) + + child = frame.var("bytes") + for t in ("[UInt8]", "$sSays5UInt8VGD"): + self.expect( + f"memory read -t {t} {child.load_addr}", + substrs=[f"([UInt8]) 0x{child.load_addr:x} = [1, 2, 4, 8]"], + ) diff --git a/lldb/test/API/lang/swift/command_memory_read/main.swift b/lldb/test/API/lang/swift/command_memory_read/main.swift new file mode 100644 index 0000000000000..8b9e757090ac8 --- /dev/null +++ b/lldb/test/API/lang/swift/command_memory_read/main.swift @@ -0,0 +1,10 @@ +@main enum Entry { + static func main() { + var name: String = "dirk" + var number: Int = 41 + var fact: Bool = true + var maybe: UInt64? = nil + var bytes: [UInt8] = [1, 2, 4, 8] + print("break here", name, number, fact, maybe, bytes) + } +}